Updating then displaying a variable during jQuery .submit function - javascript

On page load I am setting:
var qty = 1;
Then, within the page, the user chooses a product & selects a quantity which is captured as the variable clicks.
I wish to then click a button#addToInventory which will update the qty variable & display it in the console. I am attempting this as follows:
$("#addToInventory").submit(function(event){qty = clicks;console.log(" QTY: " + qty );})
This does not work (the console displaying a qty of 1 regardless of the set value, however immediately after clicking the button, if I then manually type console.log(" QTY: " + qty ) I see the correct qty as set in the console.
I have tried to delay the console.log as follows, but this does not work either:
$("#addToInventory").submit(function(event){qty = clicks;setTimeout(function (){console.log( " QTY: " + qty );}, 1000);})
--EDIT--
The above is a simplified sample of the production code which is as follows:
$.ajax(settings).done(function(response) {
var output = "";
for (i in response.Products) {
var productID = response.Products[i].ProductId;
var name = response.Products[i].Name;
var imagePath = response.Products[i].ImagePath;
var EAN = response.Products[i].EANBarcode;
var price = response.Products[i].PriceDescription;
var offer = response.Products[i].OfferPromotion;
var offerValid = response.Products[i].OfferValidity;
var qty = 0;
output += "<div class='uk-width-medium-1-4'> <div class='md-card'> <div class='md-card-head uk-text-center uk-position-relative'> <div class='uk-badge uk-badge-danger uk-position-absolute uk-position-top-left uk-margin-left uk-margin-top'>" + price + "</div><img class='md-card-head-img' src='" + imagePath + "'/> </div><div class='md-card-content'> <h4 class='heading_c uk-margin-bottom'>" + name + "<span class='sub-heading'>SKU: " + EAN + "</span></h4> <p>" + offer + "</p><p><i>" + offerValid + "</i></p><div align='center'><button data-uk-modal=\"{target:'#modal_" + productID + "'}\" class=\"md-btn md-btn-flat md-btn-flat-primary\" >ADD TO INVENTORY</button><div class=\"uk-modal\" id=\"modal_" + productID + "\"> <div class=\"uk-modal-dialog\"> <div class='uk-modal-header'> <h3 class='uk-modal-title md-card-toolbar-heading-text'><i class='md-icon material-icons'></i> QTY To Add</h3> </div><p class='uk-text-left'>How many <i><b>" + name + "</b></i> do you want to add to your home inventory : <br></p><div class='uk-text-center'> <form id='addToInventory_" + productID + "'> </p><br><h2> <table class='uk-table uk-table-popup uk-table-hover-popup'> <tbody> <td class='uk-text-center' type='button' onClick='clicks_" + productID + "--;updateClickCount_" + productID + "();' id='push-'><i class='md-icon material-icons'></i></td><td class='uk-text-center' id='clickCount_" + productID + "'>1</td><td class='uk-text-center' type='button' onClick='clicks_" + productID + "++;updateClickCount_" + productID + "();' id='push+'><i class='md-icon material-icons'></i></td></tbody> </table> </h2> <br></p><button id='addToInventory_" + productID + "-submit' type='submit' class='md-btn md-btn-flat md-btn-flat-primary'>ADD TO INVENTORY</button></form><scr" + "ipt type=\"application/javascript\">var clicks_" + productID + " = 1;var minimum = 1;function updateClickCount_" + productID + "() {if (clicks >= minimum) {document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";} else {clicks_" + productID + " = 1;document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";}} $(\"#addToInventory_" + productID + "\").submit(function(event){qty = 0;console.log('QTY IS: '+qty+' CLICKS Are: '+clicks_"+productID+");qty = clicks_"+productID+";setTimeout(function (){console.log(\""+ name + " QTY: " + qty +"\");}, 1000);}) </scr" + "ipt></div></div></div></div></div></div></div>";
}
$("#allResults").html(output);
$("#searchTerm").html(searchTerm);
});
});

Your qty will always be one because you are creating the variable and assigning it to be 0 inside of the for loop. Every time it runs the for loop a new qty var is created an set to 0 then it is given the 1 value for the iteration variable (i). So the fact that qty is being instantiated in the loop it will never increase.
If you move the qty variable out of the for loop it should work.
var qty = 0;
For (.............) {
// your code here
}

Related

onclick not working for two or more links for same function in javascript

