Modify input names in childnodes with JavaScript - javascript

I need help extending this JavaScript (borrowed from https://www.quirksmode.org/dom/domform.html):
var appCounter = 0;
function anotherApp() {
appCounter = appCounter + 1;
var newAppField = document.getElementById("keyApp").cloneNode(true);
newAppField.id = '';
newAppField.style.display = 'block';
var newApp = newAppField.childNodes;
for (var i = 0; i < newApp.length; i++) {
var theName = newApp[i].name
if (theName) {
newApp[i].name = theName + appCounter;
}
}
var insertApp = document.getElementById('keyApp');
insertApp.parentNode.insertBefore(newAppField, insertApp);
document.getElementById('appCount').value = appCounter
}
This works fine when element in my form is:
<div id="keyApp" style="display:none">
<input type="text" name="application" id="application">
<input type="text" name="usage" id="usage">
<\div>
But when I add div's around the inputs (bootstrap styling reasons) I loose the ability to update the input names:
<div id="keyApp" style="display:none">
<div class="col-md-2">
<input type="text" name="application" id="application">
</div>
<div class="col-md-2">
<input type="text" name="usage" id="usage">
</div>
<\div>
How do I extend the script to modify the input names in these new div's?

Since there is now another layer, you need to get newApp[i].childNodes[0] now in order to get the actual input elements.
newApp now holds a list of the div elements with col-md-2 styling, and you need to get the children inside of these div elements.

Related

Avoid input text erase when a function is run

I'm working on a TO DO List.
here's the HTML body-
<div class="cardDiv">
<input type="text" class="titleText" placeholder="Today's Battle Plans🤠">
<div class="taskList">
<div class="indiv-task task1">
<input type="checkbox" class="checkBox">
<input type="text" class="textBox" placeholder="task1">
</div>
</div>
<button class="addTask-btn" onclick="addTask()">Add More Tasks</button>
</div>
<script src="index.js"></script>
Basically, the button at the end adds a code block for a new task each time the button gets pressed as per this JS code-
let taskList = document.querySelector(".taskList");
let taskCode = '<div class="indiv-task"> <input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1"> </div>';
function addTask() {
taskList.innerHTML += taskCode;
let taskListLength = document.querySelectorAll(".indiv-task").length;
for(i=0; i<taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task"+(i+1);
document.querySelectorAll(".indiv-task")[i].classList.add("task"+(i+1));
}
}
But the problem is that whenever the button is pressed all the input text in textBox(es) gets erased. Is there a way I can avoid that, or is it possible only with databases?
PS- I'm still on my learning path...
Like what epascarello said we need to create an element and add it to the taskList element and not use innerHTML to add elements.
let taskList = document.querySelector(".taskList");
let taskHTML = '<input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1">';
function addTask() {
let taskCode = document.createElement("DIV");
taskCode.innerHTML = taskHTML;
taskCode.classList.add("indiv-task")
taskList.appendChild(taskCode)
let taskListLength = document.querySelectorAll(".indiv-task").length;
for(i=0; i<taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task"+(i+1);
document.querySelectorAll(".indiv-task")[i].classList.add("task"+(i+1));
}
}
This means that the innerHTML for the taskList element is not reset to have empty text boxes, rather, it just adds another element.
This is because the innerHTML will replace the current html of the element. You can try with:
function addTask() {
const taskList = document.querySelector(".taskList");
const taskCode = '<div class="indiv-task"> <input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1"> </div>';
const taskCodeDocument = new DOMParser().parseFromString(taskCode, "text/html");
const taskCodeChild = taskCodeDocument.body.firstChild;
taskList.appendChild(taskCodeChild);
let taskListLength = document.querySelectorAll(".indiv-task").length;
for (i = 0; i < taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task" + (i + 1);
document.querySelectorAll(".indiv-task")[i].classList.add("task" + (i + 1));
}
}
ref: https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
& https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

How to grab values of checkboxes in an array

I have a div as follows:
<div class="questionholder" id="question5" style="display:none">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(6);">Next</a>
</div>
The user is expected to select all the checkboxes that apply to his situation. Let's assume he selects all 3.
When he clicks "Next", the function displayquestion(); will fire.
function displayquestion(a) {
var Elements = '';
var b = a - 1;
Elements = document.querySelector("#question" + b + " input[name=ID1element]").value;
}
Basically, the function is meant to store all the checked values into var Elements, which is meant to be an array.
However, I'm only getting the value of the first selected answer instead of an array of all selected answers.
How do I grab all the selected answers into an array?
No jQuery please.
Use querySelectorAll to get an array-like NodeList instead of querySelector, and then you can use Array.from to transform that NodeList into an array containing only the .value of the selected inputs:
function displayquestion(a) {
const b = a - 1;
const elements = Array.from(
document.querySelectorAll('#question' + b + ' input:checked'),
input => input.value
);
console.log(elements);
}
<div class="questionholder" id="question5">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(6);">Next</a>
</div>
Here is the script that you can use for that:
I haven't changed anything in your HTML structure. Except I have removed the display: none; from the style attribute of the class questionholder.
<script>
function displayquestion(b) {
let checkboxList = document.querySelectorAll("#question" + b + " input:checked");
let obj = [];
if (checkboxList.length > 0) { //Code works only if some checbox is checked
checkboxList.forEach(function(item) {
obj.push(item.value); //Contains the value of all the selected checkboxes.
});
}
console.log(obj); //array list containing all the selected values
}
</script>
<div class="questionholder" id="question5" style="">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button" onclick="displayquestion(5);">Next</a>
</div>
Here is a JSFiddle link for that.
I hope this is helpful.
So first of I would make a variable for your
<a class="text2button">Next</a>. And I have removed the
onclick="displayquestion(6)" from your html.
Here is the variable.
var text2button = document.getElementsByClassName("text2button")[0];
text2button.addEventListener("click", displayquestion);
Here we have the function, so what I've done is.
I have created a variable var elements = []; Which is a empty array.
Then I create this variable var inputs = document.getElementsByClassName("input5");
This variable gets all the inputs with class input5.
Next I would loop through each of the inputs from the var inputs. Like this.
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
elements.push(inputs[i].value);
}
}
So what I do here is loop through each input for (var i = 0; i < inputs.length; i++) and then I check if any of the inputs are checked if (inputs[i].checked), then I push them to the array var elements with elements.push(inputs[i].value);.
And then I use console.log(elements); so show it in the console.
Check out the snippet below to see it in effect.
Hope this helps.
var text2button = document.getElementsByClassName("text2button")[0];
text2button.addEventListener("click", displayquestion);
function displayquestion() {
var elements = [];
var inputs = document.getElementsByClassName("input5");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
elements.push(inputs[i].value);
}
}
console.log(elements);
}
<div class="questionholder" id="question5">
<div>
<h5>Select all that apply</h5>
<input class="input5" type="checkbox" id="ID1elementColor" name="ID1element" value="color"><label for="ID1elementColor"><p class="radioChoice">Color</p></label>
<input class="input5" type="checkbox" id="ID1elementHeight" name="ID1element" value="height"><label for="ID1elementHeight"><p class="radioChoice">Height</p></label>
<input class="input5" type="checkbox" id="ID1elementWeight" name="ID1element" value="weight"><label for="ID1elementWeight"><p class="radioChoice">Weight</p></label>
</div>
</div>
<div class="holdButtons">
<a class="text2button">Next</a>
</div>

