Adding contents of Array to HTML of a div JS - javascript

I am working on the ordering process for a site and I am experimenting with having an order alert box displayed in the window at all times.
Currently I have this box set to show how many items are in your order.
I would like to display the name of the product and the qty in this box also.
Below is the code that controls this box:
$(document).ready(function(){
//if cookie exists, show the panel
if($.cookie('order_cookie') != undefined){
productArray = JSON.parse($.cookie('order_cookie'));
$(".order-alert").show();
for(var i = 0; i < productArray.length; i++){
console.log(productArray[i]);
var obj = productArray[i];
console.log("Object code: " + obj.stockCode + " Qty: " + obj.quantity);
}
$('#order_counter').html(productArray.length);
}
});
The console.log is printing the correct data, I guess it's just a case of inserting the data into the html
The HTML for the box is:
<section class="order-alert">
Your Order
<p>You have <span id="order_counter">0</span> items in your order</p>
</section>
I would like to display the contents of the order below the counter but I'm not sure how I would do that.

Just add append to your code -
for(var i = 0; i < productArray.length; i++){
console.log(productArray[i]);
var obj = productArray[i];
console.log("Object code: " + obj.stockCode + " Qty: " + obj.quantity);
$('.order-alert').append('<p>Object code: ' + obj.stockCode + ' Qty: ' + obj.quantity + '</p>');
}

Simply use the append on the div you want to put them in.
$("#myDiv").append($("<p>Object code: "+obj.stockCode+" Qty: "+obj.quantity+"</p>"));
You can put any html string in the jquery fragment initializer. { $(" < html > ") }

Related

Dynamic html form data AJAX redirect to google sheets bug