I have displayed records from MySQL database. After displaying records added javascript onclick function. It works only for the first record and not works for other records.
In the above image, I clicked the first link which works fine. But if I click second click nothing happens.
<script>
function Confirm(title, msg, $true, $false, $link) {
/*change*/
var $content =
"<div class='dialog-ovelay'>" +
"<div class='dialog'><header>" +
" <h3> " +
title +
" </h3> " +
"<i class='fa fa-close'></i>" +
"</header>" +
"<div class='dialog-msg'>" +
" <p> " +
msg +
" </p> " +
"</div>" +
"<footer>" +
"<div class='controls' style='text-align:right'>" +
" <button class='button button-danger doAction'>" +
$true +
"</button> " +
" <button class='button button-default cancelAction'>" +
$false +
"</button> " +
"</div>" +
"</footer>" +
"</div>" +
"</div>";
$("body").prepend($content);
$(".doAction").click(function() {
$(this)
.parents(".dialog-ovelay")
.fadeOut(500, function() {
var subtotal = document.getElementById("subtotal").innerHTML;
var price = "<?php echo $price ;?>";
var subtotal = +subtotal + +price;
var totalitems = document.getElementById("totalitems").innerHTML;
var totalitems = +totalitems + +1;
document.getElementById("totalitems").innerHTML = totalitems;
document.getElementById("subtotal").innerHTML = subtotal.toFixed(2);
var total = +subtotal + +8 + +4;
document.getElementById("total").innerHTML = total.toFixed(2);
$(this).remove();
});
});
$(".cancelAction, .fa-close").click(function() {
$(this)
.parents(".dialog-ovelay")
.fadeOut(500, function() {
$(this).remove();
});
});
}
$("#linkdup").click(function() {
Confirm(
"Are you sure you want to Duplicate Frame",
"One more frame will be added to Cart",
"Yes",
"No"
); /*change*/
});
</script>
You are working with IDs here. An ID is unique, if you query it, you will get one result (the first).
Example:
// This selects one
const result = document.getElementById('myId').innerHTML;
console.log(result);
// This selects all
const elements = document.querySelectorAll('[id=myId]');
elements.forEach(function(element) {
console.log(element.innerHTML);
// add click event to element here
});
<div id="myId">Test 1</div>
<div id="myId">Test 2</div>
Use classes for this. Using an ID multiple times is invalid, even though you can make it work as shown in example.

Creating Html table from array (Using prompt)

I am new to Html. This is my first html javascript program and I have an issue with it.
A user puts his/her gpa CS102 A 3, Math101 B 3. Then, I put the data into an Array. The problem is when I create the table. I want to create a table like
THL100 B+ 3
PHL107 A 3
ENG120 C+ 3
MTH245 A 4
CSC221 A 3
What kind of loop I should use? I tried to use a for loop but it just doesn't work.
Here is my code:
function load(){
var data = [];
while(true) {
line = prompt("Enter course name, grade, and credit hours or click OK with no data to terminate");
if(line == null || line == "") {
break;
}
var values = line.split(/\s/);
var citem = values[0];
data.push(citem);
var gpa = parseFloat(values[1]);
var cgpa = [gpa];
data.push(cgpa);
var unit = values[2];
var cunit = [unit];
data.push(cunit);
}
return data;
}
function display(data) {
var table=document.getElementById('result');
table.innerHTML= "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th></tr>";
for(var i in data){
table.innerHTML +="<tr><td>" + data[i] + "</td><td>" + data[i]+1 + "</td><td>" + data[i]+2 + "</td></tr>";
}
}
data = load();
display(data);
<table id="result" border="1px" class="classy">
</table>
<span id="text"></span>
the problem is with accessing data not the loop, store each line as one element in the array, like object will be easy:
function load(){
var data = [];
while(true) {
line = prompt("Enter course name, grade, and credit hours or click OK with no data to terminate");
if(line == null || line == "") {
break;
}
var values = line.split(/\s/);
var line = {
COURSE: values[0],
GRADE: parseFloat(values[1]),
HOURS: values[2]
};
data.push(line); // now your array is [{COURSE: value, GRADE: value, HOURS: value}, {}, ...]
}
return data;
}
function display(data) {
var table=document.getElementById('result');
table.innerHTML= "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th> </tr>";
for(var i in data){
table.innerHTML +="<tr><td>" + data[i]["COURSE"] + "</td><td>" + data[i]["GRADE"] + "</td> <td>" + data[i]["HOURS"] + "</td></tr>";
}
}
UPDATE: yes the data is accessible inside the loop but for any variable
function display(data) {
var table = document.getElementById('result');
table.innerHTML = "<tr><th> COURSE </th><th> GRADE </th><th> HOURS </th> </tr>";
let totalgp = 0; // if the total is for all courses define it here
for (var i in data) {
let totalgp = 0; // if total grade for each course separately define it inside the loop
if (data[i]["GRADE"] == "A") {
var gp = 4 * data[i]["HOURS"];
totalgp = totalgp + gp;
}
table.innerHTML += "<tr><td>" + data[i]["COURSE"] + "</td><td>" + data[i]["GRADE"] + "</td> <td>" + data[i]["HOURS"] + "</td></tr>";
}
}
The data should be stored in a 2-dimensional array to easily access the elements. The usage of for loop is right.
To append the first row -
table.innerHTML +="<tr><td>" + data[0][0] + "</td><td>" + data[0][1] + "</td> <td>" + data[0][2] + "</td></tr>";
similarly for 2nd row,
table.innerHTML +="<tr><td>" + data[1][0] + "</td><td>" + data[1][1] + "</td> <td>" + data[1][2] + "</td></tr>";