Array of html inputs

I have a html form, where user need to enter the name and address of their office. The number of offices are dynamic.
I want to add an Add More button, so that users can enter the details of any number of offices.
My question is, how can I create an array of inputs where new elements can be added and removed using JavaScript. Currently, I'm doing it using js clone method, but I want an array, so that input data can easily be validated and stored to database using Laravel.
What I'm currently doing..
This is my HTML form where users have to enter the address of their clinic or office. I've taken a hidden input field and increasing the value of that field whenever a new clinic is added, so that I can use loop for storing data.
<div class="inputs">
<label><strong>Address</strong></label>
<input type="text" class="hidden" value="1" id="clinicCount" />
<div id="addresscontainer">
<div id="address">
<div class="row" style="margin-top:15px">
<div class="col-md-6">
<label><strong>Clinic 1</strong></label>
</div>
<div class="col-md-6">
<button id="deleteclinic" type="button" class="close deleteclinic"
onclick="removeClinic(this)">×</button>
</div>
</div>
<textarea name="address1" placeholder="Enter Clinic Address" class="form-control"></textarea>
<label class="text-muted" style="margin-top:10px">Coordinates (Click on map to get coordinates)</label>
<div class="row">
<div class="col-md-6">
<input class="form-control" id="latitude" type="text" name="latitude1" placeholder="Latitude" />
</div>
<div class="col-md-6">
<input class="form-control" id="longitude" type="text" name="longitude1" placeholder="Longitude" />
</div>
</div>
</div>
</div>
</div>
<div class="text-right">
<button class="btn btn-success" id="addclinic">Add More</button>
</div>
And my js code..
function numberClinic(){
//alert('test');
var i=0;
$('#addresscontainer > #address').each(function () {
i++;
$(this).find("strong").html("Clinic " + i);
$(this).find("textarea").attr('name','name'+i);
$(this).find("#latitude").attr('name','latitude'+i);
$(this).find("#longitude").attr('name','longitude'+i);
});
}
$("#addclinic").click(function(e){
e.preventDefault();
$("#addresscontainer").append($("#address").clone());
numberClinic();
$("#addresscontainer").find("div#address:last").find("input[name=latitude]").val('');
$("#addresscontainer").find("div#address:last").find("input[name=longitude]").val('');
$("#clinicCount").val(parseInt($("#clinicCount").val())+1);
});
function removeClinic(address){
if($("#clinicCount").val()>1){
$(address).parent('div').parent('div').parent('div').remove();
$("#clinicCount").val(parseInt($("#clinicCount").val())-1);
}
numberClinic();
}
This way, I think I can store the data to the database but can't validate the data. I'm using the laravel framework.
One way you could do this is by using the position of the input in the parent as the index in the array, then saving the value in the array every time each input is changed. Then you can just add and remove inputs.
Sample code:
var offices = document.getElementById('offices');
var output = document.getElementById('output');
var data = [];
var i = 0;
document.getElementById('add').addEventListener('click', function() {
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('placeholder', 'Office');
var button = document.createElement('button');
var index = i++;
input.addEventListener('keyup', function() {
for (var i = 0; i < offices.children.length; i++) {
var child = offices.children[i];
if (child === input) {
break;
}
}
// i is now the index in the array
data[i] = input.value;
renderText();
});
offices.appendChild(input);
});
document.getElementById('remove').addEventListener('click', function() {
var children = offices.children;
if (children.length === data.length) {
data = data.splice(0, data.length - 1);
}
offices.removeChild(children[children.length - 1]);
renderText();
});
function renderText() {
output.innerHTML = data.join(', ');
}
JSFiddle: https://jsfiddle.net/94sns39b/2/

