Get individual input values from dynamic input fields - javascript

After creating dynamic inputs along with its dynamic id's by append, only the latest generated input field gives values
Other dynamic input fields return empty string
Note: I'm able to get all values of dynamic inputs by using for loop and pushing inside an array, but i also want to get each input individually on key up . But only final input field created gives value
Here is my fiddle,
https://jsfiddle.net/xd8nvktf/3/
Not able to come up with a solution, Help is appreciated
--Thanks
HTML
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<button type = "button" class = "btn btn-primary" id = "addInput">Add Input Fields</button>
<div id = "inputAdder">
</div>
</body>
JS/JQUERY
var a = 0;
var fieldValue;
var dataStored = [];
var valueStored = [];
$("#addInput").on("click", function() {
a += 1;
fieldValue = `#filter-value${a}`;
$("#inputAdder").append(
`<div class = "row" id="appender${a}">
<div class="col-md-4 padderSpace">
<input id="filter-value${a}">
</div>
</div>`
)
dataStored.push({value:fieldValue});
console.log(dataStored)
})
$("#inputAdder").on("keyup",fieldValue,changeFunc);
function changeFunc(){
console.log($(fieldValue).val());
valueStored = [];
for(let i = 0;i<=dataStored.length;i++){
valueStored.push({value:$(dataStored[i].value).val()})
console.log(valueStored)
}
}

You need to pass current textbox id to your changeFunc function.
function changeFunc(e){
console.log($("#" + e.target.id).val());
}
Here is working sample.

Related

How to make the materializecss dropdown work when added dynamically