Append and Remove Multiple Data Attributes to URL with JQuery

Having a tuff time figuring this out. I am building a front-end WooCommerce cart component that will add multiple products to the cart by passing the product ID into the URL. The URL structure will ultimately look like this http://cleancolor.staging.wpengine.com/?add-to-cart=2998,3339,2934 where the 2998,3339,2934 are the WooCommerce Product ID's.
Here is a live working version (without the append) http://studiorooster.com/dojo/cleancolor/ - just click on a "5 Pack" or "10 Pack" and select an addon. I have the product id's appended to the Addon name to the right side list and have the attribute named data-itemid
Here is my html block
<div class="col-md-3 clearfix" id="order_summary_box">
<div class="summary-box">
<div class="heading-total">Order Summary : <span class="color-txt" id="order_total"><span>$</span>0</span>
</div>
<div class="summary-basic-pack">
<h5>Whats in Your Bundle</h5>
<ul class="entree-add" id="entree-add">
<li id="no-entrees">No Entrees Added</li>
</ul>
<ul class="pack-add" id="pack-add">
<li id="no-addons">No Addons Selected</li>
</ul>
</div>
<div class="orderbtn-area">
<div class="order-btn-cont"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Subscribe Now !</div>
</div>
</div>
</div>
jQuery
$('#get-started').delegate('.check-opt', 'click', function () {
let cost = '0';
let itemname = '';
let first = '';
let itemid = ''
if ($(this).is(':checked')) {
cost = $(this).attr('data');
itemid = $(this).attr('data-itemid');
order_additional_options += Number(cost);
itemname = $(this).attr('value');
first = itemname.slice(0, itemname.indexOf(" "));
$("#no-addons").remove();
$(".pack-add").append("<li data-cost='" + cost + "' data-id='item_" + first + cost + "' data-itemid='" + itemid + "'>" + itemname + itemid + "</li>");
} else { // minus unchecked value
cost = $(this).attr('data');
itemname = $(this).attr('value');
first = itemname.slice(0, itemname.indexOf(" "));
order_additional_options -= Number(cost);
$('[data-id=item_' + first + cost + ']').remove();
}
cart_update();
});
// on click order button submit the form
$('#order_btn_id').on("click", function () {
$('a').attr("href", "http://cleancolor.staging.wpengine.com/?add-to-cart=");
});
Determine whether the window has a push stat
Find all elements that are added to the .pack-add and extract their number
Compile a , delimited string
The following sections that starts and end with //*************
in the snip below should do the trick. Probably you can refactor it into a function.
// add and remove check box items on summary
$('#get-started').delegate('.check-opt', 'click', function () {
let cost = '0';
let itemname = '';
let first = '';
let itemid = ''
if ($(this).is(':checked')) {
cost = $(this).attr('data');
itemid = $(this).attr('data-itemid');
order_additional_options += Number(cost);
itemname = $(this).attr('value');
first = itemname.slice(0, itemname.indexOf(" "));
$("#no-addons").remove();
$(".pack-add").append("<li data-cost='" + cost + "' data-id='item_" + first + cost + "' data-itemid='" + itemid + "'>" + itemname + itemid + "</li>");
// ********************* INSERTED CODES
var all_values=""
$(".pack-add").children().each(function(){
all_values+=$(this).attr('data-itemid')+" "
})
console.log(all_values.trim().replace(" ",","));
var query_string="?add-to-cart="+all_values.trim().replace(/ /g,",");
if (history.pushState) {
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + query_string;
window.history.pushState({path:newurl},'',newurl);
}
// **********************END OF NEW CODES
} else { // minus unchecked value
cost = $(this).attr('data');
itemname = $(this).attr('value');
first = itemname.slice(0, itemname.indexOf(" "));
order_additional_options -= Number(cost);
$('[data-id=item_' + first + cost + ']').remove();
// ********************* INSERTED CODES
var all_values=""
$(".pack-add").children().each(function(){
all_values+=$(this).attr('data-itemid')+" "
})
console.log(all_values.trim().replace(" ",","));
var query_string="?add-to-cart="+all_values.trim().replace(/ /g,",");
if (history.pushState) {
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + query_string;
window.history.pushState({path:newurl},'',newurl);
}
}
cart_update();
});

