How to make an array with dynamic jQuery input? - javascript

I have a form with dynamic input. Inputs have same name attributes. So I want to make array for each row.
Like this;
[{'company':'Apple'},{'address':'USA'}],
[{'company':'Samsung'},{'address':'Korea'}]
I am using this simple form (it's dynamic);
<form id='companies'>
<input name='company[]'>
<input name='address[]'>
</form>
And this;
$('form').submit(function(event) {
var newFormData = $('#companies').serializeArray();
console.log(newFormData);
event.preventDefault();
});
Console Log; (All inputs in same array)
[{'company':'Apple'},{'address':'USA'},{'company':'Samsung'},{'address':'Korea'}]

This is an example of solution of your problem :)
<form id='companies'>
<div class='container-input'>
<input name='company[]'>
<input name='address[]'>
</div>
<div class='container-input'>
<input name='company[]'>
<input name='address[]'>
</div>
... -> Now you have dynamic containers
</form>
You could use this approach to solve the problem with jQuery.
$('#companies').submit(function(event) {
var $data = [];
var $containers = $(".container-input");
$containers.each(function() {
var $contenedor = $(this);
var $inputCompany = $contenedor.find('input[name^="company"]');
var $inputAddress = $contenedor.find('input[name^="address"]');
var $objectInput = [{
'company': $inputCompany.val()
}, {
'address': $inputAddress.val()
}];
$data.push($objectInput);
});
console.log($data);
});