Following is an example of a sample webform I made in Google Apps Script, where I'm trying to dynamically add three select dropdowns and an input element whenever the add button is clicked. The elements should render in following order -
dropdown dropdown input dropdown.
I'm using materialize framework for this.
After a lot of trying and going through the materializecss documentation, I was able to render the text input field as expected. But, the dropdowns still won't render. Clearly, I'm making some mistake, cannot figure out what and where.
I'm including the code files-
Code.gs
function doGet(e) {
Logger.log(e);
return HtmlService.createTemplateFromFile('form_materialize').evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
form_materialize.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<!-- google font pack link -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Mini materialize.css cdn link -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<?!= include('css_scripts'); ?>
</head>
<body>
<div class="container">
<div class = "row">
<h1>A Sample Form</h1>
</div>
<div id="productsection">
<!-- product details like "Product Type"(dropdown), "Products"(dropdown), "Product Qty"(text input field), "Unit"(dropdown) to be added here dynamically -->
</div>
<div class = "row">
<a class="btn-floating btn-large waves-effect waves-light red" id="addproduct"><i class="material-icons">add</i></a>
</div>
</div>
<!-- Mini materialize.js cdn link -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include('js_scripts_materialize'); ?>
</body>
</html>
js_scripts_materialize.html
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, options);
});
let counter = 0;
const orderTypeList = ["PH", "ECOM"];
const optionList = ["Test Product 1", "Test Product 2", "Test Product 3", "Test Product 4", "Test Product 5"];
const unitOptionList = ["KGS", "PCS", "BAGS"];
document.getElementById("addproduct").addEventListener("click", addInputField);
function addInputField(){
counter++;
// everytime when "add product" button is clicked, the following elements must be added to the "<div id="produc></div>" tag.
// <div class="row">
// <div class="input-field col s4" id="divone">
// <select id="productX">
// <option>option-i</option>
// <option>option-1</option>
// <option>option-2</option>
// ...
// ...
// <option>option-n</option>
// <select>
// </select>
// <div class="input-field col s4" id="divtwo">
// <input id="productqtyX" type="text">
// <label for="productqtyX">Quantity</label>
// </div>
// <div class="input-field col s4" id="divthree">
// <select id="productUnitX">
// <option>option-1</option>
// <option>option-2</option>
// ...
// ...
// <option>option-n</option>
// </select>
// </div>
// </div>
// creates a new div of class row
const newDivElem = createElementTemplate('div', null, ['row']);
// creates a new select tag for order type dropdown
const newOrderTypeSelectElem = createElementTemplate('select', "ordertype" + counter.toString());
// generates the content of the dropdown for products and is inserted to the above "productX" select tag
createOptionsElem(newOrderTypeSelectElem, orderTypeList);
// creates a new select tag for product dropdown
const newProductSelectElem = createElementTemplate('select', "product" + counter.toString());
// generates the content of the dropdown for products and is inserted to the above "productX" select tag
createOptionsElem(newProductSelectElem, optionList);
// creates a input element for quantity input
const newQtyInputElem = createElementTemplate('input', 'productqty' + counter.toString(), ['validate']);
newQtyInputElem.type = 'text';
// creates a label for the quantity input element
const newQtyLabelElem = createElementTemplate('label');
newQtyLabelElem.textContent = "Quantity";
//Creates a new select element for product quantity unit(dropdown)
const newUnitSelectElem = createElementTemplate('select', 'productqtyunit' + counter.toString());
// generates the content of the dropdown for units and is inserted to the above "productqtyunitX" select tag
createOptionsElem(newUnitSelectElem, unitOptionList);
//create inner "div" tags with class "input-field col s4" as described in materializecss documentation
const innerDivElems = [];
for(let i = 0; i < 4; i++){
innerDivElems.push(createElementTemplate('div', `div${(Number(i) + 1)}`, ['input-field', 'col', 's3']));
}
innerDivElems[0].appendChild(newOrderTypeSelectElem);
innerDivElems[1].appendChild(newProductSelectElem);
innerDivElems[2].appendChild(newQtyInputElem);
innerDivElems[2].appendChild(newQtyLabelElem);
innerDivElems[3].appendChild(newUnitSelectElem);
//Inserts select, quantityInput, quanityLabel, newUnitSelectTag tags in div child
for(let i in innerDivElems){
newDivElem.appendChild(innerDivElems[i]);
}
// Finally, appends the newly created div tag to the productSection tag.
document.getElementById('productsection').appendChild(newDivElem);
}
function createOptionsElem(selectElem, optionsArr){
const newDefaultOptionElem = document.createElement('option');
newDefaultOptionElem.disabled = true;
newDefaultOptionElem.setAttribute('selected', true);
newDefaultOptionElem.textContent="Choose your option";
selectElem.appendChild(newDefaultOptionElem);
for(let i in optionsArr){
const newOptionElem = document.createElement('option');
newOptionElem.textContent = optionsArr[i];
newOptionElem.value = optionsArr[i];
// Inserts the option tag in select tag
selectElem.appendChild(newOptionElem);
}
}
// function to create a new element
function createElementTemplate(tagType, idVal, classNameList){
const newElement = document.createElement(tagType);
if(idVal !== undefined)
newElement.id = idVal;
if(classNameList !== undefined){
for(let i in classNameList){
newElement.classList.add(classNameList[i]);
}
}
return newElement;
}
</script>
Although I'm not sure whether I could correctly understand your expected result, how about the following modification?
In this modification, your js_scripts_materialize.html is modified.
Modified script:
I think that in this case, this part might not be required to be used.
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, options);
});
And also, please modify addInputField() as follows.
From:
document.getElementById('productsection').appendChild(newDivElem);
To:
document.getElementById('productsection').appendChild(newDivElem);
var elems = document.querySelectorAll('select'); // Added
M.FormSelect.init(elems); // Added
By this modification, I thought that when you click a red button, you can see the dropdown lists.

How to search page for words and highlight them (JQuery)

