I have a dynamic array as such:
var PartnerEmailList = [one#email.com, two#email.com, three#email.com];
The following function creates a table that is displayed in a showModalDialog window.
function makeTableHTML() {
var PartnerEmailList = [one#email.com, two#email.com, three#email.com];
var result = "<table border=0>";
result += "<tr><td style=\"text-align:center\"><input type=\"checkbox\" name =" + PartnerEmailList[0] + " value =" + PartnerEmailList[0] + " checked></input></td>";
result += "<td style=\"vertical-align:text-middle\">" + PartnerEmailList[0] + "</td></tr>";
for(var i=1; i<PartnerEmailList.length; i++) {
result += "<tr><td style=\"text-align:center\"><input type=\"checkbox\" unchecked></input></td>";
result += "<td style=\"vertical-align:text-middle\">" + PartnerEmailList[i] + "</td></tr>";
}
result += "</table>";
result += "<input type=\"submit\" value=\"Submit\" class=\"action\" onclick=\"form_data()\">"
result += "<input type=\"button\" value=\"Close\" onclick=\"google.script.host.close()\">"
return result;
}
The user clicks a button within Google Sheets that runs the following script. This script pops up a ModalDialog window where the user can check which emails they want to send this product to.
function SelectEmails(){
var ui = SpreadsheetApp.getUi();
var result = makeTableHTML();
var bccSend = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('main_gen').getRange(2,2).getValue();
if(bccSend === ''){
//Call the HTML file and set the width and height
var html = HtmlService.createHtmlOutput(result)
.setWidth(450)
.setHeight(300);
//Display the dialog
var dialog = ui.showModalDialog(html, "Select the intended recipients of this briefing.");
}
}
I need to write a function that looks through all the checkboxes (they are all assigned a value within the html code) and stores the values of each one that is checked in an array. I will be calling this array in a different function to actually send out the email.
There may be a much better way to go about this, but this is what I have come up with so far. Any help would be much appreciated! Thanks!
Related
I have a JS function where I'm dynamically creating a set of buttons. The buttons are placed in rows such that everytime a button is clicked, that particular row needs to be added to another table below that division.
I am able to successfully add only the first row of the original table to the intended table below the check division. All the others are not working. I'm not sure why the event-listener is not being called for all the Select buttons.
Dynamically creating the Original Table
for(var q=0;q<attributesNameArray.length;q++)
{
var chkID = "chkID"+elementID+attributesNameArray[q];
var aggComboID = "Aggregate-Combo"+q;
var attrNameID = "attrName"+q;
var attrTypeID = "attrType"+q;
var btnID = q+"addSelectedColumnBtn";
chkname = attributesNameArray[q];
chkVal = attributesDataTypeArray[q];
var asNameLbl = "usr"+q;
asNameid = asNameLbl;
$("#tableSelectedAttributes").append(
"<tr>"+
"<td id='"+attrNameID+"'>"+attributesNameArray[q]+"</td>"+
"<td id='"+attrTypeID+"'>"+attributesDataTypeArray[q]+"</td>"+
"<td><input type='text' id='"+asNameid+"'></td>"+
"<td>"+
"<select id='"+aggComboID+"' name='Aggregate-Combo' class='form-control'>"+
"<option value='Select an option'>Select an option</option>"+
"<option value='MIN'>MIN</option>"+
"<option value='MAX'>MAX</option>"+
"<option value='SUM'>SUM</option>"+
"<option value='AVG'>AVG</option>"+
"<option value='COUNT'>COUNT</option>"+
"</select>"+
"</td>"+
"<td><button id='addSelectedColumnBtn' name='"+btnID+"' class='btn btn-info'>Select</button></td>"+
"</tr>"+
"</div>"
);
}
...
document.getElementById("addSelectedColumnBtn").addEventListener("click", function() {
displaySelectedColumns(this,fromNameSt);
}, false);
displaySelectedColumns(this,fromNameSt)
function displaySelectedColumns(sender,fromNameSt)
{
var clickedelemId=sender.name;
q = clickedelemId.charAt(0);
var aggComboID = "Aggregate-Combo"+q;
var attrNameID = "attrName"+q;
var attrTypeID = "attrType"+q;
var asNameLbl = "usr"+q;
var selTableId1 = "sel1"+selectedColumnCount;
var selTableId2 = "sel2"+selectedColumnCount;
var selTableId3 = "sel3"+selectedColumnCount;
var selTableId4 = "sel4"+selectedColumnCount;
var attributeName = document.getElementById(attrNameID).innerText;
var attributeType = document.getElementById(attrTypeID).innerHTML;
var selectedAsName = document.getElementById(asNameLbl).value;
var choice=document.getElementById(aggComboID);
var selectedAggregate = choice.options[choice.selectedIndex].text;
alert(attributeName+" "+attributeType+" "+selectedAsName+" "+selectedAggregate);
if(selectedAggregate == "Select an option")
{
if(selectedAsName == "" || selectedAsName == " " || selectedAsName == "null" || selectedAsName == "undefined" ||selectedAsName == null || selectedAsName == undefined)
{
alert("As name: false");
$("#displaySelectedColumnTable").append(
"<tr>"+
"<td id='"+selTableId1+"'>"+attributeName+"</td>"+
"<td id='"+selTableId2+"'>"+attributeType+"</td>"+
"<td id='"+selTableId3+"'></td>"+
"<td id='"+selTableId4+"'></td>"+
"</tr>"
);
}
else
{
$("#displaySelectedColumnTable").append(
...
Any suggestions in this regard will be highly appreciated.
Id's have to be unique across your html page, addSelectedColumnBtn is repeated for every button.
Make it a unique id first by appending the same q variable which you added for the select element
"<td><button id='addSelectedColumnBtn_" + q + "' name='"+btnID+"' class='btn btn-info'>Select</button></td>"+
Now call this addEventListener inside the for-loop only for all buttons
document.getElementById("addSelectedColumnBtn_" + q).addEventListener("click", function() {
displaySelectedColumns(this,fromNameSt);
}, false);
So I have 2 pages.
On one I have a table that is getting data from a JSON page and I inserted a button on each row that whenever is clicked it should get that item on an array.
And then, that array should give the results on the second page.
I can get the info from the JSON without problems, but cannot store the information on an array. Can someone help me? I'm quite new on JavaScript.
Page 1:
<script>
<!-- Retrieve data from file -->
var products=[];
var cartArray=[];
var product_array=[];
$.getJSON('products.json',function(data){
$.each(data.products, function(i, f){
var img = f.image_url;
var title = f.title;
var price = f.price;
var old_price = f.old_price;
product_array.push([img, title, price]);
var tblCell = "<tr><td class='prod_container'><tr><td class='prod_img_container'><img class='prod_img' src=" + img + "></td></tr>" + "<tr class='title_container'><td class='title'>" + title + "</td></tr>" + "<tr class='price_container'><td class='price'>" + price + "</td>" + "<td class='price_org'>" + old_price + "</td>" + "<td class='add_cart'><img class='add_cart_img' src='img/buynow-green-6.png' onClick='addToCart()'>" + "</td></tr>"
$(tblCell).appendTo("#list_products tbody");
});
});
<!-- Add To Cart -->
function addToCart(){
cartArray.push([product_array.title, product_array.img, product_array.price]);
window.alert(cartArray);
}
<!-- Store and go to checkout -->
function goToCheckout(){
$('#store').on('click', function(){
localStorage.cartArray = cartArray;
});
window.location.href="cart.html";
}
Not sure of your final data structure needs, but if you want a multi-dimensional array:
var cartArray = []
function addToCart(product_array){
cartArray.push([product_array.title, product_array.img, product_array.price];
window.alert(cartArray);
}
I'm trying to do something pretty simple, but for some reason I can't spot my mistake. The statement at the end of the function seems to be executing prior to the for loop, which I'm sure isn't the case.
var object = {
"key1":"foo",
"key2":"bar"
}
var message = document.getElementById("message");
message.innerHTML = "<table>";
for(var index in object) {
if (object.hasOwnProperty(index)) {
message.innerHTML += "<tr><td>" + index + "</td><td>" + object[index] + "</td></tr>";
}
}
message.innerHTML += "</table>";
I figured this would create the string:
<table>
<tr><td>key1</td><td>foo</td></tr>
<tr><td>key2</td><td>bar</td></tr>
</table>
However, when I inspect element, I'm getting this result:
<div id="message">
<table></table> <!-- why would </table> be in the string before key1 etc.? -->
key1fookey2bar
</div>
When I replace the table with line breaks, it looks like the loop is executing correctly, so I'm not sure what's happening. Can anyone spot my mistake?
It is because you are appending directly to the innerHTML of the message.
Build your html using a variable, and then set message.innerHTML = that variable.
As in:
var messageElement = document.getElementById("message");
var message = "<table>";
for(var index in object) {
if (object.hasOwnProperty(index)) {
message += "<tr><td>" + index + "</td><td>" + object[index] + "</td></tr>";
}
}
message += "</table>";
messageElement.innerHTML = message;
I'm going to try to describe this the best I can. I have a form that the user fills out, when it confirms the users info, it then prints it out on a table, and the user may edit it directly on the table using the contendEditable attribute. The problem i'm having is if the user edits his/her email address, the browser detects it as an email address (since it's not in an input element) and doesn't pass the email through the form. All other values go through fine. I'm using PHP to process the form and just print out the fields to make sure it goes through properly.
The confirm page should like this:
John,Smith,JSMITH,abc#123.com,111-222-3345
But it looks like this:
John,Smith,JSMITH,null,111-222-3345
Any suggestions?
It would be easier if i posted my code so here it is:
HTML:
<html>
<head>
<script type = "text/javascript" src = "ext.js"></script>
</head>
<body>
<form name = "setupForm" id = "setupForm" action = "confirmSetup.php" method = "post">
<div id = "confirmInfo"></div>
<div id = "hiddenFields"></div>
</form>
</body>
</html>
/* I didn't put my full code on here as it is way too long.
But this HTML document is what is shown after input fields
have been previously submit, and this page is just to confirm
the user input.
*/
JS:
function verifyInfo(){ // This function is called when user submits all his info
var firstname = document.getElementById("txtFirstname").value;
var lastname = document.getElementById("txtLastname").value;
var username = document.getElementById("hdnUsername").value;
var email = document.getElementById("txtEmail").value;
var phone = document.getElementById("txtPhone").value;
var output = "";
output += "<table id = 'confirm'>";
output += "<tr>";
output += " <th>Firstname</th>";
output += " <td id = 'tdFirstname'>";
output += " <div onkeyup = 'updateUsername()' contentEditable>" + firstname + "</div>";
output += " </td>";
output += "</tr>";
output += "<tr>";
output += " <th>Lastname</th>";
output += " <td id = 'tdLastname'>";
output += " <div onkeyup = 'updateUsername()' contentEditable>" + lastname + "</div>";
output += " </td>";
output += "</tr>";
output += "<tr>";
output += " <th>Username</th>";
output += " <td id = 'tdUsername'>" + username + "</td>";
output += "</tr>";
output += "<tr>";
output += " <th>Email</th>";
output += " <td id = 'tdEmail'>";
output += " <div style = 'min-width:1px;' onkeyup = 'verifyEmail(this.parentNode.id,event)' contentEditable>" + email + "</div>";
output += " <div id = 'validInvalid'>";
output += " <span class = 'dgreen'><br/>Valid email!</span>";
output += " </div>";
output += " </td>";
output += "</tr>";
output += "<tr>";
output += " <th>Phone</th>";
output += " <td id = 'tdPhone'>";
output += " <div style = 'min-width:1px;' onkeyup = 'verifyPhone(this.parentNode.id,event)' contentEditable>" + phone + "</div>";
output += " <div id = 'validInvalid1'>";
output += " <span class = 'dgreen'><br/>Valid phone!</span>";
output += " </div>";
output += " </td>";
output += "</tr>";
output += "</table>";
output += "<input type = 'button' name = 'submitSetup' id = 'submitSetup' value = 'Get Set Up!' onclick = 'goToConfirm()'/>";
document.getElementById("confirmInfo").innerHTML = output;
}
/* The way that function works is it takes the inputted text,
and places it into the table. This table enables the user to dynamically make any
changes necessary right onto the table. The username is created from first initial
and last name, which is called on the 'updateUsername()' function, which I am leaving
out.
*/
function verifyEmail(id,e){
var unicode = e.charCode ? e.charCode : e.keyCode;
if((unicode < 37 || unicode > 40) && unicode != 9){ // This doesn't allow email to be verified if the arrow keys, or tab key is pressed
var email = document.getElementById(id).firstChild.firstChild.nodeValue;
var emailFilter = /^[^0-9][A-z0-9_]+([.]A-z0-9_]+)*[#][A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}$/;
if(!emailFilter.test(email)){ // Checks if valid email
document.getElementById("validInvalid").innerHTML = "<span class = 'red'><br/>Not a valid email!</span>";
}else{
document.getElementById("validInvalid").innerHTML = "<span class = 'dgree'><br/>Valid email!</span>";
}
}
disableButton(); //If email or phone is invalid, button will be disabled
}
function verifyPhone(id,e){
var unicode = e.charCode ? e.charCode : e.keycode;
if((unicode < 37 || unicode > 40) && unicode != 9)){
var phone = document.getElementById(id).firstChild.firstChild.nodeValue;
if(phone.length > 12){ // Doesn't let user put it more than 12 characters (xxx-xxx-xxxx)
var difference = phone.length - 12;
phone = phone.substr(0,phone.length - difference);
document.getElementById(id).firstChild.firstChild.nodeValue = phone;
}
var phoneFilter = /\d{3}\-\d{3}\-\d{4}/;
if(!phoneFilter.test(phone)){ // Checks for valid phone number
document.getElementById("validInvalid1").innerHTML = "<span class = 'red'><br/>Not a valid phone!</span>";
}else{
document.getElementById("validInvalid1").innerHTML = "<span class = 'dgreen'><br/>Valid phone!</span>";
}
}
disableButton();
}
function disableButton(){
var email = document.getElementById("tdEmail").firstChild.nextSibling.firstChild.className;
var phone = document.getElementById("tdPhone").firstChild.nextSibling.firstsChild.className;
if(email == "red" || phone == "red"){
document.getElementById("submitSetup").disabled = true;
}else{
document.getElementById("submitSetup").disabled = false;
}
}
function goToConfirm(){ //This is the function that goes to confirmsetup.php. it works fine if email isn't edited in table, but if email is edited, it doesn't work
var firstname = document.getElementById("tdFirstname").firstChild.firstChild.nodeValue;
var lastname = document.getElementById("tdLastname").firstChild.firstChild.nodeValue;
var username = document.getElementById("tdUsername").firstChild.nodeValue;
var email = document.getElementById("tdEmail").firstChild.firstChild.nodeValue;
var phone = document.getElementById("tdPhone").firstChild.firstChild.nodeValue;
var hiddenfields = document.getElementById("hiddenFields");
var input = "<input type = 'hidden' name = 'hdnFirstname' id = 'hdnFirstname' value = '"+firstname+"'/>";
input += "<input type = 'hidden' name = 'hdnLastname' id = 'hdnLastname' value = '"+lastname+"'/>";
input += "<input type = 'hidden' name = 'hdnUsername' id = 'hdnUsername' value = '"+username+"'/>";
input += "<input type = 'hidden' name = 'hdnEmail' id = 'hdnEmail' value = '"+email+"'/>";
input += "<input type = 'hidden' name = 'hdnPHone' id = 'hdnPhone' value = '"+phone+"'/>";
hiddenFields.innerHTML = input;
document.setupForm.submit();
}
/* That is the end of my javascript file, it's a lot,
but hopefully you can understand it
*/
Finally, the final php script is simple:
<?php
$fn = $_POST['hdnFirstname'];
$ln = $_POST['hdnLastname'];
$un = $_POST['hdnUsername'];
$em = $_POST['hdnEmail'];
$ph = $_POST['hdnPhone'];
die($fn.",".$ln.",".$un.",".$em.",".$ph);
?>
the firstname, lastname, username, and phone alway print out correctly.
When the email is not edited, it prints out correctly,
When the email is edited, it prints out as null.
This is incorrect, values are parsed as text. Please review the code and make sure that you parse correct form names from http request object. It should fix your issue.
I creating jquery code to generate specific html-blocks that contains html-controls (e.g. textbox, textarea, button) with two buttons - add new block and delete current block:
$(document).ready(function () {
// Constants
var SEPARATOR = "`";
var SEPARATOR_START = "<span class='Hidden'>";
var SEPARATOR_END = "</span>";
var SEPARATOR_BLOCK = SEPARATOR_START + SEPARATOR + SEPARATOR_END;
var CONTAINER = "#weContainer";
// Initialize container
InitializeDataContainer(CONTAINER);
// Buttons events
$(".AddBlock").click(function () {
AddBlock(CONTAINER);
});
$(".DeleteBlock").click(function () {
DeleteBlock(CONTAINER, GetParentId(this));
});
// Functions
function GetParentId(container) {
var id = ($(container).parent().attr("id")).replace(new RegExp("_", 'g'), "");
return id;
}
function Template() {
var uniqueId = Math.random() * 10000000;
var template = "<div class='weBlock' id='_" + uniqueId + "_'>";
template += "<input type='button' value='add' class=\"AddBlock\" />";
template += "<input type='button' value='del' class=\"DeleteBlock\" />";
template += "<br/>";
template += "<input type='text' class='weStartDate weTextbox' />";
template += " ";
template += "<input type='text' class='weEndDate weTextbox' />";
template += "<br/>";
template += "<input type='text' class='weCompany weTextbox' />";
template += " ";
template += "<input type='text' class='weJobTitle weTextbox' />";
template += "<br/>";
template += "<input type='text' class='weClients weTextbox' />";
template += " ";
template += "<input type='text' class='weProjectName weTextbox' />";
template += "<br/>";
template += "<textarea type='text' rows='4' cols='40' class='weProjectDesc weTextarea'></textarea>";
template += "<br/>";
template += "<textarea type='text' rows='6' cols='40' class='weActivities weTextarea'></textarea>";
template += "<br/>";
template += "<textarea type='text' rows='4' cols='40' class='weToolsTech weTextarea'></textarea>";
template += "</div>";
template += SEPARATOR_BLOCK;
return template;
}
function GetIdFromTemplate(template) {
var array = template.split('_');
return array[1];
}
function AddBlock(container) {
$(container).append(Template());
}
function DeleteBlock(container, id) {
var content = $(container).html();
content = content.replace(new RegExp("\<span class='Hidden'\>", "g"), "")
.replace(new RegExp("\</span\>", "g"), "");
var blocks = content.split(SEPARATOR);
content = "";
var index;
for (var i = 0; i < blocks.length; i++) {
if (GetIdFromTemplate(blocks[i]) != id && !IsNullOrEmpty(blocks[i])) {
content += blocks[i] + SEPARATOR_BLOCK;
}
else {
index = i;
}
}
$(container).html(content);
}
function IsNullOrEmpty(string) {
if (string == null || string == 'undefined' || string.length == 0) {
return true;
}
else {
return false;
}
}
function InitializeDataContainer(container) {
$(container).html(Template());
}
});
For the first time (when page load) i created first block:
function InitializeDataContainer(container) {
$(container).html(Template());
}
My problem is next - buttons Add and Delete work only for this first html-block that i created when page load, but if i add new blocks in page using Add button (from this first block that works) then buttons Add and Delete from this new blocks doesn't work!
Sorry for may be not good code, im not javascript engineer:)
Use the .live() instead:
$(".AddBlock").live("click", function () {
AddBlock(CONTAINER);
});
And same for the other class - the .click() is "static" only for the elements that exists in the time of calling it, while .live() should work for any existing or future elements.
Your jQuery code adds event handlers to the Add/Delete buttons you create uses click to do so:
$(".AddBlock").click(function () {
AddBlock(CONTAINER);
});
This only affects HTML elements that are already in the page.
One solution would be to change it to
$(".AddBlock").live('click', function () {
AddBlock(CONTAINER);
});
to make it also work for elements that get added to the page later.
Another solution would be to manually add the click event handlers to any elements you add to the page dynamically:
function AddBlock(container) {
var $template = $(Template());
$(container).append($template);
$template.find(".AddBlock").click, function () {
AddBlock(CONTAINER);
});
$template.find(".DeleteBlock").click, function () {
DeleteBlock(CONTAINER, GetParentId(this));
});
}