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>
Related
I have a website that triggers an alert when items are added to the cart. I'm using javascript ES6, html5.
I'm dynamically creating bootstrap styled cards with menu items on the page and a add to cart button. when the add to cart button is pressed an alert is triggered.
The alert attempts to trigger on iOS 13.x.x safari but doesn't show. I attempted to set a timeout, but that didn't work. It has to be the way it's being called. I really don't know what to try next. I read that user navigation (back, forward) can break alerts. In the 'addEventListener' of the 'btn' towards the bottom of this horrific method is where the problem arises. Why is this not working on safari mobile?
createMenuCard(menu){
var heading = document.getElementById("concession-name");
heading.innerText = menu.menus.menu.concessionName;
var card = null;
var body = null;
var lsgroup = null;
for(var i = 0; i < menu.menus.menu.categories.length; i++){
for(var j = 0; j < menu.menus.menu.categories[i].menuItems.length; j++){
this.card = document.createElement('div');
this.card.className = 'card';
this.card.setAttribute('id', this.uuidv4());
this.card.setAttribute('style', 'width: 20rem;');
this.body = document.createElement('div');
this.body.className = 'card-body';
var title = document.createElement('div');
title.className = 'card-title';
title.innerText = menu.menus.menu.categories[i].menuItems[j].name;
this.body.appendChild(title);
this.lsgroup = document.createElement('div');
this.lsgroup.className = "list-group";
this.body.appendChild(this.lsgroup);
for(var k = 0; k < menu.menus.menu.categories[i].menuItems[j].subItems.length; k++){
if(menu.menus.menu.categories[i].menuItems[j].subItems[k].name === "")
{
var id = this.uuidv4();
var input = document.createElement("input");
input.setAttribute("type", "checkbox");
input.setAttribute("name", "");
input.setAttribute("id", id);
input.setAttribute("value", menu.menus.menu.categories[i].menuItems[j].name);
input.setAttribute("price", menu.menus.menu.categories[i].menuItems[j].subItems[k].price);
this.lsgroup.appendChild(input);
// label
var label = document.createElement("label");
label.className = "list-group-item";
label.setAttribute("for", id);
label.innerText = menu.menus.menu.categories[i].menuItems[j].subItems[k].price + " " + menu.menus.menu.categories[i].menuItems[j].name;
this.lsgroup.appendChild(label);
}
else
{
var id = this.uuidv4();
// input
var input = document.createElement("input");
input.setAttribute("type", "checkbox");
input.setAttribute("name", "");
input.setAttribute("id", id);
input.setAttribute("value", menu.menus.menu.categories[i].menuItems[j].subItems[k].name);
input.setAttribute("price", menu.menus.menu.categories[i].menuItems[j].subItems[k].price);
this.lsgroup.appendChild(input);
// label
var label = document.createElement("label");
label.className = "list-group-item";
label.setAttribute("for", id);
label.innerText = menu.menus.menu.categories[i].menuItems[j].subItems[k].price + " " +menu.menus.menu.categories[i].menuItems[j].subItems[k].name;
this.lsgroup.appendChild(label);
}
}
var btn = document.createElement('a');
btn.setAttribute("href", "#"); // javascript:toCart()
btn.addEventListener("click", (e)=> {
var inputs = e.path[2].querySelector("div > div.list-group").getElementsByTagName("input");
var description = e.path[2].querySelector("div > div.card-title").innerText;
for(var l = 0; l < inputs.length; l++){
if(inputs[l].checked === true){
var obj = {
option : inputs[l].value,
price : inputs[l].getAttribute("price")
};
setTimeout(function(){
window.alert("Added: " + description + " to cart");
}, 300);
//window.alert("Added: " + description + " to cart");
description += " " + obj.option;
var appItem = new AppItems(description, obj.price, 1);
cart.addItem(appItem);
}
}
});
btn.className = "btn btn-primary";
btn.innerText = "Add To Cart";
this.body.appendChild(btn);
this.card.appendChild(this.body);
var container = document.getElementById('cards');
container.appendChild(this.card);
}
}
var chk = document.getElementById("checkout");
chk.addEventListener("click", (e)=> {
cart.save();
window.open("./cart.html","_self");
});
}
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
});
});
I had to create a button inside a lookup field i have followed this page
http://bharathknight.blogspot.com/2015/03/create-button-inside-form-using.html i have added a event onchange the lookup value but the first alert is hitted but the second none and no button is displayed pleaase help me i'm stucked here
function createButton() {
alert("createButton");
var atrname = "xxxx";
if (document.getElementById(atrname ) != null) {
var fieldId = "field" + atrname ;
var elementId = document.getElementById(atrname + "_d");
var div = document.createElement("div");
div.style.width = "20%";
div.style.textAlign = "right";
div.style.display = "inline";
childDiv = elementId.getElementsByTagName('div')[0]
childDiv.style.display = "none";
elementId.appendChild(div, elementId );
div.innerHTML = '<button id="' + fieldId + '" type="button" style="margin-left: 4px; width: 50%;" >CRM Save Button</button>';
document.getElementById(atrname).style.width = "80%";
document.getElementById(fieldId ).onclick = function () { OnClickFunction(); };
}
}
function OnClickFunction() {
alert("clicked!");
}
With the introduction of turbo forms, things have changed a bit. If you want to access DOM, use document's parent element.
function createButton() {
var atrname = 'foobar';
if (window.parent.document.getElementById(atrname) != null) {
var fieldId = 'field' + atrname;
var elementId = window.parent.document.getElementById(atrname + '_d');
var div = window.parent.document.createElement('div');
div.style.width = '20%';
div.style.textAlign = 'right';
div.style.display = 'inline';
var childDiv = elementId.getElementsByTagName('div')[0];
childDiv.style.display = 'none';
elementId.appendChild(div, elementId);
div.innerHTML = '<button id="' + fieldId + '" type="button" style="margin-left: 4px; width: 50%;" >CRM Save Button</button>';
window.parent.document.getElementById(atrname).style.width = '80%';
window.parent.document.getElementById(fieldId).onclick = function () { OnClickFunction(); };
}
}
Here id my code. I want to append 4 buttons inside the specific div. In the other words, I want to put these 4 buttons inside ''. Now it works but they are not inside the div.
getmyItems function is a function that contains an array of information like: title, description , age ,... .
Help
getmyItems(param, function(data) {
var mtItem = JSON.stringify(data);
myItem = JSON.parse(mtItem);
var Item = document.getElementById('myItems');
for (var i = 0; i < myItem.results.length; i++) {
var buffer = "";
buffer += '<div class="act-time">';
buffer += '<div class="activity-body act-in">';
buffer += '<span class="arrow"></span>';
buffer += '<div class="text">';
buffer += '<p class="attribution">';
buffer += ''+myItem.results[i].title+'';
buffer += myItem.results[i].description;
buffer += '</p>';
buffer += '</div>';
buffer += '</div>';
buffer += '</div>';
var div = document.createElement('div');
div.innerHTML = buffer;
//var elem = div.firstChild;
Item.appendChild(div);
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'btn btn-danger');
btn.value = "Delete";
btn.onclick = (function(i) {
return function() {
var c=confirm('Are you Sure? ');
if (c==true)
doDelete(myItem.results[i].item_id);
};
})(i);
Item.appendChild(btn);
var show_btn=document.createElement('input');
show_btn.setAttribute('type','button');
show_btn.setAttribute('class','btn btn-primary');
show_btn.value="ShowInDetail";
show_btn.onclick=(function(i){
return function(){
showInDetail(myItem.results[i]);
window.location='showInDetail.html';
};
})(i);
Item.appendChild(show_btn);
var extend_btn=document.createElement('input');
extend_btn.setAttribute('class','btn btn-warning');
extend_btn.setAttribute('type','button');
extend_btn.value="Extend";
extend_btn.onclick=(function(i){
return function(){
extendItem(myItem.results[i]);
window.location='extendItem.html';
};
})(i);
Item.appendChild(extend_btn);
var bookmark=document.createElement('input');
bookmark.setAttribute('type','button');
bookmark.setAttribute('class','btn btn-primary');
bookmark.value='Bookmark';
bookmark.onclick=(function(i){
return function(){
var p={user_id:localStorage.getItem('user_id')};
window.localStorage.setItem('this_item_id', myItem.results[i].item_id);
getBookmarks(p, function(d){
var bk=JSON.stringify(d);
bk=JSON.parse(bk);
if(bk.results){
var l=0;
for(var j in bk.results){
if(bk.results[j].item_id==localStorage.getItem('this_item_id')){
removeBookmark(bk.results[j]);
l=1;
}
}if(l==0){
addBookmark(myItem.results[i]);
}
}else{
addBookmark(myItem.results[i]);
}
});
};
})(i);
Item.appendChild(bookmark);
//document.getElementById(i).appendChild(btn);
}
});
In what specific div do you want them? So far, in this way the four buttons are inside the myItens div see in the fiddle and in the code below.
var getmyItems = function(data) {
var item = document.getElementById('myItems');
for (var i = 0; i < data.length; i++) {
var result = data[i];
// creation of the buffer outer div
var buffer = document.createElement('div');
buffer.className = 'act-time';
//creation of de activity-body
var activity = document.createElement('div');
activity.className = 'activity-body act-in';
//creation of the first span
var arrow = document.createElement('span');
arrow.className = 'arrow';
//creation of the most inner div
var textDiv = document.createElement('div');
textDiv.className = 'text';
//creation of the content of the most inner div
var attribution = '';
attribution += '<p class="attribution">';
attribution += '' + result.title + '';
attribution += result.description;
attribution += '</p>';
//initialize the text div
textDiv.innerHTML = attribution;
//put the arrow span inside the activity div
activity.appendChild(arrow);
// put the text div inside the activity div
activity.appendChild(textDiv);
//put the activity inside the buffer div
// each time appendChild is applied the element is attach tho the end of the target element
buffer.appendChild(activity);
var div = document.createElement('div');
div.appendChild(buffer);
item.appendChild(div);
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'btn btn-danger');
btn.value = "Delete";
btn.onclick = (function(i) {
return function() {
var c = confirm('Are you Sure? ');
if (c === true) {
//do something;
};
};
})(i);
// now that all div are created you can choose which div you want to put the button inside.
// in this I chose the buffer.
buffer.appendChild(btn);
var showBtn = document.createElement('input');
showBtn.setAttribute('type', 'button');
showBtn.setAttribute('class', 'btn btn-primary');
showBtn.value = "ShowInDetail";
showBtn.onclick = (function(i) {
return function() {
window.location = 'showInDetail.html';
//do something
};
})(i);
// button is append to the end of the buffer
buffer.appendChild(showBtn);
var extendBtn = document.createElement('input');
extendBtn.setAttribute('class', 'btn btn-warning');
extendBtn.setAttribute('type', 'button');
extendBtn.value = "Extend";
extendBtn.onclick = (function(i) {
return function() {
window.location = 'extendItem.html';
//do something
};
})(i);
// button is append to the end of the buffer
buffer.appendChild(extendBtn);
var bookmark = document.createElement('input');
bookmark.setAttribute('type', 'button');
bookmark.setAttribute('class', 'btn btn-primary');
bookmark.value = 'Bookmark';
bookmark.onclick = (function(i) {
return function() {
var p = { user_id: localStorage.getItem('user_id') };
window.localStorage.setItem('this_item_id', myItem.results[i].item_id);
//do something
};
})(i);
// button is append to the end of the buffer
buffer.appendChild(bookmark);
}
};
var myItem = [{ title: 'person', description: 'familyName' }, { title: 'ohterPerson', description: 'otherFamilyName' }];
getmyItems(myItem);
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!!!!