How to return a value in the only non-blank column in a range for sendEmail function in Google App Scripts

The issue is: I can't find a way to return the value for 'Course' because each form submission generates a new row where the name of the course is spread over columns E to M (column 4 through 12).
In each row, there is only one 'Course' name in one of the columns from E to M (e.g only in F) and all other columns are blank. (Users can only select one course and all the other columns will be blank. I have to categorize the courses into the 9 columns because of the page breaks in order to split the sheer number of options that users select the course from.) How do I return the value of the only non blank cell from E to M which will be entered in the email ?
I was advised to insert the entire findCourse function inside of the sendEmail function before any of the other code. I did so but I have still been receiving failure notifications of the Google App Scripts: TypeError: Cannot read property "values" from undefined. (line 14, file "Code") (referring to var value = e.values[i])
The full code below:
function sendEmail(e) {
function findCourse (e){
var courseToTake;
//loop through values
for ( var i = 4; i <=12; i ++){
//pull value into variable
var value = e.values[i];
if (value != undefined){
//if we find an actual string value, set the course to take variable
courseToTake = value;
}
}
return courseToTake;
}
var Name = e.namedValues["Full name as appear in NRIC"];
var Course = findCourse();
var Start = e.values[14];
var End = e.values[15];
var StartTime = e.values[24];
var EndTime = e.values[25];
var Details = e.values[13];
var Cost = e.values[17];
var Email = e.values[18];
var ROname = e.values[19];
var ROemail = e.values[20];
var Location = e.values[23];
var subject = "Training Approval Request for " + Course;
var message = "<p >" + "Dear " + ROname + "<p />"
+ Name + " seeks your approval to attend the " + Course + ". The details are as follow:"
+ "<p >" + "<b>Date:</b> " + Start + " - " + End + " <br />"
+ "<b>Time:</b> " + StartTime + " - " + EndTime + " <br />"
+ "<b>Location:</b> " + Location + " <br />"
+ "<b>Course objectives and benefits:</b> " + Details + " <br />"
+ "<b>Course fees:</b> " + "$" + Cost + " <br />" + "<p />"
+ "Please reply directly to this email for your approval or if you have any questions/comments. Thank you. "
MailApp.sendEmail(ROemail, Email, subject, message);
}
After rearranging findCourse as its own function: sorry if I made any mistakes here but i'll try my best to follow all suggestions. If i've added in Logger.log(e) correctly, both functions seem to be undefined
function sendEmail(e) {
Logger.log(e);
var Name = e.values[2];
var Course = findCourse();
var Start = e.values[14];
var End = e.values[15];
var StartTime = e.values[24];
var EndTime = e.values[25];
var Details = e.values[13];
var Cost = e.values[17];
var Email = e.values[18];
var ROname = e.values[19];
var ROemail = e.values[20];
var Location = e.values[23];
var subject = "Training Approval Request for " + Course;
var message = "<p >" + "Dear " + ROname + "<p />"
+ Name + " seeks your approval to attend the " + Course + ". The details are as follow:"
+ "<p >" + "<b>Date:</b> " + Start + " - " + End + " <br />"
+ "<b>Time:</b> " + StartTime + " - " + EndTime + " <br />"
+ "<b>Location:</b> " + Location + " <br />"
+ "<b>Course objectives and benefits:</b> " + Details + " <br />"
+ "<b>Course fees:</b> " + "$" + Cost + " <br />" + "<p />"
+ "Please reply directly to this email for your approval or if you have any questions/comments. Thank you. "
MailApp.sendEmail(ROemail, Email, subject, message);
}
function findCourse (e){
var courseToTake;
//loop through values
for ( var i = 4; i <=12; i ++){
//pull value into variable
var value = e.values[i];
if (value != undefined){
//if we find an actual string value, set the course to take variable
courseToTake = value;
}
}
return courseToTake;
var courseToTake = findCourse(e);
Logger.log(e);
}
I will really deeply appreciate any help or alternative solutions here.
Thank you!
What I changed in your code to address your question:
I assigned the onFormSubmit trigger to your sendEmail function so the event object would no longer be undefined
I added a call to findCourse() so your course variable would no longer be undefined
I fixed the undefined check by changing if(value != undefined) to if(typeof value !== 'undefined')
I added a check for a blank value (This was the important bit in the logic after the faulty undefined check) if(value != '')
Explanation:
To trigger the event, an installable trigger needs to be setup for the On Form Submit event that points to your sendEmail function. This can be found in Resources -> Current Project Triggers
To retrieve the course, you need to call your function findCourse() and pass in the e event object. Example: var course = findCourse(e);. This will assign the return value from findCourse(e); to the course variable. You can then use this variable like normal within the rest of your statements.
When checking for undefined, you need to use typeof and then check for the string of 'undefined', or your check will ironically throw an undefined exception.
The values of the form submit should not be undefined, blank values should just be blank strings. so checking for non-blank strings was necessary to get the course name from the values array.
Fixed Code:
function sendEmail(e) {
Logger.log(e)
var course = findCourse(e);
var Name = e.values[19];
var Start = e.values[12];
var End = e.values[14];
var StartTime = e.values[13];
var EndTime = e.values[15];
var Details = e.values[11];
var Cost = e.values[17];
var Email = e.values[20];
var ROname = e.values[21];
var ROemail = e.values[22];
var Location = e.values[16];
var subject = "Training Approval Request for " + course;
var message = "<p >" + "Dear " + ROname + "<p />"
+ Name + " seeks your approval to attend the " + course + ". The details are as follow:"
+ "<p >" + "<b>Date:</b> " + Start + " - " + End + " <br />"
+ "<b>Time:</b> " + StartTime + " - " + EndTime + " <br />"
+ "<b>Location:</b> " + Location + " <br />"
+ "<b>Course objectives and benefits:</b> " + Details + " <br />"
+ "<b>Course fees:</b> " + "$" + Cost + " <br />" + "<p />"
+ "Please reply directly to this email for your approval or if you have any questions/comments. Thank you. "
MailApp.sendEmail(ROemail, Email+";" + "redactedEmail", subject, message);
}
function findCourse (e){
var courseToTake;
//loop through values
for ( var i = 2; i <=10; i ++){
//pull value into variable
var value = e.values[i];
if (typeof value !== 'undefined'){ //If value is defined
if(value != ''){ //If value is not blank
//if we find an actual non-blank string value, set the course to take variable
courseToTake = value;
}
}
}
return courseToTake;
}

