I have the following code for generating checkboxes in a Google Docs sidebar:
for( var i = 0;i < values.length; i ++)
{
var cb = document.createElement( "input" );
cb.type = "checkbox";
cb.id = values[i][1];
cb.value = values[i][0];
var text = document.createTextNode( values[i][0].substring(0, 30) );
var br = document.createElement('br');
document.getElementById( 'class_list' ).appendChild( cb );
document.getElementById( 'class_list' ).appendChild( text );
document.getElementById( 'class_list' ).appendChild( br );
}
Is there a way to include a check all box at the top of this list and then pass all of the selected values and ids to another function?
Here is the HTML and client side JavaScript that will do what you want:
<div class="inputFormElement"><!-- Beginning of input -->
<button onmouseup="checkAllBoxes()">Select All</button>
<br>
<br>
<div class="chkBoxListElement">
<input type="checkbox" id="idOne" value="1">One<br>
<input type="checkbox" id="idTwo" value="2">Two<br>
<input type="checkbox" id="idThree" value="3">Three<br>
<input type="checkbox" id="idFour" value="4">Four<br>
<input type="checkbox" id="idFive" value="5">Five<br>
<input type="checkbox" id="idSix" value="6">Six<br>
</div>
</div><!-- End of input -->
<script>
window.checkAllBoxes = function() {
var allCheckBoxes,dataAsString,elementHoldingChkBoxes,i,L,objectOfData,thisChkBox,thisID;
objectOfData = {};
elementHoldingChkBoxes = document.getElementsByClassName('chkBoxListElement')[0];
console.log('elementHoldingChkBoxes: ' + elementHoldingChkBoxes)
console.log('typeof elementHoldingChkBoxes: ' + typeof elementHoldingChkBoxes)
allCheckBoxes = elementHoldingChkBoxes.getElementsByTagName('input');//Get all inputs
L = allCheckBoxes.length;
for (i=0;i<L;i++) {
thisChkBox = allCheckBoxes[i];//Get this check box
if (thisChkBox) {//Not null, undefined or empty string - truthy
thisChkBox.checked = true;
thisID = thisChkBox.id;
objectOfData[thisID] = thisChkBox.value;
}
}
dataAsString = JSON.stringify(objectOfData);//Convert object to a string
console.log('dataAsString: ' + dataAsString)
mySecondFunction(objectOfData);
}
window.mySecondFunction = function(data) {
console.log(data)
}
</script>
If you want the input boxes to dynamically change whenever the sidebar is loaded, some code will be needed to build the HTML. But that is another question.
Related
I have A Form in HTML. Here's my Code:
<div id="format">
<form id="myForm" onsubmit="myForm(event)">
<b>Name:</b></br>
<input type="text" name="name" id="name" required="required" ></input></br>
<b>Phone Number:</b></br>
<input type="phone" name="phone" id="phone" required="required" ></input></br>
<b>Birthday:</b></br>
<input type="date" name="bday" id="bday" required="required" ></input></br>
<b>Email:</b></br>
<input type="email" name="email" id="email" required="required" ></input></br>
<b>Password:</b></br>
<input type="password" name="pWord" id="pWord" required" ></input></br>
<button type="submit" name="submit" id="submit" value="Submit" onsubmit="myData()" >Submit</button>
</form>
<div id="sample"></div>
</div>
Here's my Javascript code. In this code, when I trigger the submitted button from html, it will display the info of the user and append a div for each submitted info of the users.
var data = [];
var i, item;
function myForm(event){
event.preventDefault();
var name = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
var bday = document.getElementById("bday").value;
var email = document.getElementById("email").value;
var pWord = document.getElementById("pWord").value;
var age = document.getElementById("bday").value;
var ageValue;
var Bdate = document.getElementById("bday").value;
var Bday = +new Date(Bdate);
ageValue = ~~ ((Date.now() - Bday) / (31557600000));
var theBday = document.getElementById("age");
theBday.innerHTML = ageValue;
var userObject = {
name: name,
phone: phone,
bday: bday,
email: email,
pWord: pWord,
ageValue: ageValue,
};
data.push(userObject);
document.getElementById("sample").innerHTML = ""; //Prevents duplicate
for (var i=0 ; i <data.length ; i++){
var theDiv ;
var container ;
var button;
theDiv = document.createElement( "div" );
button = document.createElement( "button");
button.setAttribute("id", "remove");
button.remove(sample);
theDiv.style = "background-color:pink; border-style:solid; margin:1%;";
for (item in data[i]) {
var x = item + ":" + data[i][item] + "</br>" ;
theDiv.innerHTML += item + ":" + data[i][item] + "</br>" ;
}
button.innerHTML += "Remove";
button.style = "background-color:maroon; color:white;";
container = document.getElementById( "sample" );
container.appendChild( theDiv );
theDiv.appendChild (button);
}
console.log(data);
}
I want to to create a button for each appended div. The button will have the function of removing the entire div where the button belong.
A reasonably simple algorithm to correctly remove objects from the list is to provide a data- attribute value on each remove botton that gives its original index in the data array. (The attribute name used below is data-index).
Then take the inline code that adds objects and turn it into three functions to
(re-)draw all objects held in the data array.
add a single object to data and redraw all objects.
remove an object from the data array (coded as a remove button onclick handler) and redraw all objects.
The code already redraws all object when adding a new object is added, so redrawing everything when removing an object keeps it on the same level of simplicity.
Example code for simplified form:
"use strict";
var data = [];
function myFormData(event){
// halper functions
function addData( userObject) {
data.push(userObject);
redrawList();
}
function removeData( event) {
var index = this.getAttribute("data-index");
data.splice( index,1);
redrawList();
}
function redrawList() {
var container = document.getElementById( "sample" );
container.innerHTML = ""; // reset list displayed on page
for (var index=0 ; index <data.length ; index++){
var theDiv = document.createElement( "div" );
var divHTML = "";
var button = document.createElement( "button");
var userObject = data[index];
for( var item in userObject) {
if( !userObject.hasOwnProperty( item)) {
continue; // ignore inherited properties
}
divHTML += item + ":" + userObject[item] + "</br>" ;
}
theDiv.innerHTML = divHTML;
theDiv.style = "background-color:pink; border-style:solid; margin:1%;";
button.type="button";
button.setAttribute("data-index", index);
button.innerHTML = "remove";
button.style = "background-color:maroon; color:white;";
button.onclick=removeData;
theDiv.appendChild (button);
container.appendChild( theDiv );
}
}
// handle form submit event to add an event
event.preventDefault();
// cut down form:
var name = document.getElementById("name").value;
var userObject = {
name: name
};
addData( userObject);
// console.log(data); // not used in code example
}
<div id="format">
<form id="myForm" onsubmit="myFormData(event);">
<b>Name:</b></br>
<input type="text" name="name" id="name" required="required" ></input></br>
<button type="submit" name="submit" id="submit" value="Submit"
onsubmit="myFormData(event)" >Submit</button>
</form>
<div id="sample">
</div>
</div>
Note the code uses getAttribute("data-index") in case target browser support for element.dataset is unknown or absent. Function names myForm and myData were changed to myFormData as I presume they are the same function.
Probable issue: the existing code comment that clearing the sample list prevents duplicates is wrong. In the example code, clicking the submit button multiple times adds the same user. You could add a test to check for duplicate email addresses when adding a user to the list, but such code is outside the scope of this question. You may also wish to consider resetting the form after adding data to the "sample" list.
check the fiddler, i have implemented with a single value 'name'.
var data = [];
var i, item;
function myForm(event){
event.preventDefault();
var name = document.getElementById("name").value;
var userObject = {
name: name
};
data.push(userObject);
document.getElementById("sample").innerHTML = ""; //Prevents duplicate
for (var i=0 ; i <data.length ; i++){
var theDiv ;
var container ;
var button;
var index;
theDiv = document.createElement( "div" );
button = document.createElement( "button");
index = document.createElement("input");
index.setAttribute('hidden', 'true');
button.setAttribute("id", "remove");
button.setAttribute("onclick", "removeItem(this)");
for (item in data[i]) {
var x = item + ":" + data[i][item] + "</br>" ;
theDiv.innerHTML += item + ":" + data[i][item] + "</br>" ;
index.value += i;
}
button.innerHTML += "Remove";
container = document.getElementById( "sample" );
container.appendChild( theDiv );
theDiv.appendChild (button);
theDiv.appendChild(index);
}
}
function removeItem(event){
let el = event;
let index = el.parentNode.lastElementChild.value;
el.parentElement.remove();
data.splice(index,1);
}
<div id="format">
<form id="myForm" onsubmit="myForm(event)">
<b>Name:</b>
<input type="text" name="name" id="name" required="required" >
<button type="submit" name="submit" id="submit" value="Submit" onsubmit="myData()" >Submit</button>
</form>
<div id="sample"></div>
</div>
I have made a script that produces a form in a Google spreadsheet, takes its input values and appends them to the current sheet. All this works perfectly fine until I try and access the input values that have variable names.
I'm currently focusing on trying to get the inputs entered into the "Price" fields of which i are created with names "vPrice" + (i + 1) where i is the number entered previously in "Number of Variations" numVar.
In varItemAdd() I can access the values individually (vPrice1, vPrice2 etc.) and they produce the correct values. I can also access the numVar value but when I try to incrementally adjust the vPrice variable to produce each value on the spreadsheet it comes up as 'undefined'.
Script:
function varItemAdd(form) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var number = form.numVar;
var attribNumber = form.numAttr;
sheet.appendRow([form.manufacturer, number, attribNumber]);
for (i=0;i<number;i++) {
var vPrice = "vPrice" + (i + 1);
var vPriceInput = form.vPrice;
sheet.appendRow([vPriceInput, number, attribNumber]);
}
return true;
}
HTML
<body>
<form>
<!-- Select Number of Attributes to appear -->
<h2 class="title">Number of Attributes:</h2>
<input class="input-box" type="number" min="1" max="5" id="numAttr" name="numAttr" value="1"><br/>
<!-- Select Number of Variations to appear -->
<h2 class="title">Number of Variations:</h2>
<input class="input-box" type="number" id="numVar" name="numVar" value="1"><br/>
<h3 class="buttons" id="submit" onclick="addFields()">ADD</h3>
<div id="attBoxes"></div>
<div id="varBoxes"></div>
<br>
<input class="buttons" id="submit" type="button" value="SUBMIT"
onclick="google.script.run
//.withSuccessHandler(google.script.host.close)
.varItemAdd(this.parentNode)" />
<input class="buttons" id="reset" type="reset" value="RESET">
</form>
</body>
<script type='text/javascript'>
function addFields(){
// Get number of variation inputs to create
var number = document.getElementById("numVar").value;
// Get number of attribute inputs to create
var attribNumber = document.getElementById("numAttr").value;
// Get container <div>s where dynamic content will be placed
var varBoxes = document.getElementById("varBoxes");
var attBoxes = document.getElementById("attBoxes");
// Clear previous contents of the container
while (varBoxes.hasChildNodes()) {
varBoxes.removeChild(varBoxes.lastChild);
}
while (attBoxes.hasChildNodes()) {
attBoxes.removeChild(attBoxes.lastChild);
}
attBoxes.appendChild(document.createTextNode("Attribute Name(s)"));
// For each attribute append an input box inside each variation
for (k=0;k<attribNumber;k++){
var attTitle = attBoxes.appendChild(document.createElement("h2"));
var attInput = attBoxes.appendChild(document.createElement("input"));
attTitle.textContent = "Attribute " + (k + 1);
attInput.type = "text";
attInput.name = "v-att" + (k + 1);
attBoxes.appendChild(document.createElement("br"));
};
attBoxes.appendChild(document.createElement("br"));
// For each variation create inputs
for (i=0;i<number;i++){
varBoxes.appendChild(document.createTextNode("Variation " + (i+1)));
// Set variables
var skuTitle = varBoxes.appendChild(document.createElement("h2"));
var skuInput = document.createElement("input");
var priceTitle = varBoxes.appendChild(document.createElement("h2"));
var priceInput = document.createElement("input");
var attributes = varBoxes.appendChild(document.createElement("div"));
attributes.id = "varAttribs";
var varAttribs = document.getElementById("varAttribs");
// Set element values
skuTitle.textContent = "SKU";
skuInput.type = "text";
skuInput.name = "vSku";
priceTitle.textContent = "Price";
priceInput.type = "number";
priceInput.id = "vPrice" + (i + 1);
priceInput.name = "vPrice" + (i + 1);
// Call elements
varBoxes.appendChild(skuTitle);
varBoxes.appendChild(skuInput);
varBoxes.appendChild(document.createElement("br"));
varBoxes.appendChild(priceTitle);
varBoxes.appendChild(priceInput);
varBoxes.appendChild(document.createElement("br"));
for (j=0;j<attribNumber;j++){
var aValueTitle = varAttribs.appendChild(document.createElement("h2"));
var aValueInput = document.createElement("input");
aValueTitle.textContent = "Attribute " + (j + 1) + " Value";
aValueTitle.className = "title";
aValueInput.type = "text";
aValueInput.className = "input-box";
aValueInput.name = "a-value-" + (j + 1);
varBoxes.appendChild(aValueTitle);
varBoxes.appendChild(aValueInput);
varBoxes.appendChild(document.createElement("br"));
};
varBoxes.appendChild(document.createElement("br"));
varBoxes.appendChild(document.createElement("br"));
}
}
</script>
Just replace the below line in script then you should be able to access the value of each price element.
From:
var vPriceInput = form.vPrice;
To:
var vPriceInput = form[vPrice];
I tried using document.createElement, which works fine to add textbox but I can't increment ID name.
I am using it in a metro app.
function textBox(noOfInputTag){
noOfInputTag = noOfInputTag*1; // Convert to Number
//noOfInputTag is used to get total textbox you want to create
for(var i = 0; i <= noOfInputTag; i++){
var textbox = document.createElement('input');
textbox.type = 'text';`enter code here`
textbox.id = 'textBox_' + i; // As number of textbox increases id get incremented
document.body.appendChild(textbox);
}
}
textBox(2);
<form>
No. of lines:
<input type="text" id="number" value="0"/>
<br/>
<input type="button" id="button" value="Add Line" />
</form>
<div>
<ol id="linedata">
</ol>
</div>
document.getElementById('button').addEventListener("click", incrementValue);
function incrementValue() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('number').value = value;
var list = document.createElement('li');
var box = document.createElement('input');
box.type = 'text';
box.id = 'line' + value;
box.placeholder='Line ' + value;
list.appendChild(box);
document.getElementById("linedata").appendChild(list);
}
I have a requirement in which I had to add a duplicate of the existing fieldset in a form. I'm able to achieve the cloning process successfully. But I'm not able to change the name and id of the filedset elements. It is the same as the first fieldset but I want it to be with a different name and id to differentiate it(even adding a number at the end would be fine). Below are my js and fieldset.
<div id="placeholder">
<div id="template">
<fieldset id="fieldset">
<legend id="legend">Professional development</legend>
<p>Item <input type ="text" size="25" name="prof_itemDYNID" id ="prof_item_id"/><br /></p>
<p>Duration <input type ="text" size="25" name="prof_durationDYNID" id="prof_duration_id" /><br /></p>
<p>Enlargement <label for="enlargement"></label><p></p>
<textarea name="textareaDYNID" cols="71" rows="5" id="prof_enlargement">
</textarea></p>
<p><input type="button" value="Add new item" id="add_prof" onclick="Add();" /></p>
</fieldset>
</div>
</div>
function Add() {
var oClone = document.getElementById("template").cloneNode(true);
document.getElementById("placeholder").appendChild(oClone);
}
Also, this is just a sample fieldset and it will be different as well. I heard that this can be done using regex but not sure how to do it. Please help.
Not sure this could be achieve using regex, but somewhat following code should work...
var copyNode = original.cloneNode(true);
copyNode.setAttribute("id", modify(original.getAttribute("id")));
document.body.appendChild(el);
Here comes the best(as per my assumption) answer to the above problem..
function addMe(a){
var original = a.parentNode;
while (original.nodeName.toLowerCase() != 'fieldset')
{
original = original.parentNode;
}
var duplicate = original.cloneNode(true);
var changeID= duplicate.id;
var counter = parseInt(changeID.charAt(changeID.length-1));
++counter;
var afterchangeID = changeID.substring(0,changeID.length-1);
var newID=afterchangeID + counter;
duplicate.id = newID;
var tagNames = ['label', 'input', 'select', 'textarea'];
for (var i in tagNames)
{
var nameChange = duplicate.getElementsByTagName(tagNames[i]);
for (var j = 0; j < nameChange.length; j++)
{if (nameChange[j].type != 'hidden'){
var elementName = nameChange[j].name;
var afterSplitName = elementName.substring(0,elementName.length-1);
nameChange[j].name = afterSplitName + counter;
var elementId = nameChange[j].id;
var afterSplitId = elementId.substring(0,elementId.length-1);
nameChange[j].id = afterSplitId + counter;
}
}
}
insertAfter(duplicate, original);
}
function insertAfter(newElement, targetElement)
{
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement)
{
parent.appendChild(newElement);
}
else
{
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
i am trying to create a bit of javascript that will create a new text field every time a button is pressed, any help would be appreciated, it seems like the javascript doesn't want to run more than once
<!DOCTYPE html>
<html>
<head>
<title>Q&A Admin Panel</title>
</head>
<body>
<h1>Q&A Admin Panel</h1>
<form action="add_question.php" method="post">
Question Type: <input type="text" id="questionType" />
Question Name: <input type="text" id="questionName" />
Question Text: <input type="text" id="questionText" />
<select id="myList" onchange="selectType()">
<option>Yes or No</option>
<option>Multiple Choice</option>
<option>Multiple Select</option>
<option>Open Response</option>
</select>
<div id='buttons'> </div>
</form>
<script type="text/javascript">
function selectType()
{
var type=document.getElementById("myList");
if(type == "Multiple Choice" or type == "Multiple Select"){
// add answer = visible
}
}
</script>
<script type="text/javascript">
var answers = 0;
function addAnswer()
{
write = document.getElementById('buttons');
write.innerHTML = write.innerHMTL + "add answer: <input type=\"text\" id=\"answer" + answers + "\" <br>";
answers = answers + 1;
}
</script>
<button onclick="addAnswer(); return false;">add answer</button>
</body>
</html>
var answers = 0,
write = document.getElementById('buttons');
function addAnswer() {
write.innerHTML += 'Add answer: <input type="text" id="answer"' + answers + '/> <br />';
answers++;
}
I faced the same problem in my college project. You can also accomplish your work as David suggested, but using innerHTML doesn't add elements to DOM and as a result, when you'll refresh the page, text fields will disappear. So for getting persistent text fields, you can use the code mentioned below:
var i = 0;
function addMore()
{
var x = document.getElementById('buttons');
var input1 = document.createElement("input");
input1.setAttribute("type","text");
input1.setAttribute("name","i" + i );
x.appendChild( input1 );
i++;
}
You can use firebug for debugging javascript things.
Thanks.
function addTextField(id){
var colors = new Array('#660000','#33ff00','#0066ff','#cc3399','#9966ff');
var container = document.getElementById(id);
var ulElement = document.createElement('ul');
container.appendChild(ulElement);
var hideLink = function(){
var firstElement = ulElement.firstChild.getElementsByTagName('a')[0];
firstElement.style.display = (ulElement.childNodes.length==1)?'none':'inline';
for(var i = 0 ; i <ulElement.childNodes.length; i++)
ulElement.childNodes[i].style.color = colors[i%5];
}
var addListElement = function(){
var liElement = document.createElement('li');
ulElement.appendChild(liElement);
var textElement = document.createElement('input');
textElement.setAttribute('type','text');
liElement.appendChild(textElement);
var deleteLink = document.createElement('a');
deleteLink.href = "#";
deleteLink.appendChild(document.createTextNode('delete'));
liElement.appendChild(deleteLink);
deleteLink.onclick = function(){
ulElement.removeChild(liElement);
hideLink();
}
hideLink();
}
addListElement();
var anchorElement = document.createElement('a');
anchorElement.href = "#";
anchorElement.appendChild(document.createTextNode('Add more'));
container.appendChild(anchorElement);
anchorElement.onclick = addListElement;
hideLink();
}
Here is the Demo
http://jsfiddle.net/mannejkumar/cjpS2/