I currently have an array of user inputted words and respective highlight colors stored in objects (below is the function that constructs the array upon user button click and input):
//DECLERATIONS////
var placementId = 0;
var searchList = [];
///FUNCTION THAT ADDS A NEW WORD TO SEARCHLIST////////
function addWord(userWord, userColor){ //append new word to find and highlight
var wordAndColorPair = {
word: userWord,
color: userColor,
id: placementId
}
searchList.push(wordAndColorPair);
}
///////BELOW IS THE EVENT THAT ACTUALLY CONSTRUCTS THE ARRAY//////////
$('.color-element').click(function(){ //adding new word-color pairs
var userInput = $('#input-word').val();
if(userInput !== ''){ //only if user enteres text:
var newWord = document.createElement("span"); //create a new search word tile
newWord.classList.add('search-word'); //add the class search-word to it
newWord.textContent = userInput; //make its text value equal to the input
var colorId = $(this).attr('id'); //set its bacckground color to a copy of the button clicked
$(newWord).css("background-color", colorId);
$(newWord).attr('id', placementId); //set this new elements unique ID for delection purposes
$('.display-array').append(newWord); //append the child to the DOM
addWord(userInput, colorId, placementId); //add the word to the search list - increment placementId for future words
placementId ++;
$('#input-word').val(''); //reset the input field
}
else{
return;
}
});
What I am having trouble with is being able to search the whole page and actually highlight the words seen in the array. What I have so far is:
$('.search').click(function(){ //when the search button is clicked
var i;
for(i =0; i< searchList.length; i++){//for each word user inputted:
$("*").contents().each(function() {
var word = searchList[i].word;
var regex = new RegExp('(\\b'+word+'\\b)', 'gi');
if(this.nodeType == 3){ //if text
$(this).html(text.replace(regex, " <span style = 'background-color: " + searchList[i].color + " ;'> " + searchList[i].word + "</span>"));
}
});
}
});
This, however, does not seem to be working, any assistance is much appreciated!
HTML for DOM reference:
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css?family=Changa:700|Roboto+Condensed:700" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type = "text/javascript" src="popup.js"></script>
<meta charset="utf-8">
<title>Word Finder</title>
<link rel="stylesheet" href="style.css" media="screen">
<meta name="description" content="Word Finder Chrome Extension">
<meta name="author" content="Aalok Borkar">
</head>
<body>
<p>
this is a test of the funcitonality TEXT text text text hello
</p>
<div class = "input">
<div class = "word">
Word <input type = "text" id = 'input-word' placeholder= "Jim Halpert"></input>
</div>
<div class = "color-palette">
<!-- on click: clear text input, add color, append search array / display array -->
<button class = "color-element" id = "red"></button>
<button class = "color-element" id = "orange"></button>
<button class = "color-element" id = "yellow"></button>
<button class = "color-element" id = "green"></button>
<button class = "color-element" id = "blue"></button>
<button class = "color-element" id = "violet"></button>
<button class = "color-element" id = "pink"></button>
</div>
</div>
<div class = "display">
<p> Words to Search</p>
<div class = "display-array">
</div>
</div>
<button class = "search">Search</button>
</body>
</html>
It need to be done that way:
$(this).parent().html($(this).parent().html().replace($(this).text(),$(this).text().replace(regex, " <span style = 'background-color: " + searchList[i].color + " ;'>" + searchList[i].word + "</span> ")));
This is because when you change the innerHTML directly you will mess the dom structure and lose the html format, when you change the text solely you would have a a sanitized DOM inside quotes, so it should be solved one way by modifying the text part inside the inner html.
see it here
I added a class to your <p> element, but you probably don't have to do that. I just did it for ease of access on my part. The biggest thing, if I understood your question right, was your search function. IMO, you need to look at each word and compare it to the search array. Find the word that matches and wrap it in something that you can apply a style to. In my case, I chose a <span> tag. Fiddle below code.
// HTML Modification
<p class="searchable">
this is a test of the functionality TEXT text text text hello
</p>
$('.search').click(function() { //when the search button is clicked
var original = $('.searchable').html().trim();
var searchable = original.split(" ");
for (var i = 0; i < searchList.length; i++) { //for each word user
inputted:
for (var s = 0; s < searchable.length; s++) {
if (searchable[s] == searchList[i].word) {
searchable[s] = "<span style='background:" + searchList[i].color +
";'>" + searchList[i].word + "</span>";
}
}
}
rewrite(searchable); //SEE BELOW
});
// This iterates over the searchable array
function rewrite(searchable) {
var highlighted = "";
for (var i = 0; i < searchable.length; i++) {
highlighted += searchable[i] + " ";
}
$('.searchable').html(highlighted.trim());
}
https://jsfiddle.net/5v3aqrzd/

How to get html element runtime code to make generic copies? Like copy textbox with text entered into it

