Serializing a form with dynamic keys - javascript

I am looking for a better way to serialize a form with input pairs; one input is for the key, another is for the value. Whoever is using this form could opt to add more key-value input pairs.
I currently have this fiddle to serialize the form, but I am not convinced this is the best/optimal/readable way. Are there any library or method I'm missing that would make this code better?
Code as follows:
HTML:
<div>
<form>
<span>
<input type="text" class="key" id="key1"/><input type="text" class="value" id="value1"/>
</span>
</form>
</div>
Add
Serialize
<div id="serialized-string"></div>
JavaScript :
$(document).ready(function(){
var numberOfPairs = $('.key').length;
$('#add').on('click', function () {
numberOfPairs += 1;
$('div > form').append('<span><input type="text" class="key" id="key'+numberOfPairs+'"/><input type="text" class="value" id="value'+numberOfPairs+'"/></span>');
});
$('#serialize').on('click', function () {
var serialized = "";
for(var x = 1; x <= numberOfPairs; x +=1) {
var keyValuePair = $('#key'+x).val() + "=" + $('#value'+x).val();
if(serialized.length > 0) {
serialized += "&" + keyValuePair;
} else {
serialized += keyValuePair;
}
}
alert(serialized);
});
});
and CSS
span {
display: block;
}
Also, I am not sure if I should properly encode this to URI...

You can use .serialize:
The .serialize() method creates a text string in standard URL-encoded
notation. It can act on a jQuery object that has selected individual
form controls, such as <input>, <textarea>, and <select>
Example:
$('#serialize').on('click', function () {
alert($('form').serialize());
});
But this assumes you've provided a name for your form elements.
<input type="text" class="key" name="key1" id="key1"/><input type="text" class="value" id="value1" name="key2" />**strong text**
See http://jsfiddle.net/s2tyS/1/

Related

How to return the first character of a text input? [duplicate]

I am working on a search with JavaScript. I would use a form, but it messes up something else on my page. I have this input text field:
<input name="searchTxt" type="text" maxlength="512" id="searchTxt" class="searchField"/>
And this is my JavaScript code:
<script type="text/javascript">
function searchURL(){
window.location = "http://www.myurl.com/search/" + (input text value);
}
</script>
How do I get the value from the text field into JavaScript?
There are various methods to get an input textbox value directly (without wrapping the input element inside a form element):
Method 1
document.getElementById('textbox_id').value to get the value of
desired box
For example
document.getElementById("searchTxt").value;
 