Display multiple blocks, radio is checked

I need some help in editing my current script.
I use 1 radio button, that should hide/display multiple divs when 1 of the radio buttons is selected.
It works fine for just 1 div, but I can not make it work with multiple divs.
My current HTML:
<div class="col-md-12">
<div class="form-group form-group-xl">
<label for="Particulier"><input type="radio" id="Particulier"checked="checked" name="checkzakelijk" onclick="ShowHideDiv()" />Particulier</label>
<label for="Zakelijk"><input type="radio" id="Zakelijk" name="checkzakelijk" onclick="ShowHideDiv()" />Bedrijf</label>
</div>
</div>
<div class="col-sm-6" id="checkzakelijk1" style="display:none;">
<div class="form-group">
<label class="control-label" for="customfield{$customfield.id}">{$customfield.name}</label>
<div class="control">
{$customfield.input} {$customfield.description}
</div>
</div>
</div>
<div class="col-sm-6" id="checkzakelijk2" style="display:none;">
<div class="form-group">
<label class="control-label" for="customfield{$customfield.id}">{$customfield.name}</label>
<div class="control">
{$customfield.input} {$customfield.description}
</div>
</div>
</div>
Current script:
<script type="text/javascript">
function ShowHideDiv() {
var chkYes = document.getElementById("Zakelijk");
var dvPassport = document.getElementById("checkzakelijk");
var dvPassport = document.getElementById("checkzakelijk1");
var dvPassport = document.getElementById("checkzakelijk2");
dvPassport.style.display = chkYes.checked ? "block" : "none";
}
</script>
You are overwriting dvPassport variable, so only the last element will be have its effect.
Change it to
function ShowHideDiv() {
var chkYes = document.getElementById("Zakelijk");
var dvPassport1 = document.getElementById("checkzakelijk");
var dvPassport2 = document.getElementById("checkzakelijk1");
var dvPassport3 = document.getElementById("checkzakelijk2");
var display = chkYes.checked ? "block" : "none";
dvPassport1.style.display = display;
dvPassport2.style.display = display;
dvPassport3.style.display = display;
}
Have a closer look at this bit:
var dvPassport = document.getElementById("checkzakelijk");
var dvPassport = document.getElementById("checkzakelijk1");
var dvPassport = document.getElementById("checkzakelijk2");
What you are doing here is declaring a new variable with the same name multiple times, which doesn't make much sense.
I would suggest jQuery class selector, i.e.
$(".col-sm-6").hide();
Also, in cases where you want to apply something to multiple elements, it's worth giving them the same class, rather than listing the ids. It's simpler and makes the code much more readable.

dynamically creating div using javascript/jquery

