Using JS loops to send unique vars from HTML buttons to function - javascript

Beginner here. I have a loop that creates 26 buttons with unique ID's and values. What I'm struggling with is figuring out the proper way to send the button's ID to a function so that I can store unique vars for each button independently without creating more than one function. I currently have an array with the 26 items I need for my buttons and the following loop:
function makeButtons() {
for (var i = 0; i < 26; i++) {
document.getElementById("whereButtonsGo").innerHTML += "<input type = 'button' value = '" + items[i] + "' id = 'button" + items[i] + "' onclick = doThing(button" + items[i] + ")'>";
}
}
I want the argument in the onclick function to be sent to a function such as:
function doThing(id) {
document.getElementById("'" + id.value + "'").style.color = "pink";
}
But so far I haven't been able to get this to work. Any help would be greatly appreciated!

Maybe this is what you are looking for:
makeButtons();
function makeButtons() {
for (var i = 0; i < 26; i++) {
document.getElementById("whereButtonsGo").innerHTML += "<input type = 'button' value = '" + i + "' onclick = doThing(this)>";
}
}
function doThing(currentButton) {
currentButton.style.color = "pink";
}
<div id="whereButtonsGo"/>
Try to keep the IDs as simple as possible

I recommend against using innerHTML for creating elements that you actually want to do something. Even if it works, your code will be amazingly unclear. Instead, write code that demonstrates that you're actually creating and adding elements:
var items = [1,2,3,4,5,6];
function makeButtons() {
var container = document.getElementById("whereButtonsGo");
for (var i = 0; i < items.length; i++) {
var button = document.createElement("button");
button.type = 'button';
button.value = items[i];
button.innerText = items[i];
button.id = 'button'+items[i];
button.onclick = doThing;
container.append(button)
}
}
function doThing() {
console.log('click of ' + this.id);
}
makeButtons();
Note that you don't need to pass the id in the function call for the event - the button that was clicked will be available as this.
Here is a fiddle.

Related

How to use JavaScript to retrieve a html element that is also created in JavaScript

The html buttons are created in JavaScript, each with their own ID. They activate the same function when pressed, and I want to know which button is pressed. I use this.id to see the ID of the button pressed. I think, since I haven't retrieved the buttons in JavaScript (eg. button = document.getElementById('button')), it doesn't work. I don't know how to do this with HTML elements created inside the script.
var paragraph = document.getElementById('paragraph');
var cabins = [1,2,3];
for (var i = 0; i < cabins.length; i++) {
paragraph.innerHTML += "Cabin " + cabins[i] + "<br><br><button id='cabin" + cabins[i] +"' onclick='purchaseCabin()'>Purchase</button><br><br>"
}
function purchaseCabin() {
var cabinId = this.id;
console.log(cabinId);
}
<p id="paragraph"></p>
Expected result: the ID of the pressed button is written in the console
Actual result: "undefined" is written in the console
this inside the function refers to Window which does not have the property id, thus you get undefined:
Pass this object to the function so that you can refer that inside the function:
var paragraph = document.getElementById('paragraph');
var cabins = [1,2,3];
for (var i = 0; i < cabins.length; i++) {
paragraph.innerHTML += "Cabin " + cabins[i] + "<br><br><button id='cabin" + cabins[i] +"' onclick='purchaseCabin(this)'>Purchase</button><br><br>"
}
function purchaseCabin(current) {
//console.log(this.constructor.name); // Window
var cabinId = current.id;
console.log(cabinId);
}
<p id="paragraph"></p>

How to get the elements class name from a dynamically created element?