Note: Method 2,3,4 and 6 returns a collection of elements, so use [whole_number] to get the desired occurrence. For the first element, use [0],
for the second one use [1], and so on...
Method 2
Use
document.getElementsByClassName('class_name')[whole_number].value which returns a Live HTMLCollection
For example
document.getElementsByClassName("searchField")[0].value; if this is the first textbox in your page.
Method 3
Use document.getElementsByTagName('tag_name')[whole_number].value which also returns a live HTMLCollection
For example
document.getElementsByTagName("input")[0].value;, if this is the first textbox in your page.
Method 4
document.getElementsByName('name')[whole_number].value which also >returns a live NodeList
For example
document.getElementsByName("searchTxt")[0].value; if this is the first textbox with name 'searchtext' in your page.
Method 5
Use the powerful document.querySelector('selector').value which uses a CSS selector to select the element
For example
document.querySelector('#searchTxt').value; selected by id
document.querySelector('.searchField').value; selected by class
document.querySelector('input').value; selected by tagname
document.querySelector('[name="searchTxt"]').value; selected by name
Method 6
document.querySelectorAll('selector')[whole_number].value which also uses a CSS selector to select elements, but it returns all elements with that selector as a static Nodelist.
For example
document.querySelectorAll('#searchTxt')[0].value; selected by id
document.querySelectorAll('.searchField')[0].value; selected by class
document.querySelectorAll('input')[0].value; selected by tagname
document.querySelectorAll('[name="searchTxt"]')[0].value; selected by name
Support
Browser
Method1
Method2
Method3
Method4
Method5/6
IE6
Y(Buggy)
N
Y
Y(Buggy)
N
IE7
Y(Buggy)
N
Y
Y(Buggy)
N
IE8
Y
N
Y
Y(Buggy)
Y
IE9
Y
Y
Y
Y(Buggy)
Y
IE10
Y
Y
Y
Y
Y
FF3.0
Y
Y
Y
Y
N IE=Internet Explorer
FF3.5/FF3.6
Y
Y
Y
Y
Y FF=Mozilla Firefox
FF4b1
Y
Y
Y
Y
Y GC=Google Chrome
GC4/GC5
Y
Y
Y
Y
Y Y=YES,N=NO
Safari4/Safari5
Y
Y
Y
Y
Y
Opera10.10/
Opera10.53/
Y
Y
Y
Y(Buggy)
Y
Opera10.60
Opera 12
Y
Y
Y
Y
Y
Useful links
To see the support of these methods with all the bugs including more details click here
Difference Between Static collections and Live collections click Here
Difference Between NodeList and HTMLCollection click Here
//creates a listener for when you press a key
window.onkeyup = keyup;
//creates a global Javascript variable
var inputTextValue;
function keyup(e) {
//setting your input text to the global Javascript Variable for every key press
inputTextValue = e.target.value;
//listens for you to press the ENTER key, at which point your web address will change to the one you have input in the search box
if (e.keyCode == 13) {
window.location = "http://www.myurl.com/search/" + inputTextValue;
}
}
See this functioning in codepen.
I would create a variable to store the input like this:
var input = document.getElementById("input_id").value;
And then I would just use the variable to add the input value to the string.
= "Your string" + input;
You should be able to type:
var input = document.getElementById("searchTxt");
function searchURL() {
window.location = "http://www.myurl.com/search/" + input.value;
}
<input name="searchTxt" type="text" maxlength="512" id="searchTxt" class="searchField"/>
I'm sure there are better ways to do this, but this one seems to work across all browsers, and it requires minimal understanding of JavaScript to make, improve, and edit.
Also you can, call by tags names, like this: form_name.input_name.value;
So you will have the specific value of determined input in a specific form.
Short
You can read value by searchTxt.value
<input name="searchTxt" type="text" maxlength="512" id="searchTxt" class="searchField"/>
<script type="text/javascript">
function searchURL(){
console.log(searchTxt.value);
// window.location = "http://www.myurl.com/search/" + searchTxt.value;
}
</script>
<!-- SHORT ugly test code -->
<button class="search" onclick="searchURL()">Search</button>
<input type="text" onkeyup="trackChange(this.value)" id="myInput">
<script>
function trackChange(value) {
window.open("http://www.google.com/search?output=search&q=" + value)
}
</script>
Tested in Chrome and Firefox:
Get value by element id:
<input type="text" maxlength="512" id="searchTxt" class="searchField"/>
<input type="button" value="Get Value" onclick="alert(searchTxt.value)">
Set value in form element:
<form name="calc" id="calculator">
<input type="text" name="input">
<input type="button" value="Set Value" onclick="calc.input.value='Set Value'">
</form>
https://jsfiddle.net/tuq79821/
Also have a look at a JavaScript calculator implementation.
From #bugwheels94: when using this method, be aware of this issue.
If your input is in a form and you want to get the value after submit you can do like:
<form onsubmit="submitLoginForm(event)">
<input type="text" name="name">
<input type="password" name="password">
<input type="submit" value="Login">
</form>
<script type="text/javascript">
function submitLoginForm(event){
event.preventDefault();
console.log(event.target['name'].value);
console.log(event.target['password'].value);
}
</script>
Benefit of this way: Example your page have 2 form for input sender and receiver information.
If you don't use form for get value then
You can set two different id (or tag or name ...) for each field like sender-name and receiver-name, sender-address and receiver-address, ...
If you set the same value for two inputs, then after getElementsByName (or getElementsByTagName ...) you need to remember 0 or 1 is sender or receiver. Later, if you change the order of 2 form in HTML, you need to check this code again
If you use form, then you can use name, address, ...
You can use onkeyup when you have more than one input field. Suppose you have four or input. Then
document.getElementById('something').value is annoying. We need to write four lines to fetch the value of an input field.
So, you can create a function that store value in object on keyup or keydown event.
Example:
<div class="container">
<div>
<label for="">Name</label>
<input type="text" name="fname" id="fname" onkeyup=handleInput(this)>
</div>
<div>
<label for="">Age</label>
<input type="number" name="age" id="age" onkeyup=handleInput(this)>
</div>
<div>
<label for="">Email</label>
<input type="text" name="email" id="email" onkeyup=handleInput(this)>
</div>
<div>
<label for="">Mobile</label>
<input type="number" name="mobile" id="number" onkeyup=handleInput(this)>
</div>
<div>
<button onclick=submitData()>Submit</button>
</div>
</div>
JavaScript:
<script>
const data = { };
function handleInput(e){
data[e.name] = e.value;
}
function submitData(){
console.log(data.fname); // Get the first name from the object
console.log(data); // return object
}
</script>
function handleValueChange() {
var y = document.getElementById('textbox_id').value;
var x = document.getElementById('result');
x.innerHTML = y;
}
function changeTextarea() {
var a = document.getElementById('text-area').value;
var b = document.getElementById('text-area-result');
b.innerHTML = a;
}
input {
padding: 5px;
}
p {
white-space: pre;
}
<input type="text" id="textbox_id" placeholder="Enter string here..." oninput="handleValueChange()">
<p id="result"></p>
<textarea name="" id="text-area" cols="20" rows="5" oninput="changeTextarea()"></textarea>
<p id="text-area-result"></p>
<input id="new" >
<button onselect="myFunction()">it</button>
<script>
function myFunction() {
document.getElementById("new").value = "a";
}
</script>
One can use the form.elements to get all elements in a form. If an element has id it can be found with .namedItem("id"). Example:
var myForm = document.getElementById("form1");
var text = myForm.elements.namedItem("searchTxt").value;
var url = "http://www.myurl.com/search/" + text;
Source: w3schools
function searchURL() {
window.location = 'http://www.myurl.com/search/' + searchTxt.value
}
So basically searchTxt.value will return the value of the input field with id='searchTxt'.
Short Answer
You can get the value of text input field using JavaScript with this code: input_text_value = console.log(document.getElementById("searchTxt").value)
More info
textObject has a property of value you can set and get this property.
To set you can assign a new value:
document.getElementById("searchTxt").value = "new value"
Simple JavaScript:
function copytext(text) {
var textField = document.createElement('textarea');
textField.innerText = text;
document.body.appendChild(textField);
textField.select();
document.execCommand('copy');
textField.remove();
}