I want to be able to copy elements with keeping everything that user entered, modified and etc.
I don't want to parse every elem like manually set value for textboxes, manually set checked for radiobuttons and etc, I need some generic way.
Is this possible?
This is what I have as example:
<html>
<head>
<title>asd</title>
<script type = "text/javascript">
function copyElement(elem_id, to_elem_id)
{
var elem = document.getElementById(elem_id);
var container = document.getElementById(to_elem_id);
if (!elem || !container)
return;
container.innerHTML = elem.outerHTML;
}
</script>
</head>
<body>
<input type = "text" id = "test_txt" />
<input type = "button" value = "copy textbox" onclick = "copyElement('test_txt', 'for_elem_paste')" />
<span id = 'for_elem_paste'></span>
</body>
</html>
I want that copied textbox to appear with text entered in original textbox.
But this not about textboxes, I need to copy any elements. I though that innerHTML and outerHTML keep things that modified by user :/
You can clone it
function copyElement(elem_id, to_elem_id) {
var elem = document.getElementById(elem_id);
var container = document.getElementById(to_elem_id);
if (elem && container) {
var clone = elem.cloneNode(true);
clone.id = "some other id to prevent id duplication";
container.appendChild(clone);
}
else return false;
}

Input entry is not catched in Javascript

I tried to build an application in which , there is one HTML page from which I get single input entry by using Submit button, and stores in the container(data structure) and dynamically show that list i.e., list of strings, on the same page
means whenever I click submit button, that entry will automatically
append on the existing list on the same page.
But in this task, firstly I try to catch that input in javascript file, and I am failing in the same. Can you tell me for this, which command will I use ?
Till now my work is :-
HTML FILE :-
<html>
<head>
<script type = "text/javascript" src = "operation_q_2.js"></script>
</head>
<body>
Enter String : <input type= "text" name = "name" id = "name_id"/>
<button type="button" onClick = "addString(this.input)">Submit</button>
</body>
</html>
JAVASCRIPT FILE:-
function addString(x) {
var val = x.name.value;
//var s = document.getElementById("name_id").getElementValue;//x.name.value;
alert(val);
}
EDITED
My New JAVASCRIPT FILE IS :-
var input = [];
function addString(x) {
var s = document.getElementById("name_id").value;//x.name.value;
input.push(input);
var size = input.length;
//alert(size);
printArray(size);
}
function printArray(size){
var div = document.createElement('div');
for (var i = 0 ; i < size; ++i) {
div.innerHTML += input[i] + "<br />";
}
document.body.appendChild(div);
//alert(size);
}
Here it stores the strings in the string, but unable to show on the web page.
See this fiddle: http://jsfiddle.net/MjyRt/
Javascript was almost right
function addString(x) {
var s = document.getElementById("name_id").value;//x.name.value;
alert(s);
}
Try to use jQuery (simpler)
function addString() {
var s = $('#name_id').val();//value of input;
$('#list').append(s+"<br/>");//list with entries
}
<div id='list'>
</div>

storing user input in array