I started creating some minor code within my site, and i wanted to do some dynamic creation, so some span tags are created using a javaScript for loop.
In the same code, but a different loop i want to add an Event Listener to the tags.The error i get is the element created is non existent, and i have a few ideas why it's not working, but searching the Web and Stack Overflow gave me no answers.
I've considered putting both for loops into a function and calling that function in a similar fashion jquery works with it's document ready function. But i don't think that will fix the issue
var country = ["is_AmericaN", "is_Europe",
"is_Africa","is_AmericaS","is_Asia","is_Australia"];
var spanInto = document.getElementById("spanSelect");
for(i=0; i<6; i++)
{
var spanMake = document.createElement("SPAN");
spanInto.appendChild(spanMake);
spanMake.className += "spanLanguage" + " " + country[i];
}
The code above creates the elements, the code below tries to call them
var countryClass = doucment.getElementsByClassName("spanLanguage");
for(i=0; i< document.countryClass.length; i++)
{
countryClass[i].addEventListener("click", function(){
var hrDisplay = document.getElementById("selectiveDisplay");
hrDisplay.removeAttribute("id");
hrDisplay.className = "noDisplay";
},false);
}
I expect the working code to, once clicked on any span tag, set the display of the hr tag to block or flex. I dont want to create 5-6 span tags manually, it has to be a dynamic creation.
You are missing the position of the adding class
var spanMake = document.createElement("SPAN");
spanInto.appendChild(spanMake);
spanMake.className += "spanLanguage" + " " + country[i];
Here you are assigning the class after appending it into span, that is wrong you need to assign class before.
var countryClass = doucment.getElementsByClassName("spanLanguage");
for(i=0; i< document.countryClass.length; i++)
{
doucment is document and document.countryClass should be countryClass as you already have the instance of the element
var country = ["is_AmericaN", "is_Europe",
"is_Africa", "is_AmericaS", "is_Asia", "is_Australia"
];
var spanInto = document.getElementById("spanSelect");
for (i = 0; i < 6; i++) {
var spanMake = document.createElement("SPAN");
spanMake.textContent = country[i];
spanMake.className += "spanLanguage" + " " + country[i];
spanInto.appendChild(spanMake);
}
var countryClass = document.getElementsByClassName("spanLanguage");
for (i = 0; i < countryClass.length; i++) {
countryClass[i].addEventListener("click", function() {
var hrDisplay = this;
hrDisplay.removeAttribute("id");
hrDisplay.className = "noDisplay";
}, false);
}
.noDisplay {
display: none;
}
<span id="spanSelect"></span>
<br/>
//click on any of them to replace the class
There are multiple points to be corrected:
There was a type "doucment" in your code.Use "document" instead.
Created elements didn't have any text on it, how will you call click
on element when it is not visible in DOM.
Events are attached to anchors/button not span.
Not sure what you are trying to do by attaching events.
below is the code snippet which works for you when you try to add events on dynamic created elements.Let me know if you need further help
function temp() {
var country = ["is_AmericaN", "is_Europe",
"is_Africa", "is_AmericaS", "is_Asia", "is_Australia"
];
var spanInto = document.getElementById("spanSelect");
for (i = 0; i < 6; i++) {
var spanMake = document.createElement("a");
spanMake.innerHTML = country[i];
spanInto.appendChild(spanMake);
spanMake.className += "spanLanguage" + " " + country[i];
}
}
function attachEvent() {
var countryClass = document.getElementsByClassName("spanLanguage");
for (i = 0; i < countryClass.length; i++) {
countryClass[i].addEventListener("click", function(event) {
console.log("I am called" + event.target);
//var hrDisplay = document.getElementById("selectiveDisplay");
//hrDisplay.removeAttribute("id");
//hrDisplay.className = "noDisplay";
}, false);
}
}
a {
padding: 20px;
}
<body>
<div id="spanSelect"></div>
<div id="selectiveDisplay"> </div>
<button onclick="temp()"> Call Me </button>
<button onclick="attachEvent()"> Attach Event </button>
</body>

JSON - How to give onclick element in script?

How to give onclick function for id in JavaScript? eg: my onclick function is oclick="function('#id')" and I need action to be made in div. My each buttons contain their own id's. But I couldnt figure out how to use this element to generate using JSON.
I prefer JavaScript rathar than jquery.
function myFunction(arr) {
var out = "";
var i;
for(i = 0; i<arr.length; i++) {
out += '<button onclick="function('#' + arr[i].ids + '')">' +
arr[i].blaah + '</button><br>';
}
document.getElementById("id01").innerHTML = out;
}
Do you need something like this?
var arr = ["id1", "id2", "id3", "id4"]
function onClick() {
alert("you clicked button with id: " + this.id);
}
function createButtons(arr) {
var out = document.getElementById("out");
for (var i = 0, l = arr.length; i < l; i++) {
var node = document.createElement("button");
node.id = arr[i];
node.innerHTML = "button " + arr[i];
node.addEventListener("click", onClick, false);
out.appendChild(node);
}
}
createButtons(arr);
<div id="out">
</div>
Simple solution: use this
function yourfunction(elem){
//elem contains the button
//you could do:
elem.style.display="none";
}
In your html do:
<div onclick="yourfunction(this)">Button</div>
For shure this can be created dynamically.
If you want to keep your code, dont get confused with " and ' .
" ' " for example: the second " closes the first, even if theres an opened '. And you cannot name a function function. Thats an syntax error. Do this:
"<button onclick=\'func('#elem')\' >test</button>";

Passing an argument to a event listener from dynamically created buttons

I'm dynamically creating 3 buttons. How can I pass an argument tohandlerX?
So basically I want the values in the category Array to be passed on to the handlerX eventListener.
Example:
When myBtn1 is clicked, I want the alert to be "fur_",
When myBtn3 is clicked, I want the alert to be "fas_"
var btns = '';
var category = ["fur_", "fts_", "fas_"];
for (i = 1; i < category.length; i++) {
btns += '<button type="button" class=' + category[i] + ' id= "myBtn' + i + '">.....</button>';
}
var div = document.getElementById('div');
div.innerHTML = btns;
var handlerX = function () {
alert('Clicked'); //get value from the 'category' Array
};
var buttons = div.querySelectorAll('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', handlerX, false);
}
The answers given so far are good and should solve your problem. Just thought I'd add this one because I think it's a solution more in line with what you were asking for: Make your handlerX return a function like so:
var handlerX = function (param) {
return function() {alert(param);};
};
var buttons = div.querySelectorAll('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', handlerX(category[i]), false);
}
Edit: Here's a Fiddle
If you're willing to extract it from the class attribute, then:
var handlerX = function () {
alert(this.getAttribute('class'));
};
Or you better associate it with some data- attribute. For example:
for (i = 1; i < category.length; i++) {
btns += '<button type="button" data-category="' + category[i] + '" class=' + category[i] + ' id= "myBtn' + i + '">.....</button>';
}
Then:
var handlerX = function () {
alert(this.getAttribute('data-category'));
};
See Fiddle
EDIT:
then i would reccomend adding an attibute: data-category="fur_" for example, and access that from your event handler:
this.getAttribute('data-category')
in hadlerX there is a "this" that is the element that was clicked. You can access its getAttribute("class") to get the class EDIT:this, not self
var fragment = document.createDocumentFragment(),
categories = ["fur_", "fts_", "fas_"],
btn;
function onClickBtn() {
alert(this.getAttribute("data-category"));
}
for (var i = 0; i < categories.length; i++) {
btn = document.createElement("button");
btn.id = "myBtn" + string(i);
btn.setAttribute("data-category", category[i]);
btn.addEventListener("click", onClickBtn);
fragment.appendChild(btn);
}
var div = document.getElementById('div');
div.appendChild(fragment);