May help :) more dynamically.
$('#companies').submit(function(event) {
var $data = [];
$.each($(this).children("div"),function(){
obj={};
$.each($(this).find(":input"),function(){
obj[$(this).attr("name").replace("[]","")]=$(this).val();
$data.push(obj);
});
})
console.log($data);
event.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id='companies'>
<div class="input">
<input name='company[]'>
<input name='address[]'>
<input name='phone[]'>
</div>
<div class="input">
<input name='company[]'>
<input name='address[]'>
</div>
<div class="input">
<input name='company[]'>
<input name='address[]'>
</div>
<input type="submit"/>
</form>

Related

How do I make each new output appear in a new box?

I would like for every different item inputted to be outputted in a new box.
<!DOCTYPE html>
<html>
<body>
Form to get the input
<form id="form1">
<input name="item" type="text" size="20">
</form>
Box that should be duplicated to hold the new input.
<div class="box">
<p class="output"></p>
<div>
<button onclick="outputItem()">Add</button>
javascript:
<script>
function outputItem() {
var x = document.getElementById("form1");
item = x.elements.namedItem("item").value;
document.getElementById("output").innerHTML=item;
</script>
</body>
</html>
I am not sure if this is even close to what you want, but give this a try:
function outputItem() {
var els = document.querySelectorAll("#form1 input");
var box = document.querySelector('.box');
box.innerHTML = '';
els.forEach(
function(el) {
var newEl = document.createElement('div');
newEl.innerHTML = el.value;
box.appendChild(newEl);
}
);
}
<form id="form1">
<input name="item" type="text" size="20" value="item"><br/>
<input name="eggs" type="text" size="20" value="eggs"><br/>
<input name="milk" type="text" size="20" value="milk"><br/>
<input name="grains" type="text" size="20" value="grains"><br/>
<input name="legumes" type="text" size="20" value="legumes"><br/>
</form>
<button onclick="outputItem()">Add</button>
<hr/>
<div class="box"></div>
This creates a new <div> for every input and copies the .value from the <input> into the new <div>. Then it adds the <div> into the output area.

Why is my jQuery not adding display on second div I create?

When I try adding the first contact and submit it, it shows in the div id=contact.
The function hide/show is working then.
But as soon as I add a second contact it's not working anymore.
Seems, jQuery doesn't enter display...
function css(){
$('.contacts').css('background-color', 'lightblue');
}
function visibility() {
$("#vis").click(function(){
$(".description").toggle();
return false;
});
};
$( document ).ready(function() {
$("form").submit(function (event) {
var fname = $('#fname').val();
var lname = $('#lname').val();
var desc = $('#desc').val();
$('.contacts').append( "<div id='contact'>"+fname+"<br>"+lname+"<br><button id='vis'>Show/Hide</button><div class='description' style='display:;'>"+desc+"</div></div>");
// alert(fname);
event.preventDefault();
css();
visibility();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="get">
<fieldset>
<legend>Personal information:</legend>
First name: <input type="text" name="fname" id="fname"><br>
Last name: <input type="text" name="lname" id="lname"><br>
</fieldset>
<fieldset>
<legend>Description:</legend>
<textarea id="desc" value="desc"> </textarea><br>
<input type="submit" value="Submit">
</fieldset>
</form>
<div class="contacts"> </div>
Any help would be appreciated, thanks.
As I wrote in comment - You can't have multiple elements with the same ID in html. You also don't have to add listeners for each button. You can add listener for body and selector as second parameter (see attached code).
function css(){
$('.contacts').css('background-color', 'lightblue');
}
$( document ).ready(function() {
//this way you don't need to add listener for each button
$('body').on('click', '.vis', function() {
$(this).closest('.contact').find('.description').toggle();
});
$("form").submit(function (event) {
var fname = $('#fname').val();
var lname = $('#lname').val();
var desc = $('#desc').val();
$('.contacts').append( "<div class='contact'>"+fname+"<br>"+lname+"<br><button class='vis'>Show/Hide</button><div class='description'>"+desc+"</div></div>");
event.preventDefault();
css();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="get">
<fieldset>
<legend>Personal information:</legend>
First name: <input type="text" name="fname" id="fname"><br>
Last name: <input type="text" name="lname" id="lname"><br>
</fieldset>
<fieldset>
<legend>Description:</legend>
<textarea id="desc" value="desc"> </textarea><br>
<input type="submit" value="Submit">
</fieldset>
</form>
<div class="contacts"> </div>

Collect all value from input html form to object of javascript

Normally if I add a new input tag I also have to add in Javascript.
I try to collect all value from input tag,
So how to pass value into an object by loop
use tag input name to be object key name also.
Try to use for count
document.getElementById("form1").elements.length
seem it collected the button tag also, how to void it
<form name="form1">
<input type="text" name="value1">
<input type="text" name="value2">
<input type="text" name="value3">
<input type="text" name="value4">
<input type="button" id="save" onClick="fc1()" value="Save">
</form>
for(i=0;......)
{
obj.value+'i' = document.forms["form1"]["value"+ (i+1)].value;
}
Same result as this.
function fc1(){
this.value1 = document.forms["form1"]["value1"].value;
this.value2 = document.forms["form1"]["value2"].value;
this.value3 = document.forms["form1"]["value3"].value;
this.value4 = document.forms["form1"]["value4"].value;
const obj = {
"value1": this.value1,
"value2": this.value2,
"value3": this.value3,
"value4": this.value4
};
}
I usually grab inputs by their ID or class:
<input type="text" id="value1">
then grab the value:
const value1 = document.getElementById('value1').value
to cut down on code, maybe throw it in an array:
const valueArray = [value1, value2, value3]
then you can do something like this:
const allValues = {}
valueArray.forEach((value, index) => {
allValues[`value${index + 1}`] = value
})
now when you log allValues you should have what you want. Note, I am using some es6.
What about this ?
var obj = {};
var form = document.getElementById("form1");
form.children.forEach(function(elm){
if(elm.type === 'text'){
obj[elm.name] = elm.value;
}
});
console.log(obj);
try giving same 'class' or 'name' attribute to the text fields.
try var x = document.getElementsByClassName("example");
which gives you the list of all elements with the class name as "example'. Then you can loop around based on the length of x.
References:
https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
try this:
var input = document.forms[0].querySelectorAll('input[type=text]');
var result = Array.from(input).reduce((r, ele) => {
r[ele.name] = ele.value;
return r;
}, {});
console.log(result);
<form name="form1">
<input type="text" name="value1" value=1>
<input type="text" name="value2" value=2>
<input type="text" name="value3" value=3>
<input type="text" name="value4" value=4>
<input type="button" id="save" onclick="fc1()" value="Save">
</form>
If you used something like .. I think it will work. :)
var myObj = {};
var elems = document.getElementsByTagName('input'), i;
for (i in elems) {
myObj[value + i] = myObj[i].value;
}
return from getElementsByTagName is an array of all matching tags. there are some wizard answers in here ha. :)
document.querySelectorAll is made for this.
document.querySelectorAll("form[name='form1'] input[type='text']")
will return all input fields of type text in form1 as HTML nodes.
let elements = document.querySelectorAll("form[name='form1'] input[type='text']");
elements.forEach(e => console.log(e.value));
...logs the values of the input fields. Don't make things harder on yourself by hard coding classes or ID's, and this will allow you to target the input elements you need without additional checks or without fetching every input on the page.
Example:
const values = {};
document.querySelectorAll("form[name='form1'] input[type='text']").forEach(element => values[element.name] = element.value);
console.log(values);
<form name="form1">
<input type="text" name="value1" value=1>
<input type="text" name="value2" value=2>
<input type="text" name="value3" value=3>
<input type="text" name="value4" value=4>
<input type="button" id="save" onclick="fc1()" value="Save">
</form>
This is an alternative solution done with jQuery.
Hope this is what you were looking for. Happy to explain or help in a better solution if needed.
//jQuery solution
const obj = {}
$('#save').click(function(e){
var form = $(this).parent();
var inputs = form.children().not(':input[type=button]');
$.each( inputs, function(){
obj[$(this).attr('name')] = $(this).val();
});
console.log(obj);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>jQuery solution</h2>
<form name="form1">
<input type="text" name="value1">
<input type="text" name="value2">
<input type="text" name="value3">
<input type="text" name="value4">
<input type="button" id="save" value="Save">
</form>
JS Solution
//JS Solution
const objs = {}
var button = document.getElementById('savejs');
var form = document.getElementById('formjs');
var element = {};
button.addEventListener('click', function(){
inputs = form.children;
for(i=0; i < inputs.length; i++){
if(inputs[i].name != ""){
objs[inputs[i].name] = inputs[i].value;
}
}
console.log(objs);
})
<h2>JS solution</h2>
<form name="form1" id='formjs'>
<input type="text" name="value1">
<input type="text" name="value2">
<input type="text" name="value3">
<input type="text" name="value4">
<input type="button" id="savejs" value="Save">
</form>

jQuery Form - Serialize into multi dimensional array?

I need to get value from form, format it to JSON and post it via AJAX. This is the format I want to achieve:
{
items: [
{ id: 7, name: 'Book', price: 5.7 },
{ id: 5, name: 'Pencil', price: 2.5 }
]
}
Here's the HTML:
(function($){
var $form = $('form');
// serializeArray format is way off from what I need
var rawData = $form.serializeArray();
console.log(rawData)
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
Should I loop and use regex to parse the name? or is there built-in way?
I can change the <form> format if needed.
You can't use the default serialization here, instead you can do a manual serialization like
(function($) {
var $fieldsets = $('form fieldset');
var items = $fieldsets.map(function(i, fs) {
var obj = {};
$(fs).find('input').each(function() {
obj[this.name.match(/\[([^\[]*)\]$/)[1]] = this.value;
});
return obj;
}).get();
var rawData = {
items: items
};
console.log(rawData)
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
Please take a look at this approach. We can't just use $.serializeArray() but also we need some custom code as follows. Actually we need to iterate over all <fieldset> to get JSON as we needed:
(function($) {
var $form = $('form');
var fieldSets = $form.find("fieldset");
var result = {
items: []
};
fieldSets.each(function() {
var fields = {};
$.each($(this).serializeArray(), function() {
fields[this.name] = this.value;
});
result.items.push(fields);
});
console.log(result);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="id" value="7">
<input type="text" name="name" value="Book">
<input type="number" name="price" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="id" value="5">
<input type="text" name="name" value="Pencil">
<input type="number" name="price" value="2.5">
</fieldset>
</form>
Note: Modified the HTML a bit as instead of name="items[0][id]" i have given as name="id"
Yes, you will need to parse the name field yourself. There is no automated method of parsing a custom field. There are, of course, multiple methods of doing so.
NOTE: I'm assuming that your name="items[0][id]" field specifies that this must be the 0th item in the resulting array, and that such sets of <input> fields are not, necessarily, in ascending order by item # within the DOM. In other words, the item[N] should be controlling over it being the Qth <fieldset> in the <form>.
You could use serializeArray() and then process that data:
(function($){
var $form = $('form');
var data = $form.serializeArray();
var result = {items:[]};
data.forEach(function(input){
nameArray = input.name.split(/[[\]]/);
item = nameArray[1];
prop = nameArray[3];
if(typeof result.items[item] !== 'object'){
result.items[item]={};
}
if(typeof result.items[item][prop] !== 'undefined'){
//Consistency check the name attribute
console.log('Warning duplicate "name" property =' + input.name);
}
result.items[item][prop]=input.value;
});
console.log(result);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
Or, you could directly process it from the DOM:
(function($){
var result = {items:[]};
$('form fieldset input').each(function(){
nameArray = this.name.split(/[[\]]/);
item = nameArray[1];
prop = nameArray[3];
if(typeof result.items[item] !== 'object'){
result.items[item]={};
}
if(typeof result.items[item][prop] !== 'undefined'){
//Consistency check the name attribute
console.log('Warning duplicate "name" property =' + this.name);
}
result.items[item][prop]=this.value;
});
console.log(result);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>

clone/add-new form fields

<div class="input url required addnew" id="ConfigurationValues">
<label>Bigblue</label>
<input name="data[Configuration][value][]" value="cool" type="text">
<input name="data[Configuration][value][]" value="awesome" type="text">
<input name="data[Configuration][value][]" value="neat" type="text">
<div class="actions" style="padding-left:0px;">
<a onclick="return FALSE;" href="#" id="AddNew">Add</a>
</div>
</div>
I would like to replicate/clone the input. I have the below code that works for text.
$('a.AddNew').click(function(){
var pool = $(this).closest('.addnew');
pool.find('input[type=text]:first').clone().val('').insertAfter(pool.find("input[type=text]:last"));
return false
})
Now i want to write generalized code the takes care of type=url,email,tel,number and select tag.
In the above code line 3-6 will change as folows
<input name="data[Configuration][value][]" value="neat" type="url">
or
<input name="data[Configuration][value][]" value="neat" type="tel">
or
<select></select>
Do you mean something like this:
function cloneElement(selector) {
$('a.AddNew').click(function(){
var pool = $(this).closest('.addnew');
var inputs = pool.find(selector);
inputs.first().clone().val('').insertAfter(inputs.last());
return false;
});
}
function cloneInput(type) {
return cloneElement('input[type=' + type + ']');
}
function cloneSelect() {
return cloneElement('select');
}
EDIT: Ok, what about:
$('a.AddNew').click(function(){
var pool = $(this).closest('.addnew');
var inputs = pool.find("input, select");
inputs.first().clone().val('').insertAfter(inputs.last());
return false;
});

Categories

Resources