Increase element ID by one after every click? - javascript

I am trying to clone multiple divs on my page by using the jQuery .clone() method. The problem is, as soon as a div is cloned, it needs to have a unique ID. The cloned ID has to be there too. I was thinking I could keep the old ID and then just add a number on, increasing as more div's are on the page.
Example: base ID = one, so div one would be id, then div two would be id-2, then div three would be id-3, etc.
Is this possible? My attempt at this is below:
$("a").click(function(){
var target = $(this).attr("href");
var id = $(target).attr("id");
$(target).clone().attr("id",id + $(id).size()).attr("class","drag").appendTo("body");
});
Each a tag looks like this:
One
Two
Then the cloned element looks like this:
<div class="drag base" style="background-color:blue" id="one"></div>
<div class="drag base" style="background-color:green" id="two"></div>

See this: http://jsfiddle.net/3tu7V/1/
$(function(){
$("a").click(function(){
var target = $(this).attr("href");
var id = $(target).attr("id");
var click = $(target).data("clicked") || 0;
$(target).data("clicked", ++click);
$(target).clone().attr("id",id + click).attr("class","drag").appendTo("body");
});
});
​
I think this does what you want according to your comment:
"Ah, is there any way for the element ID to be reset when the base ID is unique? Ex.) "If you clone div "one", it will produce "one-1", then "one-2", but if you then clone div "two", it will produce "two-3", not "two-1""

i think in ur case $(id).size() will always be = 2. (only the last one and its clone will have the same id)
why don't you use a global variable var clickNumber that you increment each time.
your code will be
var clickNumber = 0;
$("a").click(function(){
var target = $(this).attr("href");
var id = $(target).attr("id");
clickNumber ++;
$(target).clone().attr("id","id-" + clickNumber).attr("class","drag").appendTo("body");
});

See this live example
var increment = 2;
$('a').live('click', function() {
$(this).clone().attr('id','id-' + (increment++)).appendTo('body');
});​
Result:

Revised answer:
You can use the jQuery attribute starts with selector to keep a track of the clones, and their counts:
$("a").click(function() {
var targetId = $(this).attr("href").substring(1); // "one", "two"
var count = $("div[id^=" + targetId + "]").length; // initial value will be 1
$("#" + targetId).clone().attr("id", targetId + '-' + count).attr("class", "drag").appendTo("body");
});
Demo

You could do something like this:
$('a').addClass('link');
$('body').on('click', 'a', function() {
$(this).clone(true).attr('id', 'id-' + $('.link').length).appendTo('body');
});​
Demo: http://jsfiddle.net/Em8PE/1/

Related

jQuery click not working for dynamicly created elements

