Jquery: Get attribute value of dynamically created element - javascript

I created a div dynamically, and on click event I want to get it's attribute value, but when I try to do that, it throws me an error. "jQuery(...).attr(...).val is not a function", refer my code below
jQuery("#target1").on("click", function(){
jQuery("#target_block").append('`<div id="target2" data-rel-pid="12345">Click Me</div>`');
});
jQuery("#target2").on("click", function(){
var bid=jQuery(this).attr("data-rel-pid").val();
});

Actually the error is in this line :
var bid=jQuery(this).attr("data-rel-pid").val();
There is no need to cal .val() on .attr()
var bid=jQuery(this).attr("data-rel-pid");
.attr() itself will return the value.
For more to this, refer here.

Remove the .val()
jQuery("#target2").on("click", function(){
var bid=jQuery(this).attr("data-rel-pid");
});

As you are already using jQuery and you want to fetch a data attribute you can also do something like this.
$("#target2").on("click", function(){
var bid=$(this).data("rel-pid");
});

As target2 is being appended later in the life cycle of the web page, you need to use event delegation to attach event to dynamically appended elements.
Remove .val(), Use .attr() to get the value of an attribute for the first element in the set of matched elements or set one or more attributes for every matched element.
Try this:
jQuery("#target1").on("click", function() {
jQuery("#target_block").append('<div id="target2" data-rel-pid="12345">Click Me</div>');
});
jQuery("#target_block").on("click", '#target2', function() {
var bid = jQuery(this).attr("data-rel-pid");
alert(bid);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="target1">target1</div>
<div id="target_block">target_block</div>

You can use this code -
jQuery("#target2").on("click", function(){
var bid = jQuery(this).data("rel-pid");
});

Related

How do you target an element that is dynamically generated? [duplicate]

Beginner to all of this, playing around with Firebase. Basically, I want to retrieve text entries from Firebase and have an "Approve" button next to it. When the button is clicked, I want that specific text entry to be pushed to a new Firebase location and the text removed from the page. I am creating the button and the text dynamically and I am having some trouble with selecting the button and the divs I created. I know I have to use on() but I'm unsure of how to use it.
Thanks!
approveRef.on('child_added', function(snapshot) {
var posts = snapshot.val();
$('<div id="post">').text(posts.text).append('<button style ="button" id="approve">Approve</button>').appendTo($('#feed'));
});
$('#approve').on("click", function(){
var text = $('#post').val();
postsRef.push({'text':text});
$('#post').remove();
});
You have to bind .on() on a container of your dynamically added element that is already on the page when you load it, and have it like this:
$('#yourContainer').on('click', '#approve', function(){
//your code here..
});
Your .on() didn't work, because you are adding the button dynamically. You can't find the dynamically added elements directly using that elements id selector like $('#approve'). So you should
bind .on() with $(document) selector. This will always contain your dynamically added elements.
$(document).on( eventName, selector, function(){} );
$(document).on('click','#approve',function(){
//your code here
});
I find a quick dip into the DOM, and then running back into jQuery very handy for this problem:
// Construct some new DOM element.
$(whatever).html('... id="mynewthing"...');
// This won't work...
$("#mynewthing")...
// But this will...
$(document.getElementById("mynewthing"))...
This works by turning the DOM object directly into a selector. I like it because the approach is transparent in operation/intent.
Another alternative, simpler to understand, less powerful, also perfectly valid, is to simply bind the event while you create the element:
approveRef.on('child_added', function(snapshot) {
var posts = snapshot.val();
var $button = $('<button style ="button" id="approve">Approve</button>');
$button.on("click", function(){
var text = $('#post').val();
postsRef.push({'text':text});
$('#post').remove();
});
$('<div id="post">').text(posts.text).append($button).appendTo($('#feed'));
});
Another problem you are going to run into, assuming there will be more than one of these on a page, is that you are using IDs in the records. They're going to clash if they aren't unique.
A great alternative is to refer to these items with data-* tags or other identifying characteristics, such as css tags. But in your case, you don't need them at all!
approveRef.on('child_added', function(snapshot) {
var posts = snapshot.val();
var id = snapshot.name();
var $button = $('<button style="button">Approve</button>');
$button.on("click", function(){
// use parent.closest(...) in place of an ID here!
var text = $(this).parent().closest('textarea').val();
postsRef.push({'text':text});
$(this).parent().remove();
});
/* just an example of how to use a data-* tag; I could now refer to this element using:
$('#feed').find('[data-record="'+id+'"]') if I needed to find it */
$('<div data-record="'+id+'">').text(posts.text).append($button).appendTo($('#feed'));
});
I don't sure exactly what are you looking for. You can use .find() to select dynamically elements. I think .find() will look at the html structure again to get needed elements.
$("#button").click(function(e){
$(".parentContainer").find(".dynamically-child-element").html("Hello world");
});
Or
$(".parentContainer").find(".dynamically-child-element").html("Hello world"); // not in click event
So this is my demo

JQuery selector does not work in dynamically created content?

I am trying to retrieve the .html() .val() or something else within a html element, this is my html code (generated dynamically):
<div class="presupuesto"><h2 class="precio" id="precio" value="1202">1.202,00 €</h2>
I need the .val() attribute!
With JQuery and JavaScript I want to show, what option from a select has been selected and then show the information about h2 tag (price). This is my JS code:
$('select').on('change', function (e) {
var optionSelected = $("option:selected", this);
var valueSelected = this.value;
alert(valueSelected);
alert(("#precio").val());
});
The first alert(valueSelected) works well, but the second one triggers a TypeError
Thanks in advance!
As you said that you have dynamically generated elements. Then You need to use event-delegation:-
$(document).on('change','select',function(){
alert($(this).val()); // to get select value
alert($('#precio').attr('value')); // try to use data-attribute which is standered way
});
Note:- Since <h1>,<h2>..,<div>,<ul><li><p>.... these elements don't have value attribute (In standered way). So use data-attribute option for them like below:-
<h2 class="precio" id="precio" data-value="1202">1.202,00 €</h2>
And then change jQuery code just a bit like below:-
alert($('#precio').data('value'));

Event delegation issue with JQUERY

I am new in Jquery and I am trying to understand how event delegation work.
I am trying this:
$("#32298").on( 'click',function() { // event delegation
alert("df");
var imgs = document.getElementById("32298")[0].src;
alert(imgs);
});
When I click on the image with this Id I get the first alert but it doesn't work the second alert.
What am I doing wrong here?
Thank you.
If you want to perform event delegation then the second argument of the event handler function needs to be a selector to match the element that matches the one you want to be clicked.
$(document.body).on('click', "#32290", function(event) {
The problem with your code has nothing to do with event delegation. getElementById returns a single element (an id must be unique in the document), not a HTML Collection. (Compare with getElementsByTagName and getElementsByClassName which use the plural Elements.) It won't have a 0 property.
var imgs = document.getElementById("32298").src;
Since you're using jQuery, you can simply use the $(this) constructor, rather than document.getElementById():
$("#32298").on( 'click',function() {
alert("df");
var imgs = $(this).attr('src');
alert(imgs);
});
For what it's worth, this isn't event delegation by the way, it's just an event bound to an element.
If you must use vanilla JS to fetch the src attribute, you don't need to pass an index to the returned value of getElementById(), since this function returns a DOMObject, not an array. Update as follows:
$("#32298").on( 'click',function() {
alert("df");
var imgs = document.getElementById("32298").src;
alert(imgs);
});
It's also worth noting that IDs should be unique, so #32298 should reference a single element in the DOM. I don't know whether it's a typo, but it appears that you may have multiple elements with the same ID (since you use the variable name imgs - i.e. plural).
you can try this
$("#32298").click( function() {
alert("df");
var imgs = $(this).attr('src');
alert(imgs);
});

Get elements by data attribute and part of id in jQuery

I need to get elements by data attribute and part of id in jQuery.
I have following code.
<div class="bridgeSelectedDiv" id="bridgeDiv_13234" onclick="SelectBridgeLine(this);" data-bridgeuid="b2a42066-00e2-4b6e-bdef-397468573b75"></div>
<div class="bridgeSelectedDiv" id="bridgeDiv_13432" onclick="SelectBridgeLine(this);" data-bridgeuid="b2a42066-00e2-4b6e-bdef-397468573b75"></div>
<div class="bridgeSelectedDiv" id="bridgeDiv_45646" onclick="SelectBridgeLine(this);" data-bridgeuid="b2a42066-00e2-4b6e-bdef-397468573b75"></div>
function SelectBridgeLine(element) {
var bridgeuid = $(element).attr("data-bridgeuid");
var partofSelectedBridgeLine = $('div[id^="bridgeDiv_"]').data("bridgeuid");
console.log(partofSelectedBridgeLine);
}
But it returns only 1 element not all of them.
Any clue? Thank you!
From the docs of .data()
Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.
So whats happening here is it gets the data value for first element only. You need to iterate over them using .each() to get for all elements in matched selector:
$('div[id^="bridgeDiv_"]').each(function(){
console.log($(this).data('bridgeuid'))
});
Demo
It returns only 1 element because you are doing onclick="SelectBridgeLine(this);", and this will always point to current element on which the click handler exists, instead do:
$('.bridgeSelectedDiv').click(function(){
console.log($(this).data('bridgeuid')); //you can use .data()
});
or
$('div[id^="bridgeDiv_"]').click(function() {
console.log($(this).data('bridgeuid'));
});
Try
$('div[id^="bridgeDiv_"]').each(function(){
console.log($(this).data("bridgeuid")); });

javascript variable for jquery script

I dont know Javascript at all, so sorry for asking a question like this...
This is what I have:
$(document).ready(function(){$("#more0").click(function(){$("#update0").slideToggle("normal");});});
$(document).ready(function(){$("#more1").click(function(){$("#update1").slideToggle("normal");});});
$(document).ready(function(){$("#more2").click(function(){$("#update2").slideToggle("normal");});});
$(document).ready(function(){$("#more3").click(function(){$("#update3").slideToggle("normal");});});
$(document).ready(function(){$("#more4").click(function(){$("#update4").slideToggle("normal");});});
$(document).ready(function(){$("#more5").click(function(){$("#update5").slideToggle("normal");});});
$(document).ready(function(){$("#more6").click(function(){$("#update6").slideToggle("normal");});});
$(document).ready(function(){$("#more7").click(function(){$("#update7").slideToggle("normal");});});
$(document).ready(function(){$("#more8").click(function(){$("#update8").slideToggle("normal");});});
$(document).ready(function(){$("#more9").click(function(){$("#update9").slideToggle("normal");});});
$(document).ready(function(){$("#more10").click(function(){$("#update10").slideToggle("normal");});});
And So On.. Until #more30 and #update30...
So... Right now, my pages has 30 lines :)
Is there a way to do it less complicated?
Thanks!
Use attribute selector ^= . The [attribute^=value] selector is used to select elements whose attribute value begins with a specified value.
$(document).ready(function(){
$("[id^='more']").click(function(){
$("#update" + $(this).attr('id').slice(4)).slideToggle("normal");
});
});
Try to use attribute starts with selector to select all the elements having id starts with more , then extract the numerical value from it using the regular expression and concatenate it with update to form the required element's id and proceed,
$(document).ready(function(){
$("[id^='more']").click(function(){
var index = $(this).attr('id').match(/\d+/)[0];
$("#update" + index).slideToggle("normal");
});
});
use attribute start with selector
$(document).ready(function(){
$("[id^='more']").click(function(){
$("[id^='update']").slideToggle("normal");
});
});
//select all elements that contain 'more' in their id attribute.
$('[id^=more]').click(function(){
//get the actual full id of the clicked element.
var thisId = $(this).attr("id");
//get the last 2 characters (the number) from the clicked elem id
var elemNo= thisId.substr(thisId.length-2);
//check if last two chars are actually a number
if(parseInt(elemNo))
{
var updateId = "#update"+elemNo;//combine the "#update" id name with number e.g.5
}
else
{
//if not, then take only the last char
elemNo= thisId.substr(thisId.length-1);
var updateId = "#update"+elemNo;
}
//now use the generate id for the slide element and apply toggle.
$(updateId).slideToggle("normal");
});
Well first of all, you could replace the multiple ready event handler registrations with just one, e.g
$(document).ready(
$("#more0").click(function(){$("#update0").slideToggle("normal");});
//...
);
Then, since your buttons/links has pretty much the same functionality, I would recommend merging these into a single click event handler registration as such:
$(document).ready(
$(".generic-js-hook-class").click(function(){
var toggleContainer = $(this).data('toggleContainer');
$(toggleContainer).slideToggle("normal");
});
);
The above solution uses HTML Data Attributes to store information on which element to toggle and requires you to change the corresponding HTML like so:
<div class=".generic-js-hook-class" data-toggle-container="#relatedContainer">Click me</div>
<div id="relatedContainer>Toggle me</div>
I would recommend you to use Custom Data Attributes (data-*). Here You can store which element to toggle in the data attributes which can be fetched and used latter.
JavaScript, In event-handler you can use .data() to fetch those values.
$(document).ready(function () {
$(".more").click(function () {
$($(this).data('slide')).slideToggle("normal");
});
});
HTML
<div class="more" data-slide="#update1">more1</div>
<div class="more" data-slide="#update2">more2</div>
<div id="update1">update1</div>
<div id="update2">update2</div>
DEMO

Categories