Adding inline script to a jQuery html() return

I am using a for loop & jQuery output to html(). to output a JSON response to a html div.
In the for loop, I am transforming each result as follows into the output variable:
$.ajax(settings).done(function(response) {
var output = "";
for (i in response.Products) {
var productID = response.Products[i].ProductId;
var OtherVariables = response.Products[i].OtherResponseFields;
output += "<Some Other Code> <script type=\"application/javascript\"> ...some code unique to each productID... </script>";
}
$("#allResults").html(output);
});
The output works fine when I do not have the following in the output variable:
<script type=\"application/javascript\"> ...some code unique to each productID... </script>
But it breaks when I do add it as per the top code sample. I am looking at using the variable "clicks_productID" for the user to select a product quantity in a popup, before adding the product & qty to my database (not yet built).
Is there a better way of doing this (the results need to be different for each JSON return - which can be a variable response qty based on the submission)?
change
<script type=\"application/javascript\">var clicks_" + productID + " = 1;var minimum = 1;function updateClickCount_" + productID + "() {if (clicks >= minimum) {document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";} else {clicks_" + productID + " = 1;document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";}}</script>
to
<scr" + "ipt type=\"application/javascript\">var clicks_" + productID + " = 1;var minimum = 1;function updateClickCount_" + productID + "() {if (clicks >= minimum) {document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";} else {clicks_" + productID + " = 1;document.getElementById('clickCount_" + productID + "').innerHTML = clicks_" + productID + ";}}</scr" + "ipt>
otherwise the interpreter will think the closing script tag in your string is the end of your script

Categories