I looked at the other solutions on SO for this problem and none of them seem to help my case. To give you some background, yesterday I was trying to select all DIVs by a class and store their IDs. See this Now that I have the IDs I want to create some new elements and incorporate the IDs and be able to click on these new elements. I went to JSFiddle to show you a demo but the crazy part is over there, my code works, yet in my app (Chrome extension) it doesn't. What's even crazier is that I'm already implementing jQuery click events in other parts of it without a problem so I'm really confused why it's not working in this particular case. Here's the JSFiddle that works but in my app it doesn't do anything on click. Thanks for any help! I'm sorry for posting so many (silly) questions.
HTML:
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>
JS:
var HAContainer = document.querySelectorAll('.HA');
var HALength = document.querySelectorAll('.HA').length;
var id = [];
var j = 0;
$('.HA').each(function(){
id[j++] = $(this).attr('id');
});
for (var i=0; i<HALength; i++) {
var HABtn, HABtnImg, HAImgContainer;
HABtnImg = document.createElement("img");
HABtnImg.src = ("http://www.freesmileys.org/smileys/smiley-laughing002.gif");
HABtnImg.className = "ha-icon";
HAImgContainer = document.createElement("div");
HAImgContainer.setAttribute("id", 'HA-'+id[i] + '-container');
HAImgContainer.appendChild(HABtnImg);
HABtn = document.createElement("div");
HABtn.className = 'ha-button';
HABtn.setAttribute("id", 'HA-container');
HABtn.appendChild(HAImgContainer);
HAContainer[i].appendChild(HABtn);
HAClick(id[i]);
}
function HAClick(id) {
$('#HA-'+id+'-container').click(function() {
alert("clicked on ID " + id);
});
}
You have to delegate your event in order to make it work with dinamically added elements:
$('body').on("click", '#HA-'+id+'-container', function() {
alert("clicked on ID " + id);
});
I've noticed something and will edit with a better approach:
Change:
HABtn.setAttribute("id", 'HA-container');
To:
HABtn.setAttribute("id", 'HA-'+id[i] + '-inner-container');
HABtn.setAttribute("class", 'HA-container');
And instead of:
function HAClick(id) {
$('#HA-'+id+'-container').click(function() {
alert("clicked on ID " + id);
});
}
simply attach once the event with delegation:
$('body').on("click", '.HA-container', function() {
alert("clicked on ID " + $(this).attr('id'));
});
jsFiddle implicitly selects the javascript you use to be placed inside of an onload event handler.
As a result your code is wrapped with the onload event handler and basically looks likes this
window.onload = function(){
//your code here
};
The reason it works in jsFiddle is because the script is executing once the DOM is loaded and thus can interact with the elements as they are in the DOM. It is possible that your chrome extension is not acting after the elements have been loaded.
It would be prudent to wrap your javascript in the document.ready shortcut
$(function(){
//your code here
});
Given that, there are still some issues which exist in your code. It is not clear why you need to have that nested div structure, perhaps as a result of css styling, but one issue is the duplication of ids. They could probably just be class names (I am referencing "HA-container").
jQuery offers a very easy way to create elements in the constructor that you can take advantage of here. It will allow your code to be more streamlined and readable.
Further, you can store the id you use inside of the container element's jquery object reference for data using .data('id',value). This will all you to also assign the click event handler immediately inside of using another function to assign it.
jsFiddle Demo
$('.HA').each(function(){
var btn = $('<div class="ha-button HA-container">');
var cont = $('<div id="'+this.id+'-container">').data('id',this.id);
cont.click(function(){ alert("clicked on ID " + $(this).data('id')); });
var img = $('<img src="http://www.freesmileys.org/smileys/smiley-laughing002.gif" class="ha-icon" />');
$(this).append(btn.append(cont.append(img)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>
I'd re-write it a bit to take advantage of jQuery:
for (var i=0; i<HALength; i++) {
var HABtnImg = $('<img/>')
.attr('src', 'http://www.freesmileys.org/smileys/smiley-laughing002.gif')
.addClass('ha-icon');
var HAImgContainer = $('<div/>')
.attr('id', 'HA-'+id[i] + '-container')
.append(HABtnImg);
var HABtn = $('<div/>')
.addClass('ha-button')
.append(HAImgContainer);
//don't use duplicate ID's here
$(HAContainer[i]).append(HABtn);
}
And later attach the event like so:
$(document).on('click', '.ha-button', function(e){
//your click code here
var id = $(this).find('div').attr('id');
alert("clicked on ID " + id);
});

Javascript: indexOf($(this) to get the array-index value of clicked element?

I have an array with buttons:
var buttonnumber = ["#btn1", "#btn2", "#btn3", "#btn4", "#btn5"];
If one of them is clicked I want to get their index-value in the array:
$("#btn1, #btn2, #btn3, #btn4, #btn5").click(function() {
var y = buttonnumber.indexOf(this); //($(this)) doesn't work either!
});
This doesn't work.
I used the jQuery method .index() instead:
var y = $(this).index();
but I'd rather not because the order of the buttons in the html is not the same as in the array.
Thanks for your help!
Since your array has IDs with hashes, then you need to search for the ID with a hash, not the element itself. There are two solutions:
Make your button array reference objects instead of IDs
var buttonnumber = [$("#btn1"), $("#btn2"), $("#btn3"), $("#btn4"), $("#btn5")];
$("#btn1, #btn2, #btn3, #btn4, #btn5").click(function() {
var y = buttonnumber.indexOf($(this));
});
or do the indexOf against the id of the object you are clicking:
var buttonnumber = ["#btn1", "#btn2", "#btn3", "#btn4", "#btn5"];
$("#btn1, #btn2, #btn3, #btn4, #btn5").click(function() {
var y = buttonnumber.indexOf("#" + this.id);
});
You can also write that click selector as:
var buttonnumber = ["#btn1", "#btn2", "#btn3", "#btn4", "#btn5"];
$(buttonnumber.join()).click(function() {
var y = buttonnumber.indexOf("#" + this.id);
});
In modern browsers, you also no longer need jQuery for something like this:
var buttonnumber = ["#btn1", "#btn2", "#btn3", "#btn4", "#btn5"];
// cast nodelist that's returned from querySelectorAll to array
Array.prototype.slice.call(document.querySelectorAll(buttonNumber.join()))
.forEach(el => {
el.addEventListener("click", (event) => {
let y = buttonnumber.indexOf("#" + this.id);
});
})
buttonnumber.indexOf(this);
Supposed to be
buttonnumber.indexOf('#' + this.id);
this corresponds to the DOM element. Need to get the id of that element and get the index based of of it.
Get the clicked items ID attribute with $(this).attr('id') and get your index from the string...
$("#btn1, #btn2, #btn3, #btn4, #btn5").click(function() {
var y = buttonnumber.indexOf($(this).prop("id"));
});

Creating divs with different id's

i have one question regarding creation of divs:
I have button, when user clicks on it, javascript (or jquery) needs to create a div. But when user clicks again, it should create another div, but with different id. So, every time user clicks should be created div with different id.
I partialy know how to create div, but i have no idea how to make divs with different id's.
var c = 0; // Counter
$('#add').on('click', function() {
c += 1;
$('#parent').append('<div id="child'+ c +'">'+ c +'</div>');
});
#child1{color:red;}
#child2{color:blue;}
#child3{color:orange;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">ADD</button>
<div id="parent"></div>
var divcount = 1;
$('button').click(function(){
$('<div/>', { id:'comment'+divcount++ })
});
Here's a random ID generator for you.
function createParanoidID() {
return 'id_' + Math.floor(Math.random() * 9e99).toString(36);
}
createParanoidID(); // id_1js7ogi93ixt6x29w9svozegzhal67opdt3l3cf1iqidvgazlyaeh1ha7a74bswsg
createParanoidID(); // id_1fleq6chguuyyljhy39x3g7mg661mg845oj8fphnxgvm0bdgz7t3w0q01jptogvls
createParanoidID(); // id_ajz1ft17ml4eyz08gd3thcvq3fx1ycr927i0h2zgyw8bzq9wurv1gdfogly8tbls
Using a variable as counter and the "attr" function to set the id attribute.
HTML
<button id="button">Create Div</button>
<div class="container"></div>
jQuery:
$('#button').on('click', function() {
var count = $('div.container div').length,
id = count + Math.floor(Math.random() * 100);
$('div.container').append('<div id="'+ id+'">ID of this div is: '+ id +' </div>');
});
DEMO
Here's the easy way to do this.
Firstly, you'll need a button:
​<button id="onClickOfThis​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ButtonAnewDivWithArandomIDwillBeInserted"></button>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
Then the javascript:
$("#onClickOfThisButtonAnewDivWithArandomIDwillBeInserted").on('click', function() {
var myID = 'randomIDnumber_'+Math.random()+Math.random()+Math.random()+Math.random()+Math.random()+Math.random();
var MyNewElement = document.createElement('div');
MyNewElement.id = myID.replace(/\./g, '');
$(MyNewElement).appendTo('body');
});
Here's a FIDDLE
If you don't want to use global counter like in previous answers you can always get number of children and use that as relative value from which you will create another id.
Something like this (with jQuery):
function add_another_div() {
var wrap_div = document.getElementById("#id_of_div_who_contain_all_childrens");
var already_childs = $("#id_of_div_who_contain_all_childrens").children().length;
var div = document.createElement('div');
var divIdName = 'new_div-'+ (already_childs+1);
div.setAttribute('id', divIdName);
wrap_div.appendChild(div);
}
Of course, this requires for all of your children to have same parent (same wrapper). If that is not the case, and they are separated across multiple wrappers, then just use unique class name for all of them, and count them like that. I found this approach much better and easier instead of using global counters which I need to take care about.

Select by next instance of class with jQuery

I'm looking to convert a function that selects by id to select the next instance of a given class.
Here is the code.
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
Suppose you have this HTML:
<div id="test"></div>
<img>
<br>
<div></div>
<input>
<div class="abc">Found it</div>
<div class="cdf"></div>
Updated at 2021
The original answer is quite old now. Since the original question have the jQuery tag, the answer keeps valid and usable. But for those coming here with the hope to see an updated JavaScript code with no dependency on jQuery, take a look on how querySelector is a awesome nowadays:
const next = document.querySelector('#test ~ .abc')
next.textContent = 'Yeah, you found it!'
So the secret is to use the general sibling combinator that matches all iterations of the second element, but with querySelector that returns only the first match.
Original answer
So you select the first div by id:
var some = $("#test");
Then you want to find the next div with the class abc:
var next = some.nextAll("div.abc");
Suppose you want a variable as the className:
var x = "abc";
var next = some.nextAll("div." + x);
If I understand your question:
function nextItem(className) {
return $('#ID').closest('.' + className);
}
using closest: http://api.jquery.com/closest/
Select by ID in jQuery:
$('#class_name')
Select by class in jQuery:
$('.class_name')
Get the next item in jQuery:
$('.class_name').next('.class_name')
Using this, you can do something like
// Something to remember the current element
var currentElement = false;
function getNext(className)
{
// First time, there will be no current element
if (!currentElement)
{
currentElement = $('.' + className);
return currentElement;
}
// Other times...
currentElement = $(currentElement).next('.' + className);
return currentElement;

Get the next div in the doc after the current one with the same class

On click of the current div i want the very next div with the same class name in the entire document. Document is having a very complex nested structure.
<div><div><div class='1'></div></div></div>
<div><div class='1'></div></div>
<div><div><div><div><div class='1'></div></div></div></div></div>
Assuming that the elements are not siblings, you could do something like this:
var $elements = $('.someClass');
$elements.click(function() {
var $nextElement = $elements.eq($elements.index(this) + 1);
});
Reference: eq, index
DEMO
jQuery('currentDiv .className').click(function(){
var target = jQuery(this).next('.className');
});

Categories