I have created 3 dynamic buttons with class attribute and would like them listed when one is clicked. Only one is shown rather than all three.
<script>
var hyperlink;
$(function() {
var y = 2;
for(var i = 0; i <= 2; i++ ) {
drawRow( i, y );
}
});
function drawRow( x, y ) {
if(x == 0)
row = $("<tr />")
else {
var btnName = "btn" + x;
console.log("ln62 btnName: " + btnName);
hyperlink = document.createElement("button");
hyperlink.setAttribute('id', btnName);
hyperlink.setAttribute('class', 'btnCL'); // class set for button
hyperlink.innerHTML = x;
$("#DataTable").append(row);
row.append($("<td></td>").append(hyperlink));
var btnName2 = "#btn" + x;
}
}
$(document).on("click", '.btnCL', function() {
console.log("inside doc.on ln73");
//console.log("hyperlink: " + hyperlink.getAttribute("id"));
$(hyperlink).each(function( i ) {
console.log("ln76 " + i + ": " + hyperlink.getAttribute("id"));
});
});
</script>
Result:
ln62 btnName: btn1
ln62 btnName: btn2
ln62 btnName: btn3
inside doc.on ln73
ln76 0: btn3 // only one(1) listed?? s/b 3
ANY HELP WOULD BE APPRECIATED.
This is because hyperlink is a variable and not an array.This line hyperlink = document.createElement("button"); will always update hyperlink variable with last created button.
Instead of using each you can use the event object and get the target
var hyperlink;
$(function() {
var y = 2;
for (var i = 0; i <= 2; i++) {
drawRow(i, y);
}
});
function drawRow(x, y) {
if (x == 0)
row = $("<tr />")
else {
var btnName = "btn" + x;
console.log("ln62 btnName: " + btnName);
hyperlink = document.createElement("button");
hyperlink.setAttribute('id', btnName);
hyperlink.setAttribute('class', 'btnCL'); // class set for button
hyperlink.innerHTML = x;
$("#DataTable").append(row);
row.append($("<td></td>").append(hyperlink));
var btnName2 = "#btn" + x;
}
}
$(document).on("click", '.btnCL', function(e) {
console.log("inside doc.on ln73");
console.log(e.target.getAttribute("id"));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="DataTable"></table>
The main problem is every iteration of the loop you reassign a new value to the variable hyperlink
All you really need to do is loop over the class collection and you don't need the global variable at all
$(document).on("click", '.btnCL', function() {
// current button is `this`
console.log('Current id:', this.id);
// loop over the class instead to see them all
$('.btnCL').each(function( i, el ) {
console.log("ln76 " + i + ": " + el.id); // or this.id
});
});
Related
I get the message list from the API and create a dynamic array using javascript. I would like a new page with message details to be started when a specific row is pressed.
How do I implement a call to showMessage () on a specific table row?
var list = document.getElementById("listOfMessage");
init();
function init() {
for (var i = 0; i < messageList.length; i++) {
var message = messageList[i];
var li = document.createElement("li");
var a = document.createElement("a");
var text = document.createTextNode("Nadawca: " + message.fullName);
a.appendChild(text);
a.setAttribute('onclick', showMessage(message));
list.appendChild(li);
//list.innerHTML += "<li><a href="showMessage(message)"><h2>Nadawca: " + message.fullName + "
//</h2></a></li>";
}
//list = document.getElementById("listOfTask");
}
function showMessage(message) {
window.sessionStorage.setItem("message", JSON.stringify(message));
window.location.href = 'message.html';
}
In the code above, the showMessage () function is immediately called when the array is initialized. How to make it run only after clicking on a row?
I could add an id attribute to the (a) or (li) element in the init () function, but how to find it later and use it in this code:
var a = document.getElementById('1');
a.addEventListener('click', function() {
window.sessionStorage.setItem("message", JSON.stringify(messageList[0]));
window.location.href = 'message.html';
});
I found a way to solve this problem.
Using this code fragment, we can call a function for a specific element in a dynamically created list.
function init() {
for (var i = 0; i < messageList.length; i++) {
var message = messageList[i];
list.innerHTML += "<li id="+i+"><a onClick="+
"><h2>Nadawca: " + message.fullName + "</h2></a></li>";
}
//$(document).on("click", "ui-content", function(){ alert("hi"); });
$(document).ready(function() {
$(document).on('click', 'ul>li', function() {
var idName = $(this).attr('id');
showMessage(messageList[idName]);
});
});
}
I currently have a JavaScript that is looking at a SharePoint list, and pulling back all of the items that meet the criteria in the REST call.
It currently creates DIVs and appends them to a wrapper DIV. The intention of the button is to show/hide the sub-DIVs.
Right now, when I click any of the buttons that are produced, it expands all of the hidden divs. What I'm trying to accomplish is to be able to click each respective button and have its nested div show/hide.
Here is my code:
var listName = "announcement";
var titleField = "Title";
var tipField = "Quote";
var dateFieldFrom = "DateFrom";
var dateFieldTo = "DateTo";
var category = "category";
var noteField = "note";
var query = "/_api/Web/Lists/GetByTitle('" + listName + "')/items?$select=" + titleField + "," + dateFieldTo + "," + dateFieldFrom + "," + category + "," + noteField + "," + tipField;
var today = new Date();
var btnClass = "toggle"
todayString = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate();
//This is the query filter string where we compare the values in the 2 date fields against the current date
query += "&$filter=('" + todayString + "' ge " + dateFieldFrom + " ) and (" + dateFieldTo + " ge '" + todayString + "')";;
var call = $.ajax({
url: _spPageContextInfo.webAbsoluteUrl + query,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function(data, textStatus, jqXHR) {
var divCount = data.d.results.length;
for (var i = 0; i < divCount; i++) {
var tip = data.d.results[i][tipField]; //this is where it looks at the quote field to determine what quote to place in the current dynamically created DIV
var cat = data.d.results[i][category]; //this is where it looks at the category field to determine what color to style the background of the current dynamically created DIV
var message = data.d.results[i][noteField];
var ID = "NewDiv-" + i
var PID = "P-" + i
var BID = "btn-" + i
// Create Message DIV
var element = document.createElement("div"); //This is the creation of the dynamic DIV
element.id = ID //This is assigning a DIV an ID
element.appendChild(document.createTextNode(tip));
// Create Inner message DIV
var innerDiv = document.createElement("div"); // Create a <div> element//New Code
innerDiv.id = PID
innerDiv.appendChild(document.createTextNode(message));
// Create button to show/hide the div
var btn = document.createElement("BUTTON");
btn.id = BID
btn.appendChild(document.createTextNode("show/hide message below"));
btn.className = btnClass
// Append Inner DIVs
document.getElementById('wrapper').appendChild(element); //This is the parent DIV element that all newly created DIVs get created into
document.getElementById(ID).appendChild(btn); // Append the button to the newly created DIV
document.getElementById(ID).appendChild(innerDiv); //This is the message that appears after the newly created DIVs
if (cat == 'Information') {
document.getElementById(ID).style.backgroundColor = '#d9edf7'; //Blue Color
document.getElementById(PID).style.backgroundColor = '#d9edf7'; //Blue Color
document.getElementById(PID).style.margin = '3px';
document.getElementById(BID).style.backgroundColor = '#d9edf7';
document.getElementById(BID).style.border = 'none';
innerDiv.className = "alert alert-info"
element.className = "alert alert-info"
}
if (cat == 'Warning') {
document.getElementById(ID).style.backgroundColor = '#fcf8e3'; //Orange Color
document.getElementById(PID).style.backgroundColor = '#fcf8e3'; //Orange Color
document.getElementById(PID).style.margin = '3px';
document.getElementById(BID).style.backgroundColor = '#fcf8e3';
document.getElementById(BID).style.border = 'none';
innerDiv.className = "alert alert-warning"
element.className = "alert alert-warning"
}
if (cat == 'Critical') {
document.getElementById(ID).style.backgroundColor = '#f2dede'; //Red Color
document.getElementById(PID).style.backgroundColor = '#f2dede'; //Red Color
document.getElementById(PID).style.margin = '3px';
document.getElementById(BID).style.backgroundColor = '#f2dede';
document.getElementById(BID).style.border = 'none';
innerDiv.className = "alert alert-danger"
element.className = "alert alert-danger"
}
}
// The below variables and for loop ensure that all sub messages are initially hidden, until the show/hide button is clicked
var curDiv
var curID
for (var i = 0; i < divCount; i++) {
curID = "P-" + i
curDiv = document.getElementById(curID)
curDiv.style.display = 'none';
}
// The function below is to assign an event to the button to show/hide the sub message
var f = function(a) {
var cDiv
for (var z = 0; z < divCount; z++) {
cDiv = "P-" + z
var div = document.getElementById(cDiv);
if (div.style.display !== 'none') {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
}
return false;
}
var elems = document.getElementsByClassName("toggle");
var idx
for (var i = 0, len = elems.length; i < len; i++) {
elems[i].onclick = f;
}
});
<div id="wrapper" class="header"> </div>
You're assigning all of your buttons the same onclick function event handler, and that function loops through all the divs and shows them or hides them.
An alternative approach would be to have the event handler toggle only the specific div that's associated with the button.
When you first create the button, you can assign an event handler to it immediately and pass in a reference to the div you want to hide:
var innerDiv = document.createElement("div");
innerDiv.id = PID
innerDiv.appendChild(document.createTextNode(message));
var btn = document.createElement("BUTTON");
// Immediately-invoked function expression to attach event handler to inner div:
(function(d){
btn.onclick = function(){ f(d); };
})(innerDiv);
Then just update your f function to accept as a parameter the div you want to toggle.
// The function below is to assign an event to the button to show/hide the sub message
function f(div){
if (div.style.display !== 'none') {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
return false;
}
You can then remove the last few lines of code where you're assigning the buttons to the elems collection and looping through it to attach an onclick function.
You can replace all of this - which loops over all divs
// The function below is to assign an event to the button to show/hide the sub message
var f = function(a) {
var cDiv
for (var z = 0; z < divCount; z++) {
cDiv = "P-" + z
var div = document.getElementById(cDiv);
if (div.style.display !== 'none') {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
}
return false;
}
var elems = document.getElementsByClassName("toggle");
var idx
for (var i = 0, len = elems.length; i < len; i++) {
elems[i].onclick = f;
}
with this, it delegates the click on the button in the wrapper and toggles the next object after the button
$('#wrapper').on("click",".toggle",function(e) { // notice the delegation
e.preventDefault(); // in case you forget type="button"
$(this).next().toggle();
});
Like this:
$(function() {
$('#wrapper').on("click", ".toggle", function(e) {
e.preventDefault();
$(this).next().toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="wrapper">
<div id="NewDiv-0" class="alert alert-info" style="background-color: rgb(217, 237, 247);">Debbie Teng joins PD Tax!********
<button id="btn-0" class="toggle" style="background-color: rgb(217, 237, 247); border: none;">show/hide message below</button>
<div id="P-0" class="alert alert-info" style="background-color: rgb(217, 237, 247); margin: 3px; display: none;">yadayada1</div>
</div>
</div>
I am working on a simple drag and drop operation in JS. I have to generate the containers, since I do not know in advance how many I will need, and that seems to be leading to a couple of problems.
The first is that if I drag an item over the last div, the div disappears. I have no idea what is causing it, but it is odd.
The second is that in the drop section
box.addEventListener('drop', function(e) {
e.preventDefault();
var data = e.dataTransfer.getData('id');
e.target.appendChild(document.getElementById(data));
});
I am getting the error message: "Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'," and the 'data' is not being passed. I only get this message on JSFiddle: in both Firefox and Chrome it works fine, but I suspect that it is part of a larger issue.
I am very new at this, so any help would be appreciated.
JSFiddle here.
I think this will work for you.
I've made some changes to your javascript.
Please have a look here:
var productList = [];
for (var w = 0; w < 2; w++) {
productList.push('Apples', 'Plums', 'Rice', 'Potatoes', 'Chicken', 'Pork');
}
productList.sort();
console.log(productList.length);
var boxContainer = document.createDocumentFragment();
for (var i = 0; i < 3; i++) {
var box = boxContainer.appendChild(document.createElement("div"));
var boxID = "box" + i;
box.setAttribute('id', boxID);
box.setAttribute('class', 'dropTarget');
box.addEventListener('dragend', function(e) {
elementDragged = null;
});
box.addEventListener('dragover', function(e) {
if (e.preventDefault) {
e.preventDefault();
};
//This close was right below your Remove Class. Preventing the over class from being added
});
box.addEventListener('dragenter', function(e) {
if(this.className.indexOf('over') < 0)
//Append the className, don't remove it.
this.className += " over";
});
box.addEventListener('dragleave', function(e) {
//Now we remove it.
this.className = this.className.replace(' over','');
e.dataTransfer.dropEffect = 'move'
return false;
});
box.addEventListener('drop', function(e) {
e.preventDefault();
var data = e.dataTransfer.getData('id');
//Just preventing the HierarchyRequestError.
var parent= e.dataTransfer.getData('parent');
if(parent == e.target.id) return;
target=e.target;
//Prevent it from dragging into another div box and force it to go into the box.
if(e.target.id.indexOf('box') < 0 ) target=e.target.parentNode;
target.appendChild(document.getElementById(data));
});
document.drag = function(target, e) {
e.dataTransfer.setData("Text", 'id');
//This is the drag function that's being called. It needed the reference to the ID.
e.dataTransfer.setData('id', target.id);
//Add parentID, so we can check it later.
e.dataTransfer.setData('parent',target.parentNode.id)
}
document.getElementById("placeholder").appendChild(box);
};
for (var a = 0; a < productList.length; a++){
renderProductList(productList[a], a);
};
function renderProductList(element, index) {
console.log(element);
var nameDiv = document.createElement('div');
var itemName = element;
nameDiv.setAttribute('class','dragger');
nameDiv.setAttribute('id', itemName + index);
nameDiv.setAttribute('name', itemName);
nameDiv.setAttribute('draggable', "true");
nameDiv.setAttribute('ondragstart', 'drag(this, event)');
nameDiv.style.backgroundColor = pastelColors();
var aBox = document.getElementById('box0');
aBox.appendChild(nameDiv);
var t = document.createTextNode(element);
console.log("T: " + t);
nameDiv.innerHTML = nameDiv.innerHTML + element;
};
function pastelColors(){
var r = (Math.round(Math.random()* 127) + 127).toString(16);
var g = (Math.round(Math.random()* 127) + 127).toString(16);
var b = (Math.round(Math.random()* 127) + 127).toString(16);
pColor = '#' + r + g + b;
console.log(pColor);
return pColor;
};
function drag(target, e) {
e.dataTransfer.setData('id', target.id);
};
https://jsfiddle.net/3yLk11eb/5/
I've made comments everywhere I made changes. And there were a lot of changes to make this work smoothly.
Right now I'm doing some clean up code for my auction game, but my function is fired immediately after endAuction() is called rather than when the button is clicked. I can't seem to figure out why, and I'm not terribly familiar with JavaScript or jQuery, can anyone point out my issue?
endAuction:function()
{
var i = 0;
var btnID = "as" + (i).toString(),
liID = "asli" + (i).toString();
var cleanBtn = $('li#' + liID + ' button#' + btnID);
cleanBtn.text("Sold!");
var btn = $('#' + btnID);
btn.off().click(this.cleanUpAuction());
},
cleanUpAuction:function()
{
console.log("Removing button");
userStats.money += currentBid;
currentBid = 0;
var i = 0;
var liID = "asli" + (i).toString();
var carElement = $('li#' + liID);
carElement.remove();
},
You are calling the function, not assigning a reference to it.
Change
.click(this.cleanUpAuction())
to
.click(this.cleanUpAuction)
or
.click($.proxy(this.cleanUpAuction, this))
I am adding a row to a table, and attached an ondblclick event to the cells. The function addrow is working fine, and the dblclick is taking me to seltogg, with the correct parameters. However, the var selbutton = document.getElementById in seltogg is returning a null. When I call seltogg with a dblclick on the original table in the document, it runs fine. All the parameters "selna" have alphabetic values, with no spaces, special characters, etc. Can someone tell me why seltogg is unable to correctly perform the document.getElementById when I pass the id from addrow; also how to fix the problem.
function addrow(jtop, sel4list, ron4list) {
var tablex = document.getElementById('thetable');
var initcount = document.getElementById('numrows').value;
var sel4arr = sel4list.split(",");
var idcount = parseInt(initcount) + 1;
var rowx = tablex.insertRow(1);
var jtop1 = jtop - 1;
for (j = 0; j <= jtop1; j++) {
var cellx = rowx.insertCell(j);
cellx.style.border = "1px solid blue";
var inputx = document.createElement("input");
inputx.type = "text";
inputx.ondblclick = (function() {
var curj = j;
var selna = sel4arr[curj + 2];
var cellj = parseInt(curj) + 3;
inputx.id = "cell_" + idcount + "_" + cellj;
var b = "cell_" + idcount + "_" + cellj;
return function() {
seltogg(selna, b);
}
})();
cellx.appendChild(inputx);
} //end j loop
var rowCount = tablex.rows.length;
document.getElementById('numrows').value = rowCount - 1; //dont count header
} //end function addrow
function seltogg(selna, cellid) {
if (selna == "none") {
return;
}
document.getElementById('x').value = cellid; //setting up for the next function
var selbutton = document.getElementById(selna); //*****this is returning null
if (selbutton.style.display != 'none') { //if it's on
selbutton.style.display = 'none';
} //turn it off
else { //if it's off
selbutton.style.display = '';
} //turn it on
} //end of function seltogg
You try, writing this sentence:
document.getElementById("numrows").value on document.getElementById('numrows').value
This is my part the my code:
contapara=(parseInt(contapara)+1);
document.getElementById("sorpara").innerHTML+="<li id=\"inputp"+contapara+"_id\" class=\"ui-state-default\"><span class=\"ui-icon ui-icon-arrowthick-2-n-s\"></span>"+$('#inputp'+contapara+'_id').val()+"</li>";
Look you have to use this " y not '.
TRY!!!!