So im creating project in which you can create unlimited number of input fields that belong to the same array and eventualy are being posted to php handler via ajax. i managed to get that far, its working all fine but the problem im having is that i would want to let user to delete input he/she doesnt want (i.e. created by mistake), it seems to be core part of script, yet i dont know how to approach the issue.
This project you can see in here:
http://jsfiddle.net/7LCzN/
and this is the code:
$(function(){
$("#add").on('click', function () {
$('body').append('<input type="text" class="ac" name="array[]" />');
});
});
$(function(){
$("#post").on('click', function () {
var myArray = new Array();
$('.ac').each(function(index, elem) {
myArray.push($(elem).val());
});
$('#result').text(myArray);
});
});
So for instance ive created 4 fields with these value:
5463, 8675, 2340, 1203
and i just realized i dont want the one with value 2340 i would want to delete it so im left with 3 fields:
5463, 8675, 1203
anyone that helps, ill be glad and greatful, thank you fellows:)
.remove() is a jQuery function that you can use to remove elements from the DOM.
Here's a tiny example:
$(".inputToRemove").remove();
Here's a fork of your jsFiddle for a working example.
From the docs:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, this example attaches a handler to 1,000 elements:
$( "#dataTable tbody tr" ).on( "click", function() {
alert( $( this ).text() );
});
A delegated-events approach attaches an event handler to only one element, the tbody, and the event only needs to bubble up one level (from the clicked tr to tbody):
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});
Related
I am trying to get the value of an input box that been .append() to the HTML recently. The Input box does not exist normally. it get .append() on button click by a function.
The Value of the input should be captured and sent via jQuery Ajax to backend(php).
The Function which append the Input field:
function toggleOrder(){
$(".orderContainer").append(`
<div class="orderFilterBox">
<input id="orderFilterInput" type="text" placeHolder="Enter IMEI">
</div>
`);
}
The Function where the input value captured and sent to backend
$(document).ready(function(){
$("#orderFilterInput").on("change paste",function(){
//DO THE MAGIC
//...
});
});
I belive that the problem being there that the code on the pageload where the input not exist. im not sure how to avoid that.
Also if you would suggsest a better question title to help other people, then please go for it
if you use .on you need focus on static element which exist in page load. orderFilterInput.on is bad if orderFilterInput does not exist.
You can try
$(document).on("ready", function(){
$("body").on("change paste","#orderFilterInput", function(){
//DO THE MAGIC
//...
});
});
or you can make your append button by jquery with event in your append function.
const btn = $('<input id="orderFilterInput" type="text" placeHolder="Enter IMEI">')
.on('copy paste', function() { .. });
$container.append(btn);
Event handlers are bound only to the currently selected elements; they
must exist at the time your code makes the call to .on(). To ensure
the elements are present and can be selected, place scripts after the
elements in the HTML markup or perform event binding inside a document
ready handler. Alternatively, use delegated event handlers to attach
event handlers.
Delegated event handlers have the advantage that they can process
events from descendant elements that are added to the document at a
later time. By picking an element that is guaranteed to be present at
the time the delegated event handler is attached, you can use
delegated event handlers to avoid the need to frequently attach and
remove event handlers. This element could be the container element of
a view in a Model-View-Controller design, for example, or document if
the event handler wants to monitor all bubbling events in the
document. The document element is available in the head of the
document before loading any other HTML, so it is safe to attach events
there without waiting for the document to be ready.
Here is the api reference:
https://api.jquery.com/on/
, So as suggested by #daremachine you need to use the delegated event handler
as:
$(document).on("change paste","#orderFilterInput", function(){
//DO THE MAGIC
//...
});
Is always better to use $(document).on('click', selector, fn) than $(selector).click(fn), since the 1st choice:
1) can handle dynamically created element
2) is faster during page load.. right? (since JS doesn't have to spend time querying and binding function to each selector)
Is it safe to forget about direct binding and always go for delegation?
.on()
Advantages
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored.
Performance
Attaching many delegated event handlers near the top of the document
tree can degrade performance. Each time the event occurs, jQuery must
compare all selectors of all attached events of that type to every
element in the path from the event target up to the top of the
document. For best performance, attach delegated events at a document
location as close as possible to the target elements. Avoid excessive
use of document or document.body for delegated events on large
documents.
.click()
This method is a shortcut for .on( "click", handler )
With my research, I come to a conclusion that a good delegate method is better than the direct binding. Let's talk from the begging. We know that dom event will bubble up from the target element to it's parent, grandparent until to the document. Though there are a little difference among IE and other browsers, Jquery event creates consistent cross-browser behavior. Thus, the obvious difference between the two methods is that:
Direct bind event will occur on the target (or from its descendants) and bubble up to document, while delegation just bubble up to the outmost bind target. Consider the example:
$("#myBtn").click(function(){
console.log("button was clicked");
});
document.onclick = function(){
console.log("document is clicked");
}
<div id="testDiv" style="background:darkgrey">
<button type="button" id="testBtn">click me</button>
</div>
When click the button, document.onclick will be triggered.
However, if replace with the delegate method like:
$("#myDiv").on("click", "#myBtn", function(){
console.log("myBtn was clicked");
});
The document.onclick will not be triggered. Meanwhile, notice that click on the outmost myDiv will not trigger the event.
Here comes to the key point. Using the delegate method in a good manner will improve the performance hugely. See this example (mutated from professional javascript for web developer):
<ul id="myLinks">
<li id="goSomewhere"> Go somewhere </li>
<li id="doSomething"> Do something </li>
<li id="sayHi"> Say hi </li>
</ul>
The traditional direct bind way would be:
$("#goSomewhere").click(function(){
window.location.href = "http://sample.com";
});
$("#doSomething").click(function(){
window.title = "I change the title";
});
$("#sayHi").click(function(){
alert("hi");
});
If there are many click events, numbers of bind operation will consume a lot of memory as well as a long page initial time. We can subtract to just one bind operation with delegation:
$("#myLink").on("click", function(event){
switch(event.target.id){
case: "goSomewhere":
window.location.href = "http://sample.com";
break;
case: "doSomething":
window.title = "title was changed";
break;
case: "sayHi":
alert("hi");
break;
}
});
This reduce much memory to use. To be more practical, you may need to use a object to replace switch-case module for the performance, if there are lots of cases, like:
var eventHandler = {
goSomewhere: function(){ window.location = "http://sample.com"; },
doSomething: function(){ window.title = "title changed"; },
sayHi: function(){alert("hi"); }
}
$("#myLink").on("click", function(event){
if(eventHandler[event.target.id]) eventHandler[event.target.id]();
});
Because javascript's object is actually a hash table.
Then, there comes an idea: just attach a single event to the document to handle all of the events. It's practical to events like mousedown, click, keydown and so on, not fit for mouseout, mousein. The advantage is clear: we just bind a event causing less memory, easy to remove the event handler, need not to wait for the document ready event as document has been be visible since it's child script is read. In contact, if you just bind every single event to document, the advantage will be gone.
Additionally, there is a trap if using direct bind, the example is from jquery: Considering a table with 1000 rows:
$( "#dataTable tbody tr" ).on( "click", function() {
console.log( $( this ).text() );
});
This will attach a hander to 1000 tr! But the following one just a single attachment to tbody:
$( "#dataTable tbody" ).on( "click", "tr", function() {
console.log( $( this ).text() );
});
After using AJAX to load a partial view in to a dialog on the page, this code, located in the partial itself NOT in the main page, runs and I get tabs as expected:
// Run this on page load
$(function () {
debugger;
$("#ProjectTabset").tabs();
});
This being the case, if the div containing the partial was removed from the DOM (using jQuery remove) then added again and the partial loaded in to it once more, it should run again, but it doesn't.
Why would it run the first time, but not any subsequent time? Could the problem be that the div in to which the partial is being inserted is not really removed somehow? (Though I am testing it is not present before creating, and it seems it is no longer part of the DOM.)
Please let me know if I can be more clear or provide any more detail :)
Since you have removed the element from DOM and added back dynamically you may need to use the delegated events via on() if you want events to be handled on dynamically added elements. Try the below and see if it helps.
$( document ).on( 'ready', function (e) {
$("#ProjectTabset").tabs();
})
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to
.on(). To ensure the elements are present and can be selected, perform
event binding inside a document ready handler for elements that are in
the HTML markup on the page. If new HTML is being injected into the
page, select the elements and attach event handlers after the new HTML
is placed into the page. Or, use delegated events to attach an event
handler, as described next.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers.
May be the links here will help you resolve the problem.
You should use .delegate():
// Run this on page load or ajax load complete
$('body').delegate('#ProjectTabset', 'ready', function() {
$("#ProjectTabset").tabs();
});
UPDATE:
$(document).delegate('#ProjectTabset', 'click', function() {
$('#ProjectTabset').tabs();
}
$.ajax(function(){
...
success: function(){
$('#ProjectTabset').click();
}
})
I dynamically generate some markup and inject it into the DOM like this:
content+='<td><a class="reportLink" onclick="showReport();return false;" href="'+layerResults.features[i].attributes['Information_External']+'">Info</a></td>';
I know it would be better to use jQuery to attach the click handler instead of using an inline handler.
The problems are, even using an inline handler and a function like this:
function showReport() {
console.log('stopped');
}
Still doesn't prevent the link from navigating away from my page.
The second problem is, when I try using
jQuery('.reportLink'.on('click', function(e) {
e.preventDefault();
console.log('clicked');
});
The event never gets attached. I'm using jQuery 1.7.2.
This is driving me a bit insane as it's a simple task I've done about a zillion times in jQuery <= 1.5.
Delegate the event handler to a parent element that exists at the time the dom is loaded. You can replace body with that parent.
jQuery('body').on('click','.reportLink', function(e){
e.preventDefault();
console.log('clicked');
});
from jquery docs .on()
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, this example attaches a handler to 1,000 elements:
to prevent it from navigating away, enter this right after "console.log('stopped');
return false;
for the second one, i usually use this syntax, maybe it'll help:
jQuery(".reportLink").click(function() {
//do something
});
I want a new text input box will be appended when i click onto the latest generated text box.
But It generates new text input box only when i click the first text input box. So, any solution?
<script type="text/javascript">
$(function(event){
$('.add-new').click(function(){
$('.add-new').removeClass();
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
});
</script>
<div>
<form method='post' name='login'>
<input type='text' name='user[]' class='add-new'/>
</form>
</div>
$('form').on('click','.add-new', function(){
Direct event => Delegate Event
Live DEMO
Full code:
$('form').on('click', '.add-new', function() {
$(this).removeClass('add-new');
$(this).closest('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.
on docs
demo http://jsfiddle.net/JuvwB/8/
Plz note: you should use $(this) as your even is bind to .add-new already.
rest all the above are nice solutions,
Hope this helps, cheers
code
$(function(event){
$('.add-new').on('click', function(){
$(this).removeClass();
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
});
$('form[name=login]').on('click', '.add-new', function() {
$(this).removeClass(); // $(this) instead of $('.add-new')
// $(this) point to the clicked element
// which you want
$('form').append("<br><input type='text' name='user[]' class='add-new'/>");
});
As you're changing the class name add-new and append new element dynamically with same class, so you need delegate event.
Read more about .on()
Note
syntax of .on() for delegate event
$(container).on(eventName, target, handlerFunction)
The reason why this doesn't work is because when you set the 'click' event your target doesn't exist, so no 'click' event is bound to it.
jQuery has a fancy function called the 'on' function that catches bubbling events.
$(document).on('click','.add-new', function(){
}
All events (click, mouseover, etc) start in the deepest node and bubble up through the html tree until the document. It is safe for you to catch them in the document, unless you explicitly call "stopPropagation" or return false on a processed in the middle of the bubling click handler function.
You can also catch it in the middle of the tree with $("form").on... or even $("div").on...