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);
Related
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!
I have table that is created that shows each item added to the array. In the last row of each column is an action field that lets you either edit or delete from the row. I am not sure how I am supposed to accomplish this. What I have so far does not work properly.
function del(item) {
participantList.splice(item,1);
displayLIst();
}
function addInfo() {
var fname = document.getElementById("fname").value;
var lname = document.getElementById("lname").value;
var email = document.getElementById("email").value;
if(fname !='' && lname !="" && email !='') {
participantList[count] = new Object();
participantList[count].Fname = fname;
participantList[count].Lname = lname;
participantList[count].Email = email;
participantList[count].Action = "<button onclick='del("+count+")'>Delete</button>" + "<button onclick='edit("+count+")'>Edit</button>";
count++;
document.getElementById("fname").value ="";
document.getElementById("lname").value = "";
document.getElementById("email").value = "";
}
displayList();
}
I want to delete every object from the specified row in the array.
How are you getting the elements and putting them into the participant list?
Do you have references to the elements? Can you include the HTML as well and all the related code to what you want to do?
Below is how I would get all of the elements, and remove one.
You can remove an element by calling .remove() on it
Here is my example code: http://jsfiddle.net/gabs00/cxt170re/
var listItems = document.querySelectorAll('li');
var item = listItems[1];
item.remove();
querySelectorAll creates a live node list
I grab one of those elements (index 1) and delete it with Element.remove();
Check out the fiddle to see it in action.
Here is a current working version:
var participantList = [];
var edit = function(item) {};
var del = function(item) {
participantList.splice(item,1);
displayList();
};
function addInfo() {
var fname = document.getElementById("fname").value;
var lname = document.getElementById("lname").value;
var email = document.getElementById("email").value;
var count = participantList.length;
if(fname !='' && lname !="" && email !='') {
var item = {};
item.Fname = fname;
item.Lname = lname;
item.Email = email;
item.Action = "<button onclick='del("+count+")'>Delete</button><button onclick='edit("+count+")' disabled>Edit</button>";
participantList.push(item);
document.getElementById("fname").value ="";
document.getElementById("lname").value = "";
document.getElementById("email").value = "";
}
displayList();
};
var displayList = function () {
// clean previous data
console.log(participantList);
document.getElementById("results").innerHTML = "";
var content = "";
for(var i = 0; i<participantList.length; i++) {
content += "<tr>";
content += "<td>" + participantList[i].Fname + "</td>";
content += "<td>" + participantList[i].Lname + "</td>";
content += "<td>" + participantList[i].Email + "</td>";
content += "<td>" + participantList[i].Action + "</td>";
content += "</tr>"
}
document.getElementById("results").innerHTML = "<table>" + content + " </table>";
};
With the following HTML Code:
<input type="text" id="fname" />
<input type="text" id="lname" />
<input type="text" id="email" />
<button onclick="addInfo()">
Add
</button>
<div id="results">
EDIT: Missing JSFiddle link: https://jsfiddle.net/d64314uk/
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.
Ok here's what I am doing. Based on some dropdown value I am craeting another dropdown value.
Is it possible to display that dropdown in some specific area as I wish based on my existing code.
if (SelectedIndex == 2 || SelectedIndex == 5 || SelectedIndex == 7) {
$("#DomContainer").remove();
var MainContainer = document.createElement("Div");
MainContainer.id = "DomContainer";
$("body").append(MainContainer);
var Options = new Array();
for(var i=1;i<=28;i++){
Options.push(i);
}
AddDropDown(Options);
}
function AddDropDown(Options) {
var selectHTML = "<label>Day:</label> ";
selectHTML += "<select>";
for (i = 0; i < Options.length; i = i + 1) {
selectHTML += "<option value='" + Options[i] + "'>" + Options[i] + "</option>";
}
selectHTML += "</select>";
document.getElementById("DomContainer").innerHTML = selectHTML;
}
For example <div id="new_drop">//Display the drop down here </div>
Simply add a second parameter to AddDropDown for passing the ID of the container to which you want to insert your dropdown list:
function AddDropDown(Options, containerId) {
...
document.getElementById(containerId).innerHTML = selectHTML;
Then call it like this:
AddDropDown(Options, "new_drop");
(if I understand you correctly)
No need to remove and append elements from the DOM, just replace the existing element contents ... here's a simplified version.
// if "SelectedIndex" is one of the values in the array provided
if ($.inArray(SelectedIndex, [2,5,7])) {
$("#DomContainer").html("<label>Day:</label> "+inject_dropdown(28));
}
// Creates and returns a new drop-down based on the "length" provided
function inject_dropdown(length){
var selectHTML = "<select>";
for( i=1; i<=length; i++ ){
selectHTML += "<option value='" + i + "'>" + i + "</option>"
}
selectHTML += "</select>"
return selectHTML;
}
Replace the $('#DomContainer') selector with whatever selector identifies the place you want the new drop-down to appear.
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));
});
}