I have a search field that currently has an .on('input') event handler attached to it. However, in some instances the search field may be pre-populated if a value is passed through the URL (http://127.0.0.1/search/query-is-here). The issue here however is that the event handler will not be fired until the user edits the search field's value, meaning no search is automatically made.
I have tried initiating a .trigger by specifying focus, click, change, ... but none seem to work (and yes, I do change the event handler to .on('input focus') for example). What's the crack?
--
JS File (referenced in the footer BEFORE the trigger)
$('#search').on('input focus', function(e) {
e.preventDefault();
// various if statements and variable assignments
}
Trigger
// codeigniter -> http://ip.com/{segment 1}/{segment 2} -> this does get executed
<?php if($this->uri->segment(1) == "search" && $this->uri->segment(2)):?>
<script>
$('#search').focus();
$('#search').trigger("focus");
</script>
<?php endif; ?>
My understanding of $('#search').trigger("focus"); is that it should fire the event handler attached to #search, and execute the JS within that function.
You're subscribing to the event 'input focus' and triggering the event 'focus'. I think you'll want to subscribe to both events.
$('#search').on('focus', myHandler);
$('#search').on('focus input', myHandler);
Why are placing e.preventDefault() on focus? The event.preventDefault() method stops the default action of an element from happening.
Remove that e.preventDefault() from the code and try it again.
$('#search').on('input focus', function(e) {
//remvoe this line>> e.preventDefault();
// various if statements and variable assignments
}
Below is the jsfiddle link:
https://jsfiddle.net/shrawanlakhe/c8v5v788/1/
I have also place e.preventDefault() on the handler and it is preventing click event handler from firing .So first try it and the click event handler will not fire and then remove the e.preventDefault() and then try it again in the fiddle and this time event handler will fire
Related
I have this input form and I want to save the value of the input whenever the user either fires an on-submit or an on-blur event.
And I have the problem, that whenever the user fires the on-submit, naturally the on-blur event is also fired. Thus two events with the same content is fired. (Not a big problem, but still).
I've searched for solutions and found a lot for jQuery, and I believe that I need a raw javascript solution for this.
Here is my form:
<form method="post" on-submit="doneEditAction">
<input
type="text"
value="{{editValue::input}}"
id="editItemInputField"
on-keyup="editKeyupAction"
on-blur="editBlur">
<button type="submit">edit</button>
</form>
This form fires the doneEditAction event when I submit the form. But at the same time the editBlur event gets also fired, which should do the same as the doneEditAction event, to save the value of the input.
editBlur Event
editBlur: function (e) {
this.doneEditAction(e);
this.editing = false;
}
doneEditAction Event
doneEditAction: function (e) {
e.preventDefault();
console.log(this.editingValue);
this.editing = false;
}
HERE ARE MY QUESTIONS:
How do I make the form not fire the on-blur event, when the form is submitted? Or
How do I make the form fire always only one event? Or, see edit,
Does it even matter at all (from a performance perspective) if two identical events are fired?
EDIT
Just saw that the Polymer TodoMVC and they also fire two events when you try to edit it. Proof:
Does that mean, that it actually doesn't matter, if two same events are fired?
Since the on-blur event fires automatically everytime the on-submit event is fired, the doneEdit event handler is executed twice.
And since the doneEdit event handler sets the editing property to false twice, there is a simple solution to make sure the doneEdit event is executed only once.
In doneEdit we check if the editing is true and only then perform any action we want, setting the editing value to false.
doneEdit(function) {
if(this.editing === true) {
this.editing = false;
console.log(this.editingValue);
}
}
Thus when the doneEdit handler will be called the second time due to the on-blur event, this.editing is already set to false and console.log() is not executed twice.
Thanks to the PolymerTodoMVC source code.
I am building an application where ID are generated and the after AJAX call is done, the ID is appended to input as it's value. When this happens, the 'change' event is fired by calling .trigger('change') on the input. The code that does this is as follows:
$('form.card').each(function(index, element) {
$.ajax({
url: 'save-content.php',
method: 'POST',
data: $ajaxData,
success: function(returnData){ // the ID is received as 'returnData'
if ($create) { $(element).children('input[name=id]').val(returnData).trigger('change');
//ID added as input value and 'change' event is triggered
}
}
});
});
I use a jQuery File Upload plugin. Every time a file is done uploading, the 'done' event is triggered on each file. Since the ID is received via ajax, the script checks if there is any value, and if not, it attaches an event listener for input 'change'. The code is as follows (including the part from jQuery File Upload plugin):
$('form.fileupload').fileupload({
//some plugin setup
done: function (e, data) {
//get the input from sibling form (that is the input the 'change' event is triggered on (as described in the previous code))
$id = $(this).siblings('form.card').children('input[name=id]');
//if the input has value, do AJAX imediatelly, else wait for id 'change' event to be triggered
if($id.val()) {
//do the AJAX magic now
}
else {
//when 'change' event is fired, do the AJAX stuff
$(document).one('change', $id, function() {
//'change' event fired, do the AJAX magic
});
}
}
});
And now the problem: the change event in the second code is received even when it was triggered on other input[name=id] (from another form.card which has its own input[name=id]). Let me explain that: the first code is ran on each form.card, each having its own input[name=id] which the event is triggered on when ID from AJAX is appended. Then, when we upload the file from jQuery File upload plugin (which can be ran on multiple form.fileupload), the done event fires, registers listener for change event. And when you upload the file from let's say third form.fileupload, the event listener from the third form.fileupload done event catches change even from the first form.
And that has been driving me crazy for 2 days now. I have checked the objects that the event is triggered on and listener for: they're the same.
So what I need is the event listener attached to input[name=id] in third form.card to catch only change event from the input[name=id] in third form.card, not the first.
EDIT: Here is a fiddle of my problem: http://jsfiddle.net/yjnoaye2/3/ Timeouts added to mimic AJAX response delay.
As I stated in the comment it looks like you have event propagation issue.
you can learn about it here:
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation
I think you can add a namespace to your own event, such that only your listener will hear it.
trigger('change.myCustomChangeEvent')
...
$(document).one('change.myCustomChangeEvent', $id, function() {
See the section on namespaces here:
http://api.jquery.com/on/
OK, I have it now. The problem was, that the event listener was created on document and not the form.card that the input[name=id] is in. Even I have scpecified the exact object in the selector parameter, the event listener was attached to every input[name=id].
So all I needed to do was to change this:
$(document).one('change', $id, function() {
//'change' event fired, do the AJAX magic
});
to this
$(this).siblings('form.card').one('change', $id, function() {
//'change' event fired, do the AJAX magic
});
This way, the event listener is attached to particular input in particular form.card.
Here is a working fiddle: http://jsfiddle.net/yjnoaye2/5/
I have the following event listener on my inputs on a HTML page:
$('input').on('input', function (e) {
console.log(this.value);
});
I understand the input event captures the following individual events change, keyup and paste.
When I update an input value using jQuery, I want to trigger this event so my event code runs. If I run:
//Does not work
$('input').val('test').trigger('change');
My event does not fire. I expected the input event handler to catch the change event. If I run:
//Does work
$('input').val('test').trigger('input');
This does work... why does triggering the change event not fire my input event handler?
I expected the input event handler to catch the change event.
That's where you went wrong - the input event handler does not catch change events.
I am using Mootools and adding a click event to a link. I have added a function to an event with this:
$('addCallRoute').addEvent('click', addCallRoute); // Add button
The function contains this:
function addCallRoute(e) {
console.log(e);
}
The function that fires the event (without an actual click)
$('addCallRoute').fireEvent('click');
The Problem:
When I click on the link physically, e is defined. but when I programmatically fire the event, e is undefined. Why?
Because you're not actually/physically triggering an action but firing it remotely. This is how it works.
event normally contains all sort of information about the element from which the action was triggered.
Always check if event is defined before trying to use any methods on it. Or do this:
link.fireEvent('click', {
stop: function(){}
});
When I use event.preventDefault() on a link it works, however when I use it on a button doesn't!
DEMO
My code:
<a id="link" href="http://www.google.com">link</a>
<button id="button" onclick="alert('an alert')">button</button>
$('#link').click(function(event){
event.preventDefault();
});
$('#button').click(function(event){
event.preventDefault();
});
Link action is cancelled, but when I click on the button, still executes the onClick action.
Any help? what I want to do is to prevent the button onClick action without changing the button html (I know how to do
$('#button').removeAttr('onclick');
You want event.stopImmediatePropagation(); if there are multiple event handlers on an element and you want to prevent the others to execute. preventDefault() just blocks the default action (such as submitting a form or navigating to another URL) while stopImmediatePropagation() prevents the event from bubbling up the DOM tree and prevents any other event handlers on the same element from being executed.
Here are some useful links explaining the various methods:
http://api.jquery.com/event.preventDefault/
http://api.jquery.com/event.stopPropagation/
http://api.jquery.com/event.stopImmediatePropagation/
However, since it still doesn't work it means that the onclick="" handler executes before the attached event handler. There's nothing you can do since when your code runs the onclick code has already been executed.
The easiest solution is completely removing that handler:
$('#button').removeAttr('onclick');
Even adding an event listener via plain javascript (addEventListener()) with useCapture=true doesn't help - apparently inline events trigger even before the event starts descending the DOM tree.
If you just do not want to remove the handler because you need it, simply convert it to a properly attached event:
var onclickFunc = new Function($('#button').attr('onclick'));
$('#button').click(function(event){
if(confirm('prevent onclick event?')) {
event.stopImmediatePropagation();
}
}).click(onclickFunc).removeAttr('onclick');
you need stopImmediatePropagation not preventDefault. preventDefault prevents default browser behavior, not method bubbling.
http://api.jquery.com/event.stopImmediatePropagation/
http://api.jquery.com/event.preventDefault/
The preventDefault function does not stop event handlers from being triggered, but rather stops the default action taking place. For links, it stops the navigation, for buttons, it stops the form from being submitted, etc.
What you are looking for is stopImmediatePropagation.
you can try this:
$('#button').show(function() {
var clickEvent = new Function($(this).attr('click')); // store it for future use
this.onclick = undefined;
});
DEMO
It have helped me
function goToAccessoriesPage(targert) {
targert.onclick.arguments[0].preventDefault();
...
}