I looked at http://api.jquery.com/trigger/ and the examples did not answer my question. I am looking at some code and would like to know what this block of code is doing.
$(document).on('click', '#SubmitQuery', function(event) {
event.preventDefault();
$(document).trigger('filter:submit');
});
Specifically, what does the colon inside of that trigger function do? For complete context, here is what filter is (I assume that the 'filter' inside of the trigger function refers to that filter object):
var filter = {
init: function() {
$(document).on('keypress', '#Filter', debounce(function(event) {
if (event.keyCode == 13) {
$(document).trigger('filter:text');
}
}, 300));
$(document).on('click', '#ClearFilter', function(event) {
event.preventDefault();
$('#FilterText').val('');
$('#FilterText').focus();
$(document).trigger('filter:clear');
});
$(document).on('change', '.filterSection [type=checkbox]', function(event) {
var group = $(this).parents('[data-filter-group]').attr('data-filter-group');
var $checkboxes = $('[data-filter-group=' + group + '] [type=checkbox]');
if ($checkboxes.length > 0) {
if ($checkboxes.filter(':checked').length === 0) {
$(this).prop('checked', true);
}
}
});
$(document).on('click', '#SubmitQuery', function(event) {
event.preventDefault();
$(document).trigger('filter:submit');
});
$("#Filter").focus();
}
};
The colons specifies custom events, essentially creating namespaces for events you can call later without overriding default events or having to create multiple listeners on the same event.
You can find more information here: https://learn.jquery.com/events/introduction-to-custom-events/
Related
Is there a pure JS version of this?
$(document).on('click', 'a[href]', function(event) {
event.preventDefault();
here.change(this);
});
The specific feature I'm looking for is adding event listeners for any link that's created later via JS (AJAX for example).
Modern browsers support matches which makes this a lot easier
document.addEventListener('click', function(event) {
if (event.target.matches('a[href], a[href] *')) {
event.preventDefault();
console.log('works fine')
}
}, false);
document.body.innerHTML = '<span>Click Me!</span><br /><div>not me!</div>';
You could make this more convenient with a simple function
function addEvent(parent, evt, selector, handler) {
parent.addEventListener(evt, function(event) {
if (event.target.matches(selector + ', ' + selector + ' *')) {
handler.apply(event.target.closest(selector), arguments);
}
}, false);
}
Note that closest() is only supported in the latest browsers, there's a polyfill on MDN
This replicates the jQuery behaviour a lot more, and is easier to use, it also sets the value of this correctly
function addEvent(parent, evt, selector, handler) {
parent.addEventListener(evt, function(event) {
if (event.target.matches(selector + ', ' + selector + ' *')) {
handler.apply(event.target.closest(selector), arguments);
}
}, false);
}
/* To be used as */
addEvent(document, 'click', 'a[href]', function(e) {
console.log(this)
});
/* Add a dynamic element */
document.body.innerHTML = '<span>Click Me!</span><br /><div>not me!</div>';
You can attach click event to document. check if event.target .tagName is "A" and if event.target has property .href. It is not clear what expected result of here.change(this) is expected to do from text of Question
function dynamicA() {
var a = document.createElement("a");
a.href = "";
a.textContent = "a";
document.body.innerHTML += "<br>";
document.body.appendChild(a);
}
document.addEventListener("click", function(event) {
event.preventDefault();
if (event.target.tagName === "A" && event.target.href) {
// do stuff
dynamicA();
}
});
<a href>a</a>
I believe this accomplishes what you want:
// for all dom elements on click
document.onclick = function(event) {
var el = event.target; // get what is being clicked on
if(el.hasAttribute('href') && el.tagName == 'a') { // check if it's a link
event.preventDefault();
here.change(this); // what is this?
}
}
I want to prevent # to be entered into input. But it doesn't work, any idea why?
$(function() {
$(document).on('keyup', '[placeholder="x"]', function() {
if (event.keyCode === 64) {
event.preventDefault();
}
});
})
https://jsfiddle.net/r82wtea3/2/
You also need to pass parameter event to the function:
$(document).on('keypress', '[placeholder="x"]', function(event) { /*...*/ });
I suggest you to use event.which instead of event.keyCode for better compatibility. Here's your updated fiddle. I have used keypress event instead of keyup.
$(function() {
$(document).on('keydown', '[placeholder="x"]', function(event) {
if (event.keyCode === 50) {
event.preventDefault();
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" placeholder="x">
change your function to following:
$(function() {
$(document).on('keydown', '[placeholder="x"]', function(event) {
if (event.keyCode === 50) {
event.preventDefault();
}
});
})
You can return false; on keypress event when event.which is a certain value
$(function() {
$(document).on('keypress', '[placeholder="x"]', function(event) {
if(event.which === 64){
return false;
}
});
})
which will more or less kill off the event..
Here is a fiddle..
On keyup the # is not a single key. It is more like ALT+Q, or CMD+L on Mac. So the best way would be to check the input for existance of # in the value and to it manually. Otherwise use keypress with 64 as keyCode.
$(function() {
$(document).on('keyup', '[placeholder="x"]', function() {
var input = $(this);
if ( input.val().indexOf("#") >= 0 ) {
input.val(input.val().replace("#", ""));
}
});
});
Working example.
You can't listen for a for a keypress-type event since it won't fire if the user pastes an # with their mouse. You also can't listen for one specific keyCode because there are multiple ways to input an # across different platforms and keyboard layouts.
You should be listening for a change-type event such as input, and replace any occurrence of # with an empty string. Here's an example:
document.querySelector('input').addEventListener('input', function() {
this.value = this.value.replace(/#/g, '');
});
Here's a pen with the example in action.
I have a function that uses the value of a textbox (prodinput) to hide/show links in a dropdown list. It works when a user types in a string manually but when I want to auto-populate the value by passing a url parameter I'll need to trigger a keyup or keydown to get it to call the function.
Here is the function that does the search (located in the core.js):
prodinput.on('keyup, keydown',function() {
var search = $(this).val().toLowerCase();
$('.support-product .browse-products a').each(function() {
if($(this).text().toLowerCase().search(search) > -1) {
$(this).parent().show();
} else {
$(this).parent().hide();
}
});
});
Here is the function I'm using to trigger the function above (located on the page I'm trying to run it on.
$(function(){
$target = $('.browse-products .display');
$target.val($trimmed);
$('.browse-products').addClass('active');
$target.focus();
var e = jQuery.Event( "keydown" );
$target.trigger(e);
});
I've tried using:
$target.keyup();
and as shown above:
var e = jQuery.Event( "keydown" );
$target.trigger(e);
I'm wondering if it's a problem with the order in which things load on the page.
I'd put your keyup code in a named function.
$(function () {
myFunction();
prodinput.on('keyup, keydown', function () {
myFunction();
})
};
var myFunction = function () {
var search = $('#prodinput').val().toLowerCase();
$('.support-product .browse-products a').each(function () {
if ($(this).text().toLowerCase().search(search) > -1) {
$(this).parent().show();
} else {
$(this).parent().hide();
}
});
};
Assuming you don't need to support ancient browsers you can just listen for the input event which covers keypress and change events. Then after attaching the listener simply trigger the event:
$(function() {
$("#prodinput").on('input', function() {//alternatively you could use change and keyup
var search = $(this).val().toLowerCase();
$('.support-product .browse-products a').each(function() {
if ($(this).text().toLowerCase().search(search) > -1) {
$(this).parent().show();
} else {
$(this).parent().hide();
}
});
}).trigger("input");//trigger the event now
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="search" id="prodinput" value="peanuts" />
<div class="support-product">
<ul class="browse-products">
<li>jam</li>
<li>elephants</li>
<li>peanuts</li>
</ul>
</div>
if I'm fetching multiple events using jquery how can I determine which event is currently triggered so I can processed further, for example
$("#someId").on('paste blur', function (e) {
var data = '';
// if paste
data = e.originalEvent.clipboardData.getData('text')
// if blur
data = $("#someId").val();
});
You can use event.type to get the current event,
$("#someId").on('paste blur', function (e) {
if ('paste' == e.type) {
data = e.originalEvent.clipboardData.getData('text')
} else if ('blur' == e.type) {
data = $("#someId").val();
}
});
You can use Event.type.
$("#someId").on('paste blur', function (e) {
var data = '';
if(e.type == 'paste') {
data = e.originalEvent.clipboardData.getData('text')
}
if(e.type == 'blur') {
data = $("#someId").val();
}
});
You might wish to consider registering separate handlers depending on how different you're going to handle the events though.
To avoid unnecessary if conditions you can add only the events you actually needs:
// Bind up a couple of event handlers
$("#txt").on({
click: function() {
console.log("click")
},
mouseout: function() {
console.log("mouseout")
},
change: function() {
console.log("change")
}
});
//Lookup events for this particular Element
//prints out an object with all events on that element
console.log($._data($("#txt")[0], "events"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="txt" />
I need to temporarily change the click event for an element as follows:
var originalEvent = '';
$("#helpMode").click(function (e) {
originalEvent = $("#element").getCurrentClickEventHandler();
$("#element").click(function (e) {
//Do something else
});
});
//Later in the code
$("#helpModeOff").click(function (e) {
$("#element").click(originalEvent);
});
How would I store the current function that is an event handler in a global variable for later reuse?
EDIT: Here's what im trying to do:
var evnt = '';
$("#helpTool").click(function (e) {
if(!this.isOn){
evnt = $("#Browse").data('events').click;
$("#ele").unbind('click');
$("#ele").click(function (e) {
alert('dd');
});
this.isOn=true;
}else{
this.isOn = false;
alert('off');
$("#ele").unblind('click');
$("#ele").click(evnt);
}
});
Here you go, figured it out:
Now with e.srcElement.id you can get either HelpMode or HelpModeOff and then can turn on/off your help stuff!
http://jsfiddle.net/zcDQ9/1/
var originalEvent = '';
$('#element').on('yourCustomEvent', function (e) {
// do stuff
alert(originalEvent);
$(this).toggleClass('toggleThing');
//test for helpMode or helpModeOff here now...
});
$("#helpMode").on('click', function (e) {
originalEvent = e.srcElement.id;
$("#element").trigger('yourCustomEvent');
});
//Later in the code
$("#helpModeOff").on('click', function (e) {
originalEvent = e.srcElement.id;
$("#element").trigger('yourCustomEvent');
});
Okay. In jQuery 1.7 I guess it's a little different.
//get the handler from data('events')
$.each($("#element").data("events"), function(i, event) {
if (i === "click") {
$.each(event, function(j, h) {
alert(h.handler);
});
}
});
http://jsfiddle.net/yQwZU/
This is the reference.
Not sure if the following works with 1.7.
originalEvent = $('#element').data('events').click;
jQuery stored all the handlers in data. See here to learn more about data('events').
Personally, I think I would avoid manually binding and unbinding handlers.
Another way to approach this is to bind click events to classes, then all you need to do is add and remove classes from the appropriate elements when switching to/from help mode.
Here's a jsfiddle illustrating what I mean.
Switching to and from help mode then just involves adding removing classes:
$('#btnhelpmode').click(function(){
if(!helpMode){
helpMode = true;
$('.normalmode').addClass('helpmode').removeClass('normalmode');
$(this).val('Switch to normal mode...');
}else{
helpMode = false;
$('.helpmode').addClass('normalmode').removeClass('helpmode');
$(this).val('Switch to help mode...');
}
});
and you just create the handlers required, binding them to the appropriate classes:
$('#pagecontent').on('click', '#element1.normalmode', function(){
alert('element1 normal mode');
});
$('#pagecontent').on('click', '#element1.helpmode', function(){
alert('element1 help mode');
});
$('#pagecontent').on('click', '#element2.normalmode', function(){
alert('element2 normal mode');
});
$('#pagecontent').on('click', '#element2.helpmode', function(){
alert('element2 help mode');
});