Getting data from HTML forms in Javascript always produces Strings?

I use Javascript to intercept an HTML form submission:
var form_api = $("#apiForm");
$(form_api).submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
/* Get input values from form */
var formData = prepFormData("#apiForm");
}
However, when I convert the data into an object (I wish to use jQuery to pass this to an endpoint), all object properties are strings.
function prepFormData(formSelector){
var form_api = $(formSelector);
// Serialize the form data as a PlainObject.
var formData = $(form_api).serializeArray().reduce(function (obj, item) {
obj[item.name] = item.value;
return obj;
}, {});
}
Why does it always produce strings? I would like the following behavior instead:
<input type="text"> should produce NULL when nothing has been entered.
<input type="number"> should produce an Int when a value has been entered.
You need to parse the input to suite your needs. Every form value in HTML in inherently a string.
The type attribute lets the browser know what kind of field to display, not what is the data type of the value. Take for example:
<input type="hidden" value="1">
HTML and javascript can infer no information about the data type from hidden it could be a string it could be an int.
number is equally problematic, why default to int, what about doubles and other number types?
In my example above, note that the value is surrounded by quotes, denoting a string. (Quotes are optional, but recommended, but do nothing to the data type.)
To actually solve your problem I would consider adding a data attribute to your fields, say data-type to hold the data type you want to cast your value to.
Here's a quick example:
var form_api = $("#apiForm");
$(form_api).submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
/* Get input values from form */
var formData = prepFormData("#apiForm");
console.log(formData);
});
function prepFormData(formSelector){
var form_api = $(formSelector);
// Serialize the form data as a PlainObject.
var formData = $(form_api).serializeArray().reduce(function (obj, item) {
var tempValue = null;
if(item.value !== "") {
//Get data type of current field
var dataType = $(form_api).find("[name=" + item.name + "]").data("type");
if(dataType === undefined) {
dataType = "text";
}
//Extend this based on the other data types you need
switch(dataType) {
case "text" :
tempValue = item.value;
break;
case "int" :
tempValue = parseInt(item.value, 10);
break;
case "float" :
tempValue = parseFloat(item.value);
break;
//Fall back for no data type defined, eg the select in this example
default :
tempValue = item.value;
break;
}
}
obj[item.name] = tempValue;
return obj;
}, {});
return formData;
}
label {display:block; margin-bottom:5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<form id="apiForm" method="get" action="">
<label>Name <input type="text" data-type="text" name="Name"></label>
<label>Integer <input type="number" data-type="int" name="Integer"></label>
<label>Float <input type="number" step="0.1" data-type="float" name="Float"></label>
<fieldset>
<legend>Age Range</legend>
<label><18 <input type="radio" data-type="text" name="AgeRange" value="<18"></label>
<label>>18 <input type="radio" data-type="text" name="AgeRange" value=">18"></label>
</fieldset>
<label>Country
<select name="country">
<option value="usa">USA</option>
<option value="aus">Australia</option>
<option value="other">Other</option>
</select>
</label>
<label>Product
<select name="ProductId" data-type="int">
<option value="1">Apple</option>
<option value="2">Orange</option>
<option value="11">Pear</option>
<option value="110">Pineapple</option>
</select>
</label>
<input type="hidden" data-type="text" name="HiddenText" value="">
<input type="submit">
</form>
This in normal JS behaviour. type number and text are for validations inside the input for browsers. They don't define the data-type of the value inside of them. By default they are strings. You can perform conversions for your use. The text field returns an empty string because it's by default an empty string and not null.

How to pass dynamic value to jquery validation function

I have a form which have some dynamically added input,
Here i input have total_amt = 100;
How can i, form should not submit until, sum of all the dynamically added inputs must be equal to total_amt
Here is my code.
$(function(){
var i = 1;
$('#add_more').click(function(event) {
event.preventDefault();
$('input.items').last().attr('name', 'item['+i+']');
$('#cart_items').append($('#tmp_cart').html());
$('input[name="item['+i+']"]').rules("add", {
required: true,
depositsSum : function(){
return $(this).val();
},
messages:'Sum of total items should be equal to 100',
});
i++;
});
$.validator.addMethod("depositsSum", function(value, element, params)
{
var amnts = 0;
$(params[0]).each(function() {
amnts += parseFloat($(this).val());
});
return amnts;
});
$("#myForm").validate({
rules: {
'item[0]': {
required:true
}
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/additional-methods.min.js"></script>
<form action="" method="POST" id="myForm">
Total Items<input type="text" value="100" name="total_amt" id="total_amt">
<div id="cart_items">
Items<input type="text" name="item[0]" class="items"><br/>
</div>
<button id="add_more">Add More</button>
<input type="submit" name="submit" value="submit">
</form>
<div id="tmp_cart" style="display: none;">
<label>
Items<input type="text" name="item[]" class="items">
</label><br/>
</div>
Two flaws in your code...
Within your .rules() method:
depositsSum : function(){
return $(this).val();
},
You're trying to set the parameter of you custom rule to the value of the field. This is complete nonsense. A parameter is something like Max: 10, where 10 is the parameter and it defines the rule; it's never the actual value of the field, which, by the way, always changes and is empty when the page loads. When you want to invoke the custom rule, set the parameter to true.
And related to the next problem...
Within your .addMethod() method:
$(params[0]).each(function() {
amnts += parseFloat($(this).val());
});
The params argument would be useless in your case, since the parameter can not be used for passing the dynamic values of other fields. Use a jQuery selector to grab the other fields. Since the name begins with item, use the "starts with" selector.
$('[name^="item"]').each(function() {
amnts += parseFloat($(this).val());
});

Input number and display the Input Fields according to the number inputed

I want to display the number of input box according to the number inputed in the how many.
My code is not working
<input id="howmany" />
<div id="boxquantity"></div>
Jquery/JavaScript
$(function() {
$('#howmany').change(function(){
for(i=0; i < $("#howmany").value; i++)
{
$('#boxquantity').append('<input name="boxid[]" type="file" id="boxid[]" size="50"/>');
}
});
});
I think the problem with the code is it's using .value on a jquery object. I replaced the $("#howmany").value with $("#howmany").val()
I also added a remove function to clear the number of inputs displayed.
Do run the snippet, thanks
$(document).ready(function() {
$('#howmany').change(function() {
$("#boxquantity input").remove();
for (i = 0; i < $("#howmany").val(); i++) {
$('#boxquantity').append('<input name="boxid['+i+']" type="file" id="boxid['+i+']" size="50"/>');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="howmany" />
<div id="boxquantity"></div>
Working code, without jQuery.
Built the HTML into a variable and then appended to the DOM in a single go.
var boxes = "";
document.getElementById("howmany").onchange = function() {
boxes = "";
var howmany = document.getElementById("howmany").value;
for(i=0;i<howmany;i++) {
boxes += '<b>File ' + i + '</b>: <input type="file" id="box' + i + ' name="box' + i + ' /><br/>';
}
console.log(boxes);
document.getElementById("boxquantity").innerHTML = boxes;
}
Here is a JSBin link.
Replace value with val. You can replace $("#howmany").value with $(this).val(). Also each input should have unique id
$(function() {
$('#howmany').change(function() {
for (let i = 0; i < $(this).val(); i++) {
$('#boxquantity').append('<input name="boxid[]" type="file" id="boxid[]_' + i + '" size="50"/>');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="howmany" />
<div id="boxquantity"></div>
1st: use type="number" for input
2nd: for realtime use on('input',) instead of .change event .change works like .on('blur' ,)
3rd: use .val() instead of .value
4th: you need to reset the #boxquantity div when number is change .. for me it'll be better to save the inputs html to variable then use .html() instead of .append() .. OR you can use $('#boxquantity').html(''); before the for loop
$(document).ready(function() {
$('#howmany').on('input',function() {
var Inputs = '';
for (var i = 0; i < $("#howmany").val(); i++) {
Inputs += '<input name="boxid[]" type="file" size="50"/>';
}
$('#boxquantity').html(Inputs);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" id="howmany" />
<div id="boxquantity"></div>

Jquery one button updates multiple input fields on form

I am trying to update two input fields in a form when clicking one button. I actually had all the code right when using document.getElementById, but the form that I'm using strips the ID's I set away, so I can't use getbyid. If I know the form field name, how could I change my function to do the same thing? Please note that my form has more than two fields, including a submit button, so I don't want to update those.
This is what I used before (with the ID selector)
Html:
<input type="text" name="field-1" id="info1">
<input type="text" name="field" id="info2">
Populate
JS:
function addTxt(val, id,no)
{
var id = id;
for(var i=1;i<=no;i++){
document.getElementById(id+i).value = val[i-1];
}
}
Fiddle:
http://jsfiddle.net/qwz47phx/3/
Edited with a much simpler and readable approach
function addVal(obj) {
event.preventDefault(); // Prevent page scrolltop on anchor click
$.each(obj, function(k, v) {
$("input[name='"+ k +"']").val( v );
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="foo">
<input type="text" name="bar">
<a href="#" onclick='addVal({foo:"Hello", "bar-baz":"World"})'>Populate</a>
Or with native JS (ES5+):
function addVal(obj) {
Object.keys(obj).forEach(function(name) {
document.querySelector('input[name="' + name + '"]').value = obj[name];
});
}
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="name-with-dashes">
<a href="#" onclick='addVal({foo:"Hello", bar:"World", "name-with-dashes": "Works !"})'>Populate</a>
If you have problems with IDs you can use querySelector to select inputs by name like this:
JS:
function addTxt(val, id, no) {
for (var i = 1; i <= no; i++) {
document.querySelector('input[name="' + id + i + '"]').value = val[i - 1];
}
}
HTML:
<input type="text" name="info1" id="info1">
<input type="text" name="info2" id="info2">
Populate
Demo: http://jsfiddle.net/iRbouh/qwz47phx/6/
I hope this will help you.
You can use a jQuery attribute= selector to grab by name instead of ID.
function addTxt(val, id,no)
{
for(var i=1;i<=no;i++){
var name = id+i;
$("input[name='"+name+"']").val(val[i-1]);
}
}
Please note that this function will be looking for names of info1, info2, info3, etc, just as your original script did. However, in the HTML, you have names of info and info-1. Either the names will have to be changed to fit the function, or the function can be slightly more intricate.
Fiddle: http://jsfiddle.net/qwz47phx/8/

Categories

Resources