jQuery - capturing LAST dynamic element - javascript

I am adding new forms to my DOM dynamically, but the thing is that my code only captures first dynamically added element and not the last one.
This is my code. The screenshot below also explains everything.
Screenshot:
$('#buildyourform').on('click', '.remove_dyn_summary', function() {
var $txtarea = $(this).closest('b').find('.new_dyn_summary').val(); // this part is wrong
alert($txtarea)
});
P.S. my business logic doesnt allow me to add incrementing numbers in classes or something.
.last() or :last didnt work for me I guess because elements were added dynamically.
I am probably missing something very simple..

Use event delegation.
$(document).on('click','#buildyourform:last p.remove_dyn_summary', function() {
var $txtarea = $(this).parent().prev().prev().children('textarea.new_dyn_summary').val();
alert($txtarea);
});
Try the above.

Related

Add Class to Array of ID's in Javascript

I am using .map to get an array of element IDs (this is named 'ids') that have a 'default-highlight' class. After removing that class on mouseenter, I want to return that class to those specific id's (basically, leave it how I found it).
Two things are causing me trouble right now:
When I dynamically add data-ids to the td elements and then use those data-ids to create the array of 'ids' my mouseenter stops adding the 'HIGHLIGHT' class (NO idea why this is happening)
On mouseleave I can't loop through the 'ids' and return the 'default-highlight' class to the elements they originally were on
I figure I should be using something like this, but it obviously isn't working:
$.each(ids, function() {
$(this).addClass('default-highlight');
});
I have tried a number of things, but keep coming up short. I am attaching a link to a codepen.io where I use data-ids that are being dynamically added to the table (this one the mouseenter doesn't work) and a codepen one where I am using regular IDs for the default highlight and everything appears to work like it is supposed to be (It isn't, since I want to be using the dynamically generated data-ids and then the subsequently produced array to reapply those classes).
Both of these codepens have a gif at top showing how the interaction should work.
If anything is unclear, please let me know. Thanks for reading!
You need to add # before id selector
$.each(ids, function() {
$('#'+this).addClass('default-highlight');
});
or you can use common selector by the help of map() and join()
$(ids.map(function(i, v) {
return '#' + v;
}).join()).addClass('default-highlight');
or you can add # when getting the id's and then you just need to join them
var ids = $('.default-highlight').map(function(i) {
return '#'+$(this).data('id');
}).get();
...
...
...
$(ids.join()).addClass('default-highlight');
It seems like storing the IDs and using those is overkill when you can store a reference to the jQuery element directly:
$highlightCells = $('.default-highlight').removeClass('default-highlight')
And later give the class back:
$highlightCells.addClass('default-highlight')
Here's a codepen fork: http://codepen.io/anon/pen/ZbOvZR?editors=101
Use this way:
$.each(ids, function() {
$("#" + this).addClass('default-highlight');
});

jQuery .addClass() and .removeClass() only applies to first instance of the element

I have the following code below:
<script type="text/javascript">
var $info = $('#thumb');
enquire.register("(max-width: 480px)", {
match: function() {
$info.removeClass('col-xs-6');
$info.addClass('col-xs-12');
},
unmatch: function() {
$info.removeClass('col-xs-12');
$info.addClass('col-xs-6');
}
}).listen();
</script>
I am using Enquire.js to dynamically add and remove css classes from elements.
The above code works but only for the first '#thumb'. I have about 12 elements which have the thumb id. Anyone know how I can apply it to all elements with the same ID
You have to use a class. ID's are unique so they can only apply it once. If you do: $('.thumb') then you will be fine.
It might be helpful for you to run your source through an html validator, which would help point out that it's not valid to have more than one element with the same id. Which is why it's only updating the first of your 12 elements.
Take a read through this http://css-tricks.com/the-difference-between-id-and-class/ is one quick reference that can hopefully explain the what/why/how of what's going on here.
#xxx is get by id. and you need to make sure this id is unique. If you want to get by class is .xxx for get by class, you will get it in array. So need to to use for-loop to addclass or removeclass

how to use jquery loop function to target many element with different ids