Eventhandler for classnames is not working correctly

Here's what I am trying to do:
Let user create category (done)
Add that category to local storage (done)
Add that category to a list on the screen (done)
Attach an event to that category, so when a user clicks on it, it will show all the posts in that category.
I want to have 1 function (or eventlistener, whatever you want to call it) that handles all the clicks. It has to know for which category it has to sort some posts and that is the point where I am stuck.
This is my code that does step 1 and 2:
document.getElementById("newCategoryButton").onclick = function ()
{
var input = document.getElementById("newCategoryInput");
var li = document.createElement('li');
li.innerHTML = "<a href='#' id='sort" + input.value + "'>" + input.value + "</a></li>";
localStorage.setItem(input.value, input.value);
document.getElementById("categories").appendChild(li);
}
This is the code for step 3. The important stuff happens at the else
for (var i = 0, len = localStorage.length; i < len; ++i) {
if (localStorage.key(i).indexOf("formObject") > -1) {
var value = JSON.parse(localStorage.getItem(localStorage.key(i)));
addRow(value);
} else {
var li = document.createElement('li');
li.className = "category";
li.innerHTML = "<a href='#' id='sort" + localStorage.getItem(localStorage.key(i)) + "'>" + localStorage.getItem(localStorage.key(i)) + "</a></li>";
document.getElementById("categories").appendChild(li);
And this is the code for step 4:
var categories = document.getElementsByClassName("category");
for (var i = 0; i < categories.length; ++i) {
categories[i].addEventListener("Click", SortPosts(categories[i].textContent));
}
function SortPosts(value)
{
alert(value);
//Sort coding here
}
When the page loads, it automatically alerts the value of SortPosts(), without clicking on anything. What is wrong with my code? Also, am I giving all the categories click events or am I doing that wrong, as well?
on the line:
categories[i].addEventListener("Click", SortPosts(categories[i].textContent));
you are calling the function Sort posts and binding the result to the click event. try this:
categories[i].addEventListener("Click", function(i){
return function(){
SortPosts(categories[i].textContent);
}
}(i));
note the closure around the i variable to keep it in scope
Edit: it occured to me after submitting this, while the code is fairly compact, it is not particularly easy to read especially if you are not familiar wih closures, so here is a slightly more verbose, easier to read version:
categories[i].addEventListener("Click", getPostSorter(i));
function getPostSorter(i) {
return function(){
SortPosts(categories[i].textContent);
}
}
Try this, you can get the textContent after the function is called.
function MyEvents(){
var categories = document.getElementsByClassName("category");
for (var i = 0; i < categories.length; ++i) {
categories[i].addEventListener("click", SortPosts,false);
}
}
function SortPosts(){
alert(event.target.textContent);
//Sort coding here
}
window.onload=MyEvents;
<div class="category">Click for category one</div>
<div class="category">Click for category two</div>

Categories