How to get the ID of dynamically generated buttons - javascript

I auto genrated some buttons
<div class="wrapper" id="wrapper"></div>
<script type="application/javascript">
var x, i, y;
for(i = 0; i <= 10; i++){
y = i;
x = "<button class=btn_class"+y+"id=btn"+y+"onclick(alert(this.id);>Ukor</button>";
$("#wrapper").append(x);
}
$("button").on("click", function(){
alert(this.id);
});
</script>
I want to be perform different action when any of the buttons are clicked.
but i can't seem to get get the buttons by id. I also need to send y as an arguement to the function

The problem is that you have no spaces separating the attributes. So you're creating an element that looks like:
<button class=btnclass0id=btn0onclick(alert(this.id);>Ukor</button>
So everything is going into the class attribute. You should put quotes around the attribute values, and spaces between the attributes.
There's also no need for the onclick attribute, since you're using $("button").on("click", ...) to do that.
So it should be:
x = "<button class='btn_class"+y+"' id='btn"+y+"'>Ukor</button>";
You can also use jQuery's object-oriented way to create elements:
x = $("<button>", {
"class": "btn_class" + y,
"id": "btn"+y,
text: "Ukor"
});
BTW, why do you put y in the class? Usually the point of classes is to have all the similar elements have the same class, so you can address them all at once.

It looks like you are building your HTML without the necessary spaces or punctuation between attributes, so your button HTML will look like this:
<button class=btn_class0id=btn0onclick(alert(this.id);>Ukor</button>
This means there is no id attribute.
Try fixing it up like this:
x = '<button class="btn_class' + y + '" id="btn' + y + '" onclick="alert(this.id);">Ukor</button>';
$("#wrapper").append(x);
...or better yet, use the jQuery API to build your DOM:
x = $('<button onclick="alert(this.id);">Ukor</button>').attr({
id: 'btn' + y,
className: 'btn_class' + y
});

Your problem is in the string formatting your code will generate
<button class=btnclass0id=btn0onclick(alert(this.id);>Ukor</button>
and you need:
<button class="btnclass0" id="btn0" onclick="alert(this.id);">Ukor</button>
var x, i, y;
for (i = 0; i <= 10; i++) {
y = i;
x = "<button class='btn_class" + y + "' id='btn" + y + "'>Ukor</button>";
$("#wrapper").append(x);
}
$("button").on("click", function() {
alert(this.id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper" id="wrapper"></div>

Add the content into a single string and then append it once into the dom - faster than appending each iteration. Then using a designated click event handler - alert the id of the button. And the classes need to be a common value - not unique like the id's. Also - you don't need "y" at all and if you need to send the number to a function you have it already in the id - just get the numerical portion of the id and you can use it as required.
$(document).ready(function(){
var x="";
for(i = 0; i <= 10; i++){
x += "<button class='btn_class' id='btn"+i+"'>Ukor</button> ";
}
$("#wrapper").append(x);
$(document).on('click','.btn_class', function(){
(alert($(this).attr('id')))
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper" id="wrapper"></div>

I recommend to use String template to avoid errors of spacing between attrs on concatenating -> Better in visibility of variables in String:
$(Array.from({length:11},(v,k)=>k)
.map((i)=>`<button class="btn_class${i}" id="btn${i}" onclick="alert(this.id)">Ukor${i}</button>`)
.join('')).appendTo('#wrapper')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper" id="wrapper"></div>

Related

Get Elements By Partial Attribute Value

I've been fiddling with this for several hours and I'm utterly stumped by its behavior. On JSFiddle, it seems to only be returning the values of the href attribute when I want the entire elements, but I can still use getAttribute(attribute) as if it's an element. In the userscript that this is for, it seems to completely break everything after calling the function(hence turning to JSFiddle and having no result to show here).
Why is this happening? How can I accomplish the stated goal?
HTML:
<a name="edit-a" href="http://example.com/edit1">foo</a>
<a name="moo" href="http://example.com/edit2">roo</a>
<a name="edit-b" href="http://example.com/boo">bar</a>
JavaScript function:
function getElementsByPartialValue(searchtext, searchattr, searchtag)
{
var searchreturn = [];
var searchreturni = 0;
var tagmatches = document.getElementsByTagName(searchtag);
for (var tagmatchesi = 0; tagmatchesi < document.getElementsByTagName(searchtag).length; tagmatchesi++)
{
if (tagmatches[tagmatchesi].getAttribute(searchattr).indexOf(searchtext) > -1)
{
searchreturn[searchreturni] = tagmatches[tagmatchesi];
searchreturni++;
}
}
return searchreturn;
}
Checking the result:
alert(getElementsByPartialValue('edit', 'name', 'a')[0]);
Result(https://jsfiddle.net/81s4g42a/3/):
http://example.com/edit1
Accessing other attributes(https://jsfiddle.net/81s4g42a/4/):
alert(getElementsByPartialValue('edit', 'name', 'a')[0].getAttribute('name'));
Result:
edit-a
Use Attribute-Contains Selector like this:
var tagmatches = document.querySelectorAll(searchtag + "[" + searchattr + " *= '" + searchtext + "']");
function getElementsByPartialValue(searchtext, searchattr, searchtag)
{
return document.querySelectorAll(searchtag + "[" + searchattr + " *= '" + searchtext + "']");
}
var elems = getElementsByPartialValue("edit", "name", "a");
for(var i = 0; i < elems.length; i++) {
elems[i].style.background = "red";
}
<a name="edit-a" href="http://example.com/edit1">foo</a>
<a name="moo" href="http://example.com/edit2">roo</a>
<a name="edit-b" href="http://example.com/boo">bar</a>
Use .querySelectorAll(), attribute is equal to or begins with followed by "-" selector
var tagMatches = document.querySelectorAll("a[name|='edit']");
console.log(tagMatches);
<a name="edit-a" href="http://example.com/edit1">foo</a>
<a name="moo" href="http://example.com/edit2">roo</a>
<a name="edit-b" href="http://example.com/boo">bar</a>
I hate to say this, but it's returning "name", not "href", if you want the url you should return the "href", not the "name"... Check your script and you'll find that you've set the name of the first tag to "edit-a", so when alerting the name of [0] you get "edit-a". If you access [1] you get "edit-b", and if you use 1 instead of 'name' you get "http://example.com/boo", and it's skipping the second one with "moo" as a name because you're only searching for ones with "edit" in its name, not its href/url.
alert(getElementsByPartialValue('edit', 'name', 'a')[0].getAttribute('href'));
I tested your code sample and find out, your code execute perfectly well. The problem is from the "alert()" function, try using console log, you will see that your code actually works.

Javascript function isn't recognized

I don't have many knowlege in javascript so I don't know what is the problem here,
I create divs dynamically in js and each div call a function when is clicked but the function is not recongized. This is part of the code
for (......) {
var listatema = document.createElement("div");
listatema.innerHTML += "<a href='javascript: void(0)' onClick='functest(" + pag + ")'>" + temat + "</a>";
document.getElementById('menu').appendChild(listatema);}
}
"tema" is a text, the function "functest" has an argument "pag[aux]", this is a number.
The function is:
function functest(arg){
console.log(arg)
}
other alternative that i tried is change that: onClick='"+ functest(pag) +"':
i change the position of Quotation marks "" and the function work good but it is executed when the page is loaded, it don't wait to do click.
Your code should work if you're doing something like:
function functest(arg) {
console.log(arg);
}
for (var i = 0; i < 10; i++) {
var listatema = document.createElement("div");
listatema.innerHTML += "<a href='javascript: void(0)' onClick='functest(" + i + ")'>" + i + "</a>";
document.getElementById('menu').appendChild(listatema);
}
<div id="menu"></div>
I would, however, recommend using addEventListener or setting the onClick handler on the document element object rather than setting the innerHTML. Note that setting innerHTML is not advised, especially when rendering user input. See https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations. In your case, it probably isn't really an issue, but it's good practice to avoid it if you can :)
for (var i = 0; i < 5; i++) {
var wrapper = document.createElement("div");
var listatema = document.createElement("a");
listatema.textContent = i;
listatema.href = "javascript:void(0)";
listatema.addEventListener('click', function(e) {
console.log(this.i);
}.bind({ i : i }));
wrapper.appendChild(listatema);
document.getElementById('menu').appendChild(wrapper);
}
<div id="menu"></div>
onClick='functest(\""+ pag +"\")'
you forgot to quote the parameter.

how to change called class in javascript when button is click?

I have a div which is
<div class="add1"></div>
I want the add1 become add+thenumber of length example:
var n= $('.add1').length + 1;
$('.add1').click(function(){
so what I did is
$('.add+n').click(function(){
but it doesnt work, please help me :(
You can store the number in a data attribute and increment on every click.
Change the class attribute from the data attribute value.
HTML
<div id="myDiv" data-num='1' class="add1">click me</div>
JS
document.getElementById('myDiv').addEventListener('click', function(){
var num = Number(this.getAttribute('data-num'));
num++;
this.setAttribute('data-num', num)
this.setAttribute('class', 'add' + num);
});
Try this
$('.add'+n).click(function(){
});
the n needs to be outside of the quotes else it will interpret it as a string. Like so:
$('.add' + n).click(function(){
At first i read your question wrong and i thought you wanted to change the div's class accordingly. Which you could do like this:
var n = 1;
var n= $('.add'+1).length + 1;
$('.add' + n).click(function(){
$(this).attr('class', 'add' + n); //for if you also want to change the class of the div
});
Make use of .addClass() to add and .removeClass() to remove classes
$('.add1').click(function(){
var n= $('.add1').length + 1; //reads n
$(".add1").addClass("add"+n); //adds new class
$(".add"+n).removeClass("add1"); //removes existing class
});
Here is the example: https://jsfiddle.net/danimvijay/ssfucy6q/
If you want to select the class with combination of a variable, use $('.add'+n) instead of $('.add+n').
$('.add'+n).click(function(){
//place code here
});
Here is the example: http://jsfiddle.net/danimvijay/a0j4Latq/
Here it is!! try this .. I code following exactly you need.
<input type="text" style="display:none;" name="qty" value="0" />
<p id="inc" class="">It's class will be Increased[concate with number]</p>
<input type="button" id="btn" name="btn" value="increase"/>
Now following is Main script that will help you ..
var incrementVar = 0;
$(function() {
$("#btn").click(function() {
var value = parseInt($(":text[name='qty']").val()) + 1;
$(":text[name='qty']").val(value);
$('#inc').removeClass('a' + (value-1));
$('#inc').addClass('a' + value); // I believe class names cannot start with a number
incrementVar = incrementVar + value;
});
});
i posted this code also on www.codedownload.in
Thank You.

Dynamically load Two Questions into separate forms as well as their appropriate answer options

I'm trying to have a button, that once pressed. Dynamically loads Two Questions (question1, and question2) into separate forms. But it also contains the questions 3 Answers to choose from. Currently my for loop adds an additional set of 3 answers(question 2's answers) to choose from to Question 1
OUTPUT Looks like the following :
It needs to be QUESTION 1 (YES, NO, OTHER) and QUESTION 2 (YES2, NO2, OTHER2)
CODE
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="center col-xs-12">
<button class="contentBtn btn"><label for="contentBtn">CONTENT</label></button>
</div>
<div class="row-2 center col-xs-12"></div>
<script src="js/jquery-1.11.3.min.js" type='text/javascript'>
</script>
<script>
$('.contentBtn').click(function(){
var contentArray = [
["QUESTION1?", "YES", "NO", "OTHER"],
["QUESTION2?", "YES2", "NO2", "OTHER2"]
];
for (var i = 0; i < contentArray.length; i++){
$('.row-2').append("<form><span class='question'>" + contentArray[i][0] + "<\/span><br>")
for (var x = 1; x < 4; x++){
$('form').append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
}
$('.row-2').append("<\/form><br>");
}
});
</script>
</body>
</html>
The short answer is that you are appending 'form', meaning you are appending every form on the DOM. The code is also corrupting the DOM. The inputs are not closed, and append should never be done in partials like given in the example.
// Always favor the 'on' events instead of the 'click' events.
$('.contentBtn').on('click', function () {
var contentArray = [
['QUESTION1?', 'YES', 'NO', 'OTHER'],
['QUESTION2?', 'YES2', 'NO2', 'OTHER2']
];
// we are going to use a for each on the first item,
// we could use a for as well but it just is really messy.
// remember that variables are defined at function scope, not block scope.
$(contentArray).each(function (index, item) {
// our item in the array is directly coming in to us now.
// do not add incomplete html blocks to the dom, always
// create them and then add them!
var newContent = $('<form><span class="question">' +
item[0] + '</span><br></form><br>');
// now we will foreach, but instead of going by a length of 4,
// I am looking at the actual length of the array.
for (var i = 1; i < item.length; i++) {
// we are going to precreate our dom object.
var answerContent = $('<input type="radio" value="' +
item[i] + '">' + item[i] + '</input>');
// now we are going to append the object to our form object.
newContent.append(answerContent);
}
// now that the structure is complete we will append the browser dom.
$('.row-4').append(newContent);
});
});
I have created a corrected fiddle with comments for you.
https://jsfiddle.net/t9h91nbk/
Hope this helps.
The problem is in this line :
$('form').append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
The javascript can't detect wich form you want to append input to it so it will append to all the forms in page, so you have to add an identifier to the form you create.
I'll add class to identify each form and append the input using this identifiers :
$('.row-2').append("<form class='form_"+i+"'><span class='question'>" + contentArray[i][0] + "</span><br>")
for (var x = 1; x < 4; x++){
$('.form_'+i).append("<input type='radio' value='" + contentArray[i][x] + "'>" + contentArray[i][x] + "");
}
Hope this helps.
Working fiddle

Adding and removing elements in Javascript?

I'm trying to make a generator for a mod menu in Call of Duty. I want people to be able to add a menu or delete one. I'm trying to id the menus sequentially so that I can use the text field values correctly. I made it so that if they delete a menu it changes the ids of all the other menus to one lower and same for the button id, but I don't know how to change the onlick event to remove the right element.
Better yet, if there's a better way to do this, I would love to know it.
<script type="text/javascript">
y = 1
function test2()
{
document.getElementById("test2").innerHTML += "<div id=\"child" + y + "\"><input type=\"text\" value=\"menu name\" \><input id=\"button" + y + "\" type=\"button\" value=\"remove?\" onclick=\"test3(" + y + ")\" /></div>";
y++;
alert(y);
}
function test3(x)
{
document.getElementById("test2").removeChild(document.getElementById("child" + x));
for(var t = x+1;t < y;t++)
{
alert("t is " + t + ". And y is " + y);
document.getElementById("button" + t).setAttribute("onclick" , "test3(t-1)");
document.getElementById("button" + t).id = "button" + (t-1);
document.getElementById("child" + t).id = "child" + (t-1);
}
y--;
}
</script>
<input value="testing" type="button" onclick="test2()" />
<div id="test2" class="cfgcode"></div>
I wouldn't worry about re-indexing all of the elements after you add or remove one, that seems a waste. It would be better to simply write a more generic function, rather than one with the element id hard coded into it.
For example, your first function could be written as so:
function genericFunction(el)
{
var html = ''; // create any new html here
el.innerHTML = html;
}
You can then add onclick handlers such as:
myDiv.onclick = function() { genericFunction(this) };
I would also agree with all the commenters above, use jQuery, it makes any code which interacts with the DOM much much simpler.

Categories

Resources