Currently, I have this code:
$(document).ready(function(){
// #filtertab-00 replace this with your element id
$('#filtertab-00 .box-content .es-nav .elastislide-next, #filtertab-00 .box-content .es-nav .elastislide-prev').click(function() {
// trigger lazy load
$("#filtertab-00 img.lazy").each(function(i) {
$(this).delay(150*i).fadeIn(1000, function() {
var src = $(this).attr("data-original");
$(this).attr('src',src);
});
});
});
});
and i want to use this function to target object names (id) as below:
filtertab-00
filtertab-10
filtertab-20
filtertab-30
filtertab-40
filtertab-50
filtertab-60
....
filtertab-90
Does anyone know how to use the loop function to get it work?
i just want this:
when i click pre or next button after i select a tab(name varies from filtertab-00 to filtertab-90),it will activate lazyloading for images at current selected tab.
any idea is welcome!
Perhaps you could use jQuery's attribute-starts-with selector. You can then just select all IDs that begin with filtertab- using jQuery like this:
$('div[id^="filtertab-"]').each( //magic goes here );
Note: This method is slow because it has to search the DOM for elements with IDs that meet the criteria, but it does the job. I've never noticed an appreciable latency.
This is solved through selector magic as filoxo described but since you want the images, here's another version involving find() to get your actual images.
$('div[id^="filtertab-"]').find("img.lazy").each(function(i) {
$(this).delay(150*i).fadeIn(1000, function() {
var src = $(this).attr("data-original");
$(this).attr('src',src);
});
});
In addition to that, check out the impressive list of jQuery selectors. They cover a lot of ground :)

$.each only affects the first element?

Looping through all the elements of the class, I see the code below only affecting the first element in the array yet the console log logs every one of them.
del = $('<img class="ui-hintAdmin-delete" src="/images/close.png"/>')
$('.ui-hint').each(function(){
console.log($(this));
if ($(this + ':has(.ui-hintAdmin-delete)').length == 0) {
$(this).append(del);
}
});
The elements are all very simple divs with only text inside them. They all do not have the element of the class i am looking for in my if statement, double checked that. Tried altering the statement (using has(), using children(), etc). Guess i'm missing something very simple here, haha.
Will apperciate input.
I think what you need is (also if del should be a string, if it is a dom element reference then you need to clone it before appending)
$('.ui-hint').not(':has(.ui-hintAdmin-delete)').append(function(){
//you need to clone del else the same dom reference will be moved around instead of adding new elements to each hint
return del.clone()
});
You can do this:
$('.ui-hint:not(:has(.ui-hintAdmin-delete))').append(del);
without even using the each loop here. As jquery code will internally loop through all the descendant of the ui-hint class element and append the del element only to the descendant not having any .ui-hintAdmin-delete elements.
While it would probably help to see your HTML as well, try changing your conditional to
if (!$(this).hasClass('ui-hintAdmin-delete')) {
$(this).append(del);
}

Deleting <li> issue

I'm building a recipe saving application where I have a form that looks like this http://jsfiddle.net/LHPbh/.
As you can see, I have a set of form elements contained in an <li>. You can click Add Ingredient and have more li's added to the field.
My problem is:
The first li is the only one that deletes. If you click Add Ingredient, and then try and delete that one, nothing works?
Is there a way to not have the first li have a delete by it, but all subsequent li's have a delete link on the side? (Just because there should always be at least one ingredient?)
When you call clone(), it isn't duplicating the events. You need to call clone(true) in order for it to do this, as explained in the documentation.
You did not put an event listener on the cloned elements. Also, you should not give the "delete"-link its own id, as those need to be unique.
To make the first ingredient have no delete button, just don't include one in your markup but only dynamically create and append them to the cloned elements:
var deleteButton = $("<a class='float-left'>Delete</a>").click(deleteThis);
$('ul#listadd > li:first')
.clone()
.attr('name', 'ingredient' + newNum)
.append(deleteButton)
.appendTo('ul#listadd');
function deleteThis() {
var li = $(this).closest('li')
li.fadeOut('slow', function() { li.remove(); });
}
Demo at jsfiddle.net
http://jsfiddle.net/LHPbh/2/
$('.deleteThis').live("click", function () {
var li = $(this).closest('li')
li.fadeOut('slow', function() { li.remove(); });
});
It is answer to the 1. point. The problem was, that the eventhandler binding did not happen in newly created elements, because this code runs only on the load of the page. This can be solved by using .live(). And an other problem was, that id-s must be unique. So instead id, here you can use class .deleteThis.
http://jsfiddle.net/LHPbh/19/
This has added answer to the 2. point:
if ($("#listadd li").length == 1) {
return;
}
If the list only contains 1 li element the rest of the callback will not run.
You are adding items that are added to the DOM dynamically, thus jQuery can't access them :)
In this case you can use the following code:
$(document).on('click', '.selector', function(e) {
//code here
});
Secondly, you were loading a quite old version of jQuery.
Thirdly, you were trying to select an element with an ID that already existed, and ID's can only exist one time. I've changed it to a class in the updated example.
Lastly, you were defining the class of the link twice like this:
<a class='float-left' id="deletethis" href='#' class="deletethis">Delete</a>
That also gave a problem, so I changed it to correct markup like this:
<a class='float-left deletethis' href='#'>Delete</a>
Good luck :) I've updated your jsFiddle here:
http://jsfiddle.net/q4pf6/

Categories

Resources