I need to do the following (I'm a beginner in programming so please excuse me for my ignorance): I have to ask the user for three different pieces of information on three different text boxes on a form. Then the user has a button called "enter"and when he clicks on it the texts he entered on the three fields should be stored on three different arrays, at this stage I also want to see the user's input to check data is actually being stored in the array. I have beem trying unsuccessfully to get the application to store or show the data on just one of the arrays. I have 2 files: film.html and functions.js. Here's the code. Any help will be greatly appreciated!
<html>
<head>
<title>Film info</title>
<script src="jQuery.js" type="text/javascript"></script>
<script src="functions.js" type="text/javascript"></script>
</head>
<body>
<div id="form">
<h1><b>Please enter data</b></h1>
<hr size="3"/>
<br>
<label for="title">Title</label> <input id="title" type="text" >
<br>
<label for="name">Actor</label><input id="name" type="text">
<br>
<label for="tickets">tickets</label><input id="tickets" type="text">
<br>
<br>
<input type="button" value="Save" onclick="insert(this.form.title.value)">
<input type="button" value="Show data" onclick="show()"> <br>
<h2><b>Data:</b></h2>
<hr>
</div>
<div id= "display">
</div>
</body>
</html>
var title=new Array();
var name=new Array();
var tickets=new Array();
function insert(val){
title[title.length]=val;
}
function show() {
var string="<b>All Elements of the Array :</b><br>";
for(i = 0; i < title.length; i++) {
string =string+title[i]+"<br>";
}
if(title.length > 0)
document.getElementById('myDiv').innerHTML = string;
}
You're not actually going out after the values. You would need to gather them like this:
var title = document.getElementById("title").value;
var name = document.getElementById("name").value;
var tickets = document.getElementById("tickets").value;
You could put all of these in one array:
var myArray = [ title, name, tickets ];
Or many arrays:
var titleArr = [ title ];
var nameArr = [ name ];
var ticketsArr = [ tickets ];
Or, if the arrays already exist, you can use their .push() method to push new values onto it:
var titleArr = [];
function addTitle ( title ) {
titleArr.push( title );
console.log( "Titles: " + titleArr.join(", ") );
}
Your save button doesn't work because you refer to this.form, however you don't have a form on the page. In order for this to work you would need to have <form> tags wrapping your fields:
I've made several corrections, and placed the changes on jsbin: http://jsbin.com/ufanep/2/edit
The new form follows:
<form>
<h1>Please enter data</h1>
<input id="title" type="text" />
<input id="name" type="text" />
<input id="tickets" type="text" />
<input type="button" value="Save" onclick="insert()" />
<input type="button" value="Show data" onclick="show()" />
</form>
<div id="display"></div>
There is still some room for improvement, such as removing the onclick attributes (those bindings should be done via JavaScript, but that's beyond the scope of this question).
I've also made some changes to your JavaScript. I start by creating three empty arrays:
var titles = [];
var names = [];
var tickets = [];
Now that we have these, we'll need references to our input fields.
var titleInput = document.getElementById("title");
var nameInput = document.getElementById("name");
var ticketInput = document.getElementById("tickets");
I'm also getting a reference to our message display box.
var messageBox = document.getElementById("display");
The insert() function uses the references to each input field to get their value. It then uses the push() method on the respective arrays to put the current value into the array.
Once it's done, it cals the clearAndShow() function which is responsible for clearing these fields (making them ready for the next round of input), and showing the combined results of the three arrays.
function insert ( ) {
titles.push( titleInput.value );
names.push( nameInput.value );
tickets.push( ticketInput.value );
clearAndShow();
}
This function, as previously stated, starts by setting the .value property of each input to an empty string. It then clears out the .innerHTML of our message box. Lastly, it calls the join() method on all of our arrays to convert their values into a comma-separated list of values. This resulting string is then passed into the message box.
function clearAndShow () {
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
messageBox.innerHTML = "";
messageBox.innerHTML += "Titles: " + titles.join(", ") + "<br/>";
messageBox.innerHTML += "Names: " + names.join(", ") + "<br/>";
messageBox.innerHTML += "Tickets: " + tickets.join(", ");
}
The final result can be used online at http://jsbin.com/ufanep/2/edit
You have at least these 3 issues:
you are not getting the element's value properly
The div that you are trying to use to display whether the values have been saved or not has id display yet in your javascript you attempt to get element myDiv which is not even defined in your markup.
Never name variables with reserved keywords in javascript. using "string" as a variable name is NOT a good thing to do on most of the languages I can think of. I renamed your string variable to "content" instead. See below.
You can save all three values at once by doing:
var title=new Array();
var names=new Array();//renamed to names -added an S-
//to avoid conflicts with the input named "name"
var tickets=new Array();
function insert(){
var titleValue = document.getElementById('title').value;
var actorValue = document.getElementById('name').value;
var ticketsValue = document.getElementById('tickets').value;
title[title.length]=titleValue;
names[names.length]=actorValue;
tickets[tickets.length]=ticketsValue;
}
And then change the show function to:
function show() {
var content="<b>All Elements of the Arrays :</b><br>";
for(var i = 0; i < title.length; i++) {
content +=title[i]+"<br>";
}
for(var i = 0; i < names.length; i++) {
content +=names[i]+"<br>";
}
for(var i = 0; i < tickets.length; i++) {
content +=tickets[i]+"<br>";
}
document.getElementById('display').innerHTML = content; //note that I changed
//to 'display' because that's
//what you have in your markup
}
Here's a jsfiddle for you to play around.

Categories

Resources