I have two div called "answerdiv 1" & "answerdiv 2" in html.
now i want to give/create div id uniquely like "answerdiv 3" "answerdiv 4" "answerdiv 5" and so on.
Using javascript/jquery how can i append stuff in these dynamically created divs which id should be unique?
in my project user can add "n" numbers of div, there is no strict limit to it.
Help me out.
Thanks in Adv
================================================================================
My HTML code is:
<div id="answertextdiv">
<textarea id="answertext" name="answertext" placeholder="Type answer here" rows="2" cols="40" tabindex="6" onBlur="exchangeLabelsanswertxt(this);"></textarea>
</div>
My JS code:
function exchangeLabelsanswertxt(element)
{
var result = $(element).val();
if(result!="")
{
$(element).remove();
$("#answertextdiv").append("<label id='answertext' onClick='exchangeFieldanswertxt(this);'>"+result+"</label>");
}
}
function exchangeFieldanswertxt(element)
{
var result = element.innerHTML;
$(element).remove();
$("#answertextdiv").append("<textarea id='answertext' name='answertext' placeholder='Type answer here' rows='2' cols='40' tabindex='6' onBlur='exchangeLabelsanswertxt(this);'>"+result+"</textarea>");
}
Now from above code I want to append all stuff in unique "answertextdiv" id.
If your divs are in a container like:
<div id="container">
<div id="answerdiv 1"></div>
<div id="answerdiv 2"></div>
</div>
you could do something like:
//Call this whenever you need a new answerdiv added
var $container = $("container");
$container.append('<div id="answerdiv ' + $container.children().length + 1 + '"></div>');
If possible, try not to use global variables...they'll eventually come back to bite you and you don't really need a global variable in this case.
You can try something like this to create divs with unique ids.
HTML
<input type="button" value="Insert Div" onClick="insertDiv()" />
<div class="container">
<div id="answerdiv-1">This is div with id 1</div>
<div id="answerdiv-2">This is div with id 2</div>
</div>
JavaScript
var i=2;
function insertDiv(){
for(i;i<10;i++)
{
var d_id = i+1;
$( "<div id='answerdiv-"+d_id+"'>This is div with id "+d_id+"</div>" ).insertAfter( "#answerdiv-"+i );
}
}
Here is the DEMO
You should keep a "global" variable in Javascript, with the number of divs created, and each time you create divs you will increment that.
Example code:
<script type="text/javascript">
var divCount = 0;
function addDiv(parentElement, numberOfDivs) {
for(var i = 0; i < numberOfDivs; i++) {
var d = document.createElement("div");
d.setAttribute("id", "answerdiv"+divCount);
parentElement.appendChild(d);
divCount++;
}
}
</script>
And please keep in mind that jQuery is not necessary to do a lot of things in Javascript. It is just a library to help you "write less and do more".
I used below JQuery code for the same
$("#qnty1").on("input",function(e)
{
var qnt = $(this).val();
for (var i = 0; i < qnt; i++) {
var html = $('<div class="col-lg-6 p0 aemail1"style="margin-bottom:15px;"><input type="text" onkeyup= anyfun(this) class="" name="email1'+i+'" id="mail'+i+'" > </div><div id=" mail'+i+'" class="lft-pa img'+i+' mail'+i+'" > <img class="" src="img/btn.jpg" alt="Logo" > </div> <div id="emailer1'+i+'" class=" mailid "></div>');
var $html=$(html);
$html.attr('name', 'email'+i);
$('.email1').append($html);
}
}
my HTML contain text box like below.
<input type="text" name="qnty1" id="qnty1" class="" >
and
<div class="email1">
</div>
you need a global counter (more generally: a unique id generator) to produce the ids, either explicitly or implicitly (the latter eg. by selecting the last of the generated divs, identified by a class or their id prefix).
then try
var newdiv = null; // replace by div-generating code
$(newdiv).attr('id', 'answerdiv' + global_counter++);
$("#parent").append(newdiv); // or wherever
var newdivcount=0;
function insertDivs(){
newdivcount=newdivcount+1;
var id="answerdiv-"+(newdivcount);
var div=document.createElement("DIV");
div.setAttribute("ID",id);
var input=document.createElement("TEXTAREA");
div.appendChild(input);
document.getElementById('container').appendChild(input);
}
<button onclick="insertDivs">InsertDivs</button>
<br>
<div id="container">
<div id="answertextdiv">
<textarea id="answertext" name="answertext" placeholder="Type answer here" rows="2" cols="40" tabindex="6" onBlur="exchangeLabelsanswertxt(this);"></textarea>
</div>
</div>
Here is the another way you can try
// you can use dynamic Content
var dynamicContent = "Div NO ";
// no of div you want
var noOfdiv = 20;
for(var i = 1; i<=noOfdiv; i++){
$('.parent').append("<div class='newdiv"+i+"'>"+dynamicContent+i+"</div>" )
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
</div>

Categories