I'm working to send form data from a dynamic user form to a google sheets page. There is a corpus of 140 potential forms, users are shown 20 at random. I'm not getting any errors in the console but the google sheet is not populating. I know that the sheets gs script is OK because the connection worked alright under simpler use cases.
I've included the html and js code that I have below. The website is being rendered fine on my local machine. The images and form substance is working as well.
<!DOCTYPE html>
<body>
<!-- Required JS packages for this project-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script src="jquery-3.3.1.min.js"></script>
<script src="require.js"></script>
<!--Create empty form element -->
<div id = "form_submit"></div>
<!-- JS function to fill form element with 20 hold type questions forms -->
<script>
// Establish file name to hold mapping with two lists and a dict to link elements
var files = ['1.png', '10.png', ..., '98.png', '99.png']
var numWords = ["one", "two", "three",.., "one_hundred_and_fifty"]
var numWordDict = { 1: 'one', ..., 150: 'one_hundred_and_fifty' } // Generate list of 20 random digits that will select holds to be classified
// Create array of twenty random holds
var idx = []
for (var j = 0; j < 20; j++) {
idx.push(Math.floor(Math.random() * 140) + 0)
}
console.log(idx)
// Loop over array and make a form element for each hold within the div element
$(document).ready(function (list) {
for (var i = 0; i < idx.length; i++) {
// retrieve mapped index
var randHoldIdx = idx[i]
// build path to hold image
var holdPath = files[randHoldIdx]
var numb = holdPath.match(/\d/g);
numb = numb.join("");
var colName = numWordDict[numb]
var form_name = 'submit-to-google-sheet' + numb
const scriptURL = 'https://script.google.com/macros/s/AKfycbyhMLuTGNkaNOxeNCOx_t1ERThZT8VEYDcMmiQhj773kIrUuRA/exec'
// Form element contents will be appended into the div element with id = form_submit
$("#form_submit").append(
// html form skeleton for users to select jug,pinch, crimp, pocket or undercling from radio button
// options
"<form name = " + form_name + ">"+
"<input type='radio' name = " +colName + " class=" + String(colName) +" value=1>Jug<br>" +
"<input type='radio' name = " + colName + " class=" + String(colName) +" value=2>Pinch<br>" +
"<input type='radio'name = " +colName + " class=" + String(colName) +" value=3>Crimp<br>"+
"<input type='radio' name = " +colName + " class=" + String(colName) +" value=4>Pocket<br>"+
"<input type='radio' name = " +colName + " class=" + String(colName) +" value=5>Undercling"+
// Submit button for form, close form
"<button type='submit'>Submit!</button></form>"+
// image of climbing hold in question with coordinates to position on moonboard
"<div><img src=labelled_imgs/" +String(holdPath) +" alt='selected hold'></div>");
var form = document.forms[form_name]
window.onload=function(){
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
}
}
});
</script>
</body>
I suspect that there is something wrong with the event listener. It may be something simple, but I would welcome any suggestions for alternate solutions to this problem! This is a little different than just sending user input from a form to a google sheet as the form contents are changed each time the page is rendered. For context, this is a portion of a custom crowd-sourcing platform. Thanks for any help!
Issues:
You're rewriting the window.onload function each time in the loop for each form. Only the last form's submit event will be disabled onload and be submitted to server.
When you're creating a random array of numbers, there is no guarantee that it will be unique. If two forms end up with the same name, only the first form's submit event will be prevented.
Solution:
Since the form is already appended, directly run the function for each form inside the loop without writing window.onload
var form = document.forms[form_name]
form.addEventListener('submit', e => {
e.preventDefault();
fetch(scriptURL, { method: 'POST'.....
Make Idx unique:
idx = [...new Set(idx)]
I was able to solve the problem by changing the architecture of the page. Instead of using many different forms for each classification task, I used one form that was submitted as a whole.
I have posted the new code below. Feel free to reach out for clarification!
<!DOCTYPE html>
<body>
<!-- Required JS packages for this project-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script src="jquery-3.3.1.min.js"></script>
<script src="require.js"></script>
<!--Create empty form element -->
<div id="form_submit1">
<form id="form_submit" , name="submit_to_sheets">
</form>
</div>
<!-- JS function to fill form element with 20 hold type questions forms -->
<script>
// Establish file name to hold mapping with two lists and a dict to link elements
var files = ['1.png', '10.png',...,'99.png']
var numWords = ["one", "two",...,"one_hundred_and_fifty"]
var numWordDict = {
1: 'one',
2: 'two',
...
150: 'one_hundred_and_fifty'
} // Generate list of 20 random digits that will select holds to be classified
// Create array of twenty random holds
var idx = []
for (var j = 0; j < 20; j++) {
idx.push(Math.floor(Math.random() * 140) + 0)
}
console.log(idx)
// Loop over array and make a form element for each hold within the div element
$(document).ready(function(list) {
for (var i = 0; i < idx.length; i++) {
// retrieve mapped index
var randHoldIdx = idx[i]
// build path to hold image
var holdPath = files[randHoldIdx]
var numb = holdPath.match(/\d/g);
numb = numb.join("");
var colName = numWordDict[numb]
// Form element contents will be appended into the div element with id = form_submit
$("#form_submit").append(
// html form skeleton for users to select jug,pinch, crimp, pocket or undercling from radio button
// options
"<input type='radio' name = " + colName + " class=" + String(colName) + " value=1>Jug<br>" +
"<input type='radio' name = " + colName + " class=" + String(colName) + " value=2>Pinch<br>" +
"<input type='radio'name = " + colName + " class=" + String(colName) + " value=3>Crimp<br>" +
"<input type='radio' name = " + colName + " class=" + String(colName) + " value=4>Pocket<br>" +
"<input type='radio' name = " + colName + " class=" + String(colName) + " value=5>Undercling" +
// image of climbing hold in question with coordinates to position on moonboard
"<div><img src=labelled_imgs/" + String(holdPath) + " alt='selected hold'></div>");
}
// prepend form begining to html outside of for loop
// append end of form to html outside of for loop
});
$("#form_submit").append("<button type='submit'>Submit!</button>");
</script>
<script>
const form = document.forms["submit_to_sheets"]
const scriptURL = 'https://script.google.com/macros/s/AKfycbyhMLuTGNkaNOxeNCOx_t1ERThZT8VEYDcMmiQhj773kIrUuRA/exec'
console.log(form)
console.log("loop")
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, {
method: 'POST',
body: new FormData(form)
})
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
</script>
</body>
</html>

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

How do I create a div and give it an ID based on a changing variable?

I'm making a quiz. The user decides how many questions he wants to answer.
A function then takes this number and runs a loop to make an individual question div for each question. The quiz shows a Chinese character and the user has to pick the correct translation.
My code:
var fillInQuestion = function() {
questionDivIdHTML = 'question' + questionNum;
/****************************************
How do I make this Div's ID = to questionDivIdHTML?
// Creates question div
$('#questionArea').append("<div class='questionDiv'></div>");
//$('#questionArea:last-child').attr("id", questionDivIdHTML); <-- NOT WORKING
***************************************/
// Sets up a choice bank.
var choices = [];
// choices will be chosen from this.
var tempAnswerSet = allChoices.slice(0);
//find random item in the database for the question
var thisQuestion = allQuestions[Math.floor(Math.random() * allQuestions.length)];
// add that item to choices
choices.push(thisQuestion);
// remove item from 'database' so it cannot be used in another question
allQuestions.splice(allQuestions.indexOf(thisQuestion), 1);
// remove item from tempAnswer set so it can only be one choice
tempAnswerSet.splice(tempAnswerSet.indexOf(thisQuestion), 1);
// add three more items from the database (incorrect items)
var i = 3;
for (i; i > 0; i--) {
var addChoice = tempAnswerSet[Math.floor(Math.random() * tempAnswerSet.length)];
choices.push(addChoice);
// remove the one selected each time so they cant be chosen again
tempAnswerSet.splice(tempAnswerSet.indexOf(addChoice), 1);
//console.log("choices length: " + choices.length);
}
// shuffle the array
choices.shuffle();
// fill in the div with choices.
$('#questionDivIdHTML').append("Here is an question prompt:" + thisQuestion.english + " <br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[0].hanyu</script>'></input>" + choices[0].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[1].hanyu</script>'></input> " + choices[1].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[2].hanyu</script>'></input> " + choices[2].hanyu + "<br>");
$('questionDivIdHTMLwithHash').append("<input type='radio' name='question<script>questionNum</script>Choice' value='<script>choices[3].hanyu</script>'></input> " + choices[3].hanyu + "<br>");
};
var fillOutQuiz = function() {
for (questionAmount; questionAmount > 0; questionAmount--) {
fillInQuestion();
questionNum += 1;
}
};
I've gotten this code to work, but I broke it, when trying to add the dynamic ID and loop it.
You are saying that this portion of code is not working:
$('#questionArea').append("<div class='questionDiv'></div>");
$('#questionArea:last-child').attr("id", questionDivIdHTML);
Well, it does not work because the :last-child pseudo selector is used incorrectly (see below). It should be:
$('#questionArea').append("<div class='questionDiv'></div>");
$('#questionArea > :last-child').attr("id", questionDivIdHTML);
Or better, you can rearrange your code like this:
$("<div class='questionDiv'></div>")
.attr("id", questionDivIdHTML)
.appendTo("#questionArea");
#questionArea:last-child selects an element with id = questionArea which is also the last child of its parent
#questionArea > :last-child selects the last child of an element with id = questionArea

How to get the value of id of innerHTML?

I have created a html like this:
<body onload = callAlert();loaded()>
<ul id="thelist">
<div id = "lst"></div>
</ul>
</div>
</body>
The callAlert() is here:
function callAlert()
{
listRows = prompt("how many list row you want??");
var listText = "List Number";
for(var i = 0;i < listRows; i++)
{
if(i%2==0)
{
listText = listText +i+'<p style="background-color:#EEEEEE" id = "listNum' + i + '" onclick = itemclicked(id)>';
}
else
{
listText = listText + i+ '<p id = "listNum' + i + '" onclick = itemclicked(id)>';
}
listText = listText + i;
//document.getElementById("lst").innerHTML = listText+i+'5';
}
document.getElementById("lst").innerHTML = listText+i;
}
Inside callAlert(), I have created id runtime inside the <p> tag and at last of for loop, I have set the paragraph like this. document.getElementById("lst").innerHTML = listText+i;
Now I am confuse when listItem is clicked then how to access the value of the selected item.
I am using this:
function itemclicked(id)
{
alert("clicked at :"+id);
var pElement = document.getElementById(id).value;
alert("value of this is: "+pElement);
}
But getting value as undefined.
Any help would be grateful.
try onclick = itemclicked(this.id) instead of onclick = 'itemclicked(id)'
Dude, you should really work on you CodingStyle. Also, write simple, clean code.
First, the html-code should simply look like this:
<body onload="callAlert();loaded();">
<ul id="thelist"></ul>
</body>
No div or anything like this. ul and ol shall be used in combination with li only.
Also, you should always close the html-tags in the right order. Otherwise, like in your examle, you have different nubers of opening and closing-tags. (the closing div in the 5th line of your html-example doesn't refer to a opening div-tag)...
And here comes the fixed code:
<script type="text/javascript">
function callAlert() {
var rows = prompt('Please type in the number of required rows');
var listCode = '';
for (var i = 0; i < rows; i++) {
var listID = 'list_' + i.toString();
if (i % 2 === 0) {
listCode += '<li style="background-color:#EEEEEE" id="' + listID + '" onclick="itemClicked(this.id);">listItem# ' + i + '</li>';
}
else {
listCode += '<li id="' + listID + '" onclick="itemClicked(this.id);">listItem# ' + i + '</li>';
}
}
document.getElementById('thelist').innerHTML = listCode;
}
function itemClicked(id) {
var pElement = document.getElementById(id).innerHTML;
alert("Clicked: " + id + '\nValue: ' + pElement);
}
</script>
You can watch a working sample in this fiddle.
The problems were:
You have to commit the id of the clicked item using this.id like #Varada already mentioned.
Before that, you have to build a working id, parsing numbers to strings using .toString()
You really did write kind of messy code. What was supposed to result wasn't a list, it was various div-containers wrapped inside a ul-tag. Oh my.
BTW: Never ever check if sth. is 0 using the ==-operator. Better always use the ===-operator. Read about the problem here
BTW++: I don't know what value you wanted to read in your itemClicked()-function. I didn't test if it would read the innerHTML but generally, you can only read information from where information was written to before. In this sample, value should be empty i guess..
Hope i didn't forget about anything. The Code works right now as you can see. If you've got any further questions, just ask.
Cheers!
You can pass only the var i and search the id after like this:
Your p constructor dymanic with passing only i
<p id = "listNum' + i + '" onclick = itemclicked(' + i + ')>
function
function itemclicked(id)
{
id='listNum'+i;
alert("clicked at :"+id);
var pElement = document.getElementById(id).value;
alert("value of this is: "+pElement);
}
is what you want?
I am not sure but shouldn't the onclick function be wrapped with double quotes like so:
You have this
onclick = itemclicked(id)>'
And it should be this
onclick = "itemclicked(id)">'
You have to modify your itemclicked function to retrieve the "value" of your p element.
function itemclicked( id ) {
alert( "clicked at :" + id );
var el = document.getElementById( id );
// depending on the browser one of these will work
var pElement = el.contentText || el.innerText;
alert( "value of this is: " + pElement );
}
demo here

javascript/jquery- how to obtain all possible values in a drop down box or list box

I am trying to obtain all the values stored in a list box/drop down box.
I am currently using following code to obtain name, type, multiple attribute and values--
$(jQuery('input, select, textarea', $(this).parent('form'))).each(function() {
var textmsg=" Element # " + (count+1) + "...Name of this input element = " + $(this).attr('name') + " multiplechoice-" + $(this).attr('multiple');
textmsg= textmsg + "...Also, for this element, the value is " + $(this).val() + " and type =" + $(this).attr('type');
alert (textmsg);
});
But the jquery call $(this).val() retrieves only the currently selected value in a list box (and not all values). The same thing happens when I use the above code in a drop down box. How do I obtain all the values stored in a list/drop down box? If it is not possible to do this using jquery, then can this be done using pure javascript? (I have a reference to that form element which can be used in pure javascript...)
To create a list of your options you need to declare a variable outside of the loop
var listofoptions = new Array();
$("#id option").each(function()
{
// add $(this).val() to your list
listofoptions.push($(this).val());
});
// do what you want with listofoptions
You can get all fields inside form using following code
var formFields = $("form")[0];
var textmsg = "";
for ( var i = 0, len = formFields.length; i < len; i++ ) {
textmsg +=" Element # " + (i+1) + "...Name of this input element = " + $(formFields[i]).attr('name') + " multiplechoice-" + $(formFields[i]).attr('multiple');
textmsg= textmsg + "...Also, for this element, the value is " + $(formFields[i]).val() + " and type =" + $(formFields[i]).attr('type');
}
document.write( textmsg );
jsFiddler

Categories

Resources