JavaScript- dynamically adding input to a page - javascript

i am using JavaScript to add a div on the fly. The div should contain a form input whose 'name' attribute WILL changes in value incrementally.
I have managed to do this- I however have two problems.
First Problem:
The first div that i created is cancelled out by the next dynamically created div.
thus, when i submit the form, the first dynamically created imput form is blank-
but subsequent ones have values on them.
MY CODE :
html
<div id="dynamicDivSection"></div>
<button id="addbutton">add box</button>
<div id="boxes">
<div class="box">
<input type="text" id='dynamic-imput' name="">
</div>
</div>
javascript
var addbutton = document.getElementById("addbutton");
var key = 1;
addbutton.addEventListener("click", function() {
key++;
document.getElementById('dynamic-imput').name = 'ser['+key+'][\'name\']';
var boxes = document.getElementById("boxes");
var head = document.getElementById("dynamicDivSection");
var clone = boxes.firstElementChild.cloneNode(true);
head.appendChild(clone);
});
i suspect that the problem is causing by this:
document.getElementById('dynamic-imput').name =
'ser['+key+'][\'name\']';
i.e when i create the dynamic div it creates several inputs on the page that contain the same Id. if i am correct, then perhaps teh solution is to change the Id of the newly created imput - however, i am not sure how to change the Id of a dynamically created Imput.
Second problem.
i want each dynamically created div to go to the top of the page; i.e to be placed before the earlier created dynamic div- however, at the moment each dynamically created div go directly under the first dynamically created div.

You can insert as the first child with:
parent.insertAdjacentElement('afterbegin', nodeToInsert);
You can get and set attributes such as id with setAttribute and getAttribute. Though I'm not sure why you even need an ID here, it would be simpler not to have one and select the element with a class.
var addbutton = document.getElementById("addbutton");
var key = 1;
addbutton.addEventListener("click", function() {
key++;
document.getElementById('dynamic-imput').name = 'ser['+key+'][\'name\']';
var boxes = document.getElementById("boxes");
var head = document.getElementById("dynamicDivSection");
var clone = boxes.firstElementChild.cloneNode(true);
var clonedInput = clone.firstElementChild;
clonedInput.setAttribute('id', clonedInput.getAttribute('id') + '-' + head.children.length);
head.insertAdjacentElement('afterbegin', clone);
});
<div id="dynamicDivSection"></div>
<button id="addbutton">add box</button>
<div id="boxes">
<div class="box">
<input type="text" id='dynamic-imput' name="">
</div>
</div>

Related

Value in "input" filed becomes empty [duplicate]

This question already has answers here:
Stop input from clearing on innerHTML insert
(4 answers)
Closed 8 months ago.
Hi Folks I'm new to JS World.
I am trying to add A <div> dynamically to my HTML with the help of JavaScript.
var counter = 0;
function add_more_animals() {
counter+=1;
html = `<div id="animal${counter}">
<input type="text" name="animalName${counter}">
<input type="text" name="animalType${counter}">
</div>`;
var form = document.getElementById("animals");
form.innerHTML+=html;
}
<div id="animals">
<div id="animal0">
<input type="text" name="animalName0">
<input type="text" name="animalType0">
</div>
</div>
<button type="button" onclick="add_more_animals()">Add animals (+)</button>
The issue I'm facing:
While I populate the fields of animalName0 and animalType0 on UI. After I click on add button so as to insert more animals data, new div is created as per JS logic written in file. But my earlier inputs to animalName0 & animalType0 becomes empty & I have to insert data there all over again.
Can you please help here?
The problem stems from the line form.innerHTML+=html which is shorthand for form.innerHTML = form.innerHTML + html. When it gets the form.innerHTML it is grabbing the HTML only; The text typed into the inputs are not a part of this HTML. When the innerHTML gets set, think form.innerHTML = form.innerHTML + html, brand new HTML elements are created based off of the HTML only, and any state, including typed in text, is lost. Any event listeners will also be lost in this process.
The proper way of adding a new element while leaving adjacent elements in place is to create the new element with document.createElement, and add it with a function like .appendChild, like so
var counter = 0
function add_more_animals() {
counter+=1;
// Create an empty element
const newEl = document.createElement('div')
newEl.id = `catalogue${counter}`
// Add the first input
const nameInput = document.createElement('input')
nameInput.name = `animalName${counter}`
newEl.appendChild(nameInput)
// Now the second one
const typeInput = document.createElement('input')
typeInput.name = `animalType${counter}`
newEl.appendChild(typeInput)
// And finally attach everything to the animals form
document.getElementById("animals").appendChild(newEl)
}
<div id="animals">
<div id="animal0">
<input type="text" name="animalName0">
<input type="text" name="animalType0">
</div>
</div>
<button type="button" onclick="add_more_animals()">Add animals (+)</button>
As you can imagine, this can become verbose if you have a large amount of HTML to add. To make this process easier they came out with template tags which you may prefer using. Use them either like this or like this.

Need help fixing javascript for creating individual click events on form page with multiple file upload inputs

I have a page with a Gravity Form containing multiple file upload fields.
When a user clicks the button (modified label) the div container holding the file input has the file name appended to it.
My problem is that based on the tutorial I used to restyle the fields and set up, the javascript only targets the first file input and the others won't work when they are clicked.
How do I fix my code so that the javascript is listening to all file inputs, not just the first?
(I was trying to attach the filename to an existing div in the container. If you know a better way I'm open)
Some screenshots
four file upload fields
When I click first field button, filename appears successfully. When I click remaining field buttons, no filename appears
The issue seems to be around using .querySelector() which only targets the first file input on the page.
I've tried that, also using getElementsByClassName, iterating through a loop using querySelectorAll. But can't quite figure it out
Using .querySelector()
HTML
<li id="field_3_9" class="gfield gfield_upload w-100 field_sublabel_below field_description_below gfield_visibility_visible">
<label class="gfield_label" for="input_3_9">upload file</label>
<div class="ginput_container ginput_container_fileupload">
<input type="hidden" name="MAX_FILE_SIZE" value="52428800">
<input name="input_9" id="input_3_9" type="file" class="medium" aria-describedby="validation_message_3_9 live_validation_message_3_9 extensions_message_3_9" onchange="javascript:gformValidateFileSize( this, 52428800 );" tabindex="55">
<span id="extensions_message_3_9" class="screen-reader-text"></span>
<div class="validation_message" id="live_validation_message_3_9">pdf test.pdf</div>
</div>
</li>
Javascript
var inputLabel = document.querySelector('.gfield_label');
var inputWrapper = document.querySelector('.gfield_upload');
var input = document.querySelector("input[type='file']");
var inputSuccess = document.querySelector('.validation_message');
input.addEventListener('change', () => {
const name = input.value.split(/\\|\//).pop();
const truncated = name.length > 20
? name.substr(name.length - 20)
: name;
inputSuccess.innerHTML = truncated;
});
Tried with .querySelectorAll()
var inputWrapper = document.querySelectorAll('.gfield_upload');
Array.from(inputWrapper).forEach(input => {
input.addEventListener('click', function(event) {
var realInput = document.querySelector("input[type='file']");
var inputSuccess = document.querySelector('.validation_message');
realInput.addEventListener('change', () => {
const name = realInput.value.split(/\\|\//).pop();
const truncated = name.length > 20
? name.substr(name.length - 20)
: name;
inputSuccess.innerHTML = truncated;
});
});
});
My expectations are when I click the upload button for any of the file input fields, the file name will be appended to the input container and visible on the screen.
Your querySelectorAll solution is almost working, you are just querying from the wrong root element.

Retrieve the name of a button created with innerHTML

I'm trying to retrieve the name of a button created using innerHtml. My problem is really simple to understand, and sure enough, to solve. Thanks in advance!
this is my code, adding a column to a dynamic table:
colonne1.innerHTML = '<td align="center"><input id=' +
button_id_is_id_plat+ ' type="button" name='+title+' value="Supprimer"
onclick="DeletePlat('+button_id_is_id_plat+')"></td>';
the name which contains the variable title, is what i'm looking to retrieve in my DeletePlat function. Here is what I've tried but with no positive results:
var my_array=document.getElementById("plat_action"); //the id of the dynamic table
var longueur = arrayLignes.length;
while(i<longueur)
{
//I retrieve the cell which contains a string
var cellule = my_array.rows[i].cells[0];
//I retrieve the cell which contains the button that I've created with innerHTML
var cellule2 = my_array.rows[i].cells[1];
//Here, I want to retrieve the name of the button embedded into my "cellule2" variable
if (cellule.innerText.toString()==cellule2.innerText.toString())
{
//treatment...
}
}
I've also tried cellule2.name.toString(), but, it seems that it ain't the solution too.
Here an example of what you could do in order to retrieve the name from a button html element:
let buttonElement = document.getElementById("button");
let name = buttonElement.getAttribute('name');
console.log(name)
<button name="buttonname" type="submit" value="HTML" id="button">HTML</button>
To rerieve the name of a button no need to call toString() function : just use the .name attribute of your DOM element :
console.log(document.getElementById("button").name);
<div id="div">
<button id="button" name="nameOfButton">Button</button>
</div>

accessing form elements with javascript

im coding a form with dynamic textfield adding but i cant get num of the elements and their content created dynamically
here is the sample
<input name="mobiles[]" id="mobile"><a onclick="addfield()">add</a>
im using appenchild method for adding new inputs
for accessing mobiles elements i use
document.getElementsByName('mobiles[]').length;
but it returns just 1 and dont count added fields
I think the way you are appending the input fields is wrong. Check the snippet below, and try running it. Hope this helps.
addField = function(){
var wrapper = document.getElementById('wrapper');
var li = document.createElement('li');
var input = document.createElement('input');
input.name = 'mobiles[]';
li.append(input);
wrapper.append(li);
};
updateCount = function(){
// Shows you current count on the page.
count = document.getElementsByName('mobiles[]').length;
document.getElementById('count-wrapper').innerHTML = count;
};
<ul id="wrapper">
<li><input name="mobiles[]"></li>
</ul>
<button onclick="addField()">Add Input</button>
<button onclick="updateCount()">Update Count</button>
<div>
Input Field Count is : <span id="count-wrapper">1</span>
</div>

Select dynamically created element

I created a div dynamically and attached to div. I'm trying to add data from query and load it to that text field. But, I'm unable to select the dynamically created elements because its not visible in the DOM, since its already loaded.
This is what I have fiddle
<div id="parent">
<input id='childButton' type="button" value="Add"/>
<div id="child" data-row="0">
<input type="text" value="" />
</div>
</div>
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum);
$('#parent').append(clone);
console.log($('#child[data-row=1]').length);
});
The problem is the id selector, will return only the first element with the given id. In your case you are creating multiple elements with the id child. So #child will return the first child element, but then applying the data-row rule will filter out the selected element so you are getting 0 are the result.
The solution is to use a class instead of id to select the element
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum).removeAttr('id');
$('#parent').append(clone);
//here clone refers to the dynamically create element
//but if you want to fetch the element using a selector then
snippet.log($('.child[data-row=1]').length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<div id="parent">
<input id='childButton' type="button" value="Add" />
<div id="child" class="child" data-row="0">
<input type="text" value="" />
</div>
</div>
You're cloned element with same id, if you want to check just use
console.log($('div[data-row=1]').length);
Like others said, an ids should be unique. Use class definition instead for child id name.
When you're cloning an element with id, change the id (fiddle):
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var origin = $('#child');
var originId = $('#child').attr('id');
var cloneId = originId + rowNum;
var clone = $('#child').clone().attr('data-row', ++rowNum).attr('id', cloneId);
$('#parent').append(clone);
console.log($('#' + cloneId).length);
});
DEMO
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum);
$('#parent').append(clone);
console.log($('#parent input:text').length);
});
You can also select the input by using the selector input:text
UPDATE
DEMO
IF you want to select the specific input to set value into you can use the index and set the value by finding that index
I think your selector is wrong it must be:
console.log($('#child[data-row="1"]').length);
and consider to remove the id attr in order to avoid multiple ids.
Demo: http://jsfiddle.net/o1j7z1gL/

Categories