I have few inputs, and it comes with values from 1 to 100 in it, but user can alter those values. I have sorted my inputs in Ascending order. Now I want that each time user changes an input, they should be re-arranged in ascending order.
Here is my HTML template:
var sortedArray = $("div[class^='wrap_']").get().sort(function(a, b) {
var idx = parseInt($(a).find(".sort_by").val(),10);
var idx2 = parseInt($(b).find(".sort_by").val(),10);
return idx > idx2;
});
$(sortedArray).appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap_0">
<input class="sort_by" value="10"/>
</div>
<div class="wrap_1">
<input class="sort_by" value="3"/>
</div>
<div class="wrap_2">
<input class="sort_by" value="7"/>
</div>
Right now they appear as:
3
7
10
if user changes 3 to 12, I want my output to be automatically changed to:
7 10 12.
I want Jquery solutions only. Thanks in advance.
$(document).ready(function(){
sort();
$(".sort_by").change(function(){
sort();
});
function sort(){
var sortedArray = $("div[class^='wrap_']").get().sort(function(a, b) {
var idx = parseInt($(a).find(".sort_by").val(),10);
var idx2 = parseInt($(b).find(".sort_by").val(),10);
return idx > idx2;
});
console.log(sortedArray);
$(sortedArray).appendTo("body");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrap_0">
<input class="sort_by" value="10"/>
</div>
<div class="wrap_1">
<input class="sort_by" value="3"/>
</div>
<div class="wrap_2">
<input class="sort_by" value="7"/>
</div>
There...you change a value and press enter...your sort code is executed.
You can use the input event and apply the sort method on the parent div jQuery collection. Please note that I added class wrap so the divs can be easily selected. The code .trigger('input') ensures that the input (actually parent div) elements are sorted when the page loads.
$(function() {
$('.sort_by').on('focusout', function() {
var arr = $('div.wrap');
arr = arr.sort(function(a,b) {
return +$(a).find('.sort_by').val() - +$(b).find('.sort_by').val();
});
$('body').append( arr );
})
.trigger('focusout');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap_0 wrap">
<input class="sort_by" value="10"/>
</div>
<div class="wrap_1 wrap">
<input class="sort_by" value="3"/>
</div>
<div class="wrap_2 wrap">
<input class="sort_by" value="7"/>
</div>
Related
I have a problem with the script.
I am trying to count two input fields, and insert the result into the third field.
But it doesn't work, and unfortunately I can't figure out what's wrong.
function sum() {
var txtFirstNumberValue = document.querySelectorAll('#firstID > div > div > div > input').value;
var txtSecondNumberValue = document.querySelectorAll('#second > div > div > div > input').value;
if (txtFirstNumberValue == "")
txtFirstNumberValue = 0;
if (txtSecondNumberValue == "")
txtSecondNumberValue = 0;
var result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelectorAll('#third > div > div > div > input').value = result;
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
</div></div>
There are a few problems here.
Are you actually calling sum? I've added a call in the example code so you can run it.
Your query selectors are not right. There isn't actually anything in the divs with the IDs you query. I've moved the input boxes into the correct places. When debugging, you should check that you are actually finding elements in your querySelectorAll call before proceeding.
querySelectorAll doesn't have a value property. You would need to iterate over each element before getting the items. Given you specifically want one item, it would be better to use something more specific like getElementById. I've kept the original querySelectorAll but changed the IDs on the divs to classes so we can have more than one result for this example. Then, I iterate over them pulling out the value to add to result. I've moved the parseInt to the running calculation otherwise it would perform a string concatenation.
Even better than the above would be to access the input directly. There's probably no point accessing a div and drilling down to the input. I've included this example to output the result.
I've removed redundant html. It's not related to the answer but try to keep your markup clean.
function sum() {
var inputElements = document.querySelectorAll('.user-input > div > div > input');
var result = 0;
inputElements.forEach(element => {
result += element.value ? parseInt(element.value) : 0
})
document.getElementById('third').value = result
}
document.getElementById('run-button').addEventListener('click', sum)
<div class="user-input">
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" maxlength="255">
</div>
</div>
<div>
<div class="user-input">
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
<div>
<label>third</label>
<div>
<div>
<input id="third" name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
<div>
<button type="button" id="run-button">Run</button>
Try like this
function sum() {
let txtFirstNumberValue = document.querySelector('#firstID input').value;
let txtSecondNumberValue = document.querySelector('#second input').value;
let result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelector('#third input').value = result;
} else {
document.querySelector('#third input').value = '';
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255" disabled>
<div></div>
</div>
</div>
<div>
<button id="button" onclick="sum()">Calculate</button>
</div>
</div>
</div>
const input1 = document.querySelector('#input1');
const input2 = document.querySelector('#input2');
const input3 = document.querySelector('#input3');
const storeInputs = [input1, input2];
for(let i = 0; i < storeInputs.length; i++) {
storeInputs[i].addEventListener('input', function() {
// multiply input1 and input2 with 1 for converting there values from string to number
input3.value = input1.value * 1 + input2.value * 1;
});
};
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<label for="input1">First Input</label>
<input id="input1" type="number" value="0"></input>
<label for="input2">Second Input</label>
<input id="input2" type="number" value="0"></input>
<label for="input3">Third Input</label>
<input id="input3" type="number" value="0"></input>
</body>
</html>
I have two radio buttons:
fixed_price_option (Selected by default.)
variable_price_option (Disabled by default)
I also have two types of inputs:
fixed_price_input (Visable by default. Only one occurance.)
variable_price_input (Not present in code as it has to be added dynamically. One or more occurances.)
When fixed_price_option is selected an input called fixed_price_input should be visable and included when later running .serialize().
When fixed_price_option is selected no variable_price_input´s should be visible or included when later running .serialize().
variable_price_option should only be selectable when the difference between two date inputs are more than 12 months. (this I have solved)
When variable_price_option is selected there should be one more variable_price_input´s visable as there are whole years between the two date inputs (i.e. durationMonths + 1). They also need to be included when later running .serialize() so they need to have names like price_year_1, price_year_2, price_year_3 and so on, depending on how many whole years there are between the two date inputs.
When variable_price_option is selected fixed_price_input should not be visible or included when later running .serialize().
I have supplied the code as far as I have come. The missing logic needs to be put in the event handler at the bottom of the js code.
Any suggestions on how to solve this?
-- UPDATE --
My question needed clarification:
What I'm struggling with is to toggle the existence of the two types of inputs (fixed_price_input and variable_price_input) depending on which radio button is checked. Hiding/showing them isn't enough because I'm going to use .serialize() at a later point. Should I use .detach() and .append() somehow?
I'm also struggling with how to create one more variable_price_input's than there are years between the start and end date. Should I use <template> or .clone() somehow?
$(document).ready(function() {
$("#inputStartDate, #inputEndDate").change(function() {
if ($('#inputStartDate').val() && $('#inputEndDate').val()) {
var startDate = moment($('#inputStartDate').val());
var endDate = moment($('#inputEndDate').val());
var durationMonths = endDate.diff(startDate, 'months');
$('#durationMonths').text(durationMonths);
var durationYears = endDate.diff(startDate, 'years');
$('#durationYears').text(durationYears);
if (duration > 12) {
$('#variablePriceOption').prop("disabled", false);
} else {
$('#variablePriceOption').prop("disabled", true);
}
}
});
$('#variablePriceOption, #fixedPriceOption').change(function() {
if (this.value == 'fixedPrice') {
//Logic needed
} else if (this.value == 'variablePrice') {
//Logic needed
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<div class="container">
<div class="row mt-3">
<div class="col">
<div class="form-group">
<label for="inputStartDate">Start date</label>
<input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date">
</div>
</div>
<div class="col">
<div class="form-group">
<label for="inputEndDate">End date</label>
<input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date">
</div>
</div>
</div>
<div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>.
</div>
<div class="form-group">
<label for="inputPriceModel">Price model</label>
<div id="inputPriceModel">
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked">
<label class="form-check-label" for="fixedPriceOption">
Fixed price
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled">
<label class="form-check-label" for="variablePriceOption">
Variable price
</label>
</div>
</div>
</div>
<div class="form-group fixedPriceModelFormGroup">
<label for="fixed_price_input">Fixed price amount</label>
<div class="input-group">
<input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
</div>
This should help get you started as far as variable pricing inputs showing for each # of year difference of the calendar dates. The code could be broken out into other functions for handling the display/hiding of elements, etc. You need to move your <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> code above your other JS references to get rid of the errors you're seeing for bootstrap.
Also, your duration variable should be durationMonths for comparing > 12, as duration is undefined. durationYears should be moved outside the change function of the calendar dates so you can reference it in your other processing functions. I added Math.abs() to the date calculations to ensure you're dealing with a positive integer for comparisons.
Using the disabled attribute on the inputs that are hidden will allow you to serialize the visible form data and ensure you won't get hidden inputs (variable pricing fields, etc) as part of the serialization data.
As #Twisty mentioned in the comments on your post, you will want to use .detach() or some sort of way to store the variable pricing input values if you toggle back and forth between Fixed/Variable options (localStorage, sessionStorage also options for storing data), if you want to maintain any values placed in the variable/fixed inputs. You will need to remove the .empty() usage on the input fields in my example as well, if you intend to store the data values of the inputs.
The loop function handleVariablePricing for determining how many variable pricing inputs should show would need to hook into the stored data functionality to ensure you are creating the same amount of fields with previously entered values, and not adding additional new fields on top of the existing fields/values.
$(document).ready(function() {
var durationYears = 0;
$("#inputStartDate, #inputEndDate").change(function() {
if ($('#inputStartDate').val() && $('#inputEndDate').val()) {
var startDate = moment($('#inputStartDate').val());
var endDate = moment($('#inputEndDate').val());
var durationMonths = Math.abs(endDate.diff(startDate, 'months'));
$('#durationMonths').text(durationMonths);
// maintain value outside of change function
durationYears = Math.abs(endDate.diff(startDate, 'years'));
$('#durationYears').text(durationYears);
if (durationMonths > 12) {
$('#variablePriceOption').prop("disabled", false);
} else {
$('#variablePriceOption').prop("disabled", true);
}
// If dates changed, update variable inputs shown
if ($('#variablePriceOption').is(':checked')) {
if (durationMonths > 12) {
$('#variable_price_input_1').val('');
$('.duration-years-input').remove();
handleVariablePricing();
} else {
$('#fixedPriceOption').click();
}
}
}
});
$('#variablePriceOption, #fixedPriceOption').change(function() {
if (this.value == 'fixedPrice') {
$('.variablePriceModelFormGroup').removeClass('d-block').addClass('d-none');
$('.variablePriceModelFormGroup input').each(function() {
$(this).val('').attr('disabled', true);
});
$('.fixedPriceModelFormGroup input').prop('disabled', false);
$('.fixedPriceModelFormGroup').removeClass('d-none').addClass('d-block');
$('.duration-years-input').remove();
} else if (this.value == 'variablePrice') {
$('.fixedPriceModelFormGroup').removeClass('d-block').addClass('d-none');
$('.fixedPriceModelFormGroup input').val('').attr('disabled', true);
$('#variable_price_input_1').prop('disabled', false);
$('.variablePriceModelFormGroup').removeClass('d-none').addClass('d-block');
handleVariablePricing();
}
});
/**
* Creates inputs for variable pricing..
**/
var handleVariablePricing = function() {
$rowClone = $('.row-main').clone();
for (var i = 2; i <= durationYears + 1; i++) {
$rowClone.prop('class', 'duration-years-input');
$rowClone.find('label').text('Price Year ' + i);
$rowClone.find('input').prop('id', 'variable_price_input_' + i);
$rowClone.find('input').prop('name', 'land_contract_variable_annual_price_' + i);
if ($('.duration-years-input').length === 0) {
$('.row-main').after($rowClone);
} else {
$('.duration-years-input').last().after($rowClone);
}
$rowClone = $('.duration-years-input').last().clone();
}
};
$('button').click(function() {
console.log($('#test-form').serialize());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<div class="container">
<form id="test-form">
<div class="row mt-3">
<div class="col">
<div class="form-group">
<label for="inputStartDate">Start date</label>
<input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date">
</div>
</div>
<div class="col">
<div class="form-group">
<label for="inputEndDate">End date</label>
<input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date">
</div>
</div>
</div>
<div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>.
</div>
<div class="form-group">
<label for="inputPriceModel">Price model</label>
<div id="inputPriceModel">
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked">
<label class="form-check-label" for="fixedPriceOption">
Fixed price
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled">
<label class="form-check-label" for="variablePriceOption">
Variable price
</label>
</div>
</div>
</div>
<div class="form-group fixedPriceModelFormGroup">
<label for="fixed_price_input">Fixed price amount</label>
<div class="input-group">
<input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
<div class="form-group variablePriceModelFormGroup d-none">
<div class="row-main">
<label for="variable_price_input">Price Year 1</label>
<div class="input-group">
<input type="number" class="form-control" id="variable_price_input_1" name="land_contract_variable_annual_price_1" disabled="disabled">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
</div>
</form>
<button>Serialize</button>
</div>
I am trying to get all the values of the input fields. The issue is all of the <input type=radio/> are dynamic and can increase or decrease at any time.
So I am starting with the main DI and going from there. The problem I have now is I am not getting the input radio buttons values.
So here are the steps I am intending to accomplish:
If any radio button is selected, pass its value to the checkbox value,
If the radio button is selected and the checkbox is not selected, do not pass to the checkbox value
I am looking for a solution in JavaScript only - do not use jQuery
Here is my jsFiddle code
HTML
<div style="display: block;" id="mymainDiv" class="fullFloat">
<input type="hidden" value="1" id="startIdxShMdeCarWisevId" name="startIdxShMdeCarWise">
<div class="subTitle">UPS<a class="fRight" onclick="localG('10',false,0,false,'UPS','1','$');" href="javascript:void(0);">Show Prices</a></div>
<div style="display:none;" id="Wheel_UPS"><div class="loadingcheckout"></div></div>
<div id="Price_UPS">
</div>
<div class="wrapLeft wrapClear">
<div class="wrapleft">
<label class="">
<input type="radio" value="11098" id="deliveryMethodId_1" name="deliveryMethodId" class="section" data-mask="" data-rev="" data-rel="false" data-carrier="">
<span>
UPS Ground (Order by 9:30 PM EST)
</span>
<div class="wrapRight">
<div id="UPS_11098">
</div>
</div>
</label>
</div>
<input type="text" value="1" id="UPS">
</div>
<input type="hidden" value="2" id="startIdxShMdeCarWisevId" name="startIdxShMdeCarWise">
<div class="subTitle">Standard<a class="fRight" onclick="localG('20',false,0,false,'Standard','2','$');" href="javascript:void(0);">Show Prices</a></div>
<div style="display:none;" id="Wheel_Standard"><div class="loadingcheckout"></div></div>
<div id="Price_Standard">
</div>
<div class="wrapLeft wrapClear">
<div class="wrapleft">
<label class="">
<input type="radio" value="11117" id="deliveryMethodId_2" name="deliveryMethodId" class="section" data-mask="" data-rev="" data-rel="false" data-carrier="">
<span>
Standard Delivery - 2-3 Day Delivery at Ground Rate (Order by 9:30 PM EST)
</span>
<div class="wrapRight">
<div id="Standard_11117">
</div>
</div>
</label>
</div>
<input type="text" value="1" id="Standard">
</div>
<input type="hidden" value="3" id="startIdxShMdeCarWisevId" name="startIdxShMdeCarWise">
<div class="subTitle">FedEx<a class="fRight" onclick="localG('190',false,0,false,'FedEx','3','$');" href="javascript:void(0);">Show Prices</a></div>
<div style="display:none;" id="Wheel_FedEx"><div class="loadingcheckout"></div></div>
<div id="Price_FedEx">
</div>
<div class="wrapLeft wrapClear">
<div class="wrapleft">
<label class="">
<input type="radio" value="11088" id="deliveryMethodId_3" name="deliveryMethodId" class="section" data-mask="" data-rev="" data-rel="false" data-carrier="">
<span>
FedEx Ground (Order by 8:00 PM EST)
</span>
<div class="wrapRight">
<div id="FedEx_11088">
</div>
</div>
</label>
</div>
<input type="text" value="1" id="FedEx">
</div>
</div>
<input type="checkbox" name="shipmode" id="shipmode" value="" onclick="getpref('mymainDiv');">Get Value
JS Code
This executes when the checkbox is clicked:
function getpref(val) {
var wr = document.getElementById(val);
childElements = wr.childNodes;
//alert(childElements);
for(var i = childElements.length-1; i>=0; i--){
var elem = childElements[i];
console.log(elem.id);
if(elem.id && elem.id.indexOf(val+'_')==0){
elem.style.display = 'block';
}
}
//alert(val);
}
You can directly access input nodes in your DIV with getElementsByTagName
function getpref(val) {
var divNode = document.getElementById(val);
var inputNodes = divNode.getElementsByTagName('INPUT');
for(var i = 0; i < inputNodes.length; ++i){
var inputNode = inputNodes[i];
if(inputNode.type == 'radio') {
//Do whatever you want
if(inputNode.checked) {
//Do whatever you want
}
}
}
}
Example: http://jsfiddle.net/88vp0jLw/1/
You can use getElementsByName to get you all of the radio buttons by name='deliveryMethodId' and then go from there:
function getpref(val) {
var radioButtons = document.getElementById(val).getElementsByName("deliveryMethodId");
for(var i = radioButtons.length-1; i>=0; i--)
{
var radioButton = radioButtons[i];
if(radioButton.checked)
console.log(radioButton.id + " is selected ");
}
}
My question is how to serialize checkbox value and textbox value together in one array through searilizedarray()...
now i am getting something like this
[{"name":"text_input","value":"kalpit"},
{"name":"wpc_chkbox[]","value":"Option one"},
{"name":"wpc_chkbox[]","value":"Option two"},
{"name":"wpc_chkboxasdf[]","value":"Option one"},
{"name":"wpc_chkboxasdf[]","value":"Option two"},
{"name":"wpc_inline_chkbox[]","value":"1"},
{"name":"wpc_inline_chkbox[]","value":"2"},
{"name":"wpc_inline_chkbox[]","value":"3"},
{"name":"wpc_radios","value":"Option one"}]
but it should be like
[{"name":"text_input","value":"kalpit"},
{"name":"wpc_chkbox[]","value":"[Option one,Option Two]"},
{"name":"wpc_chkboxasdf[]","value":"[Option one,Option Two]"},
{"name":"wpc_inline_chkbox[]","value":"[1,2,3]"},
{"name":"wpc_radios","value":"Option one"}]
i am using var form = $('.wpc_contact').serializeArray(); to get form data
this is my html sample which I am generating dynamically using drag and drop future..
<form method="POST" name="1" class="form-horizontal wpc_contact" novalidate="novalidate">
<fieldset>
<div id="legend" class="">
<legend class="">Demo</legend>
<div id="alert-message" class="alert hidden" style="color: red;"></div>
</div>
<div class="control-group">
<label class="control-label">Checkboxes</label>
<div class="controls" name="wpc_chkbox" req="yes">
<input type="checkbox" value="Option one" id="wpc_chkbox_0" name="wpc_chkbox[]" req="yes"> Option one
<input type="checkbox" value="Option two" id="wpc_chkbox_1" name="wpc_chkbox[]" req="yes"> Option two
</div>
</div>
<div class="control-group">
<div class="controls" name="wpc_inline_chkbox" req="yes">
<input type="checkbox" value="1" name="wpc_inline_chkbox[]" id="wpc_inline_chkbox_0" req="yes"> 1
<input type="checkbox" value="2" name="wpc_inline_chkbox[]" id="wpc_inline_chkbox_1" req="yes"> 2
<input type="checkbox" value="3" name="wpc_inline_chkbox[]" id="wpc_inline_chkbox_2" req="yes"> 3
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-success">Button</button>
</div>
</div>
</fieldset>
</form>
Thanks in advance
Try this:
var cacheObject = {};//tmp cache for form elements name/values pairs
var serArr = $('.wpc_contact').serializeArray();
//set values of elements to cacheObject
$.each(serArr, function (arrayIndex,obj) {
if (cacheObject[obj.name]) {
cacheObject[obj.name].push(obj.value);
} else {
cacheObject[obj.name] = [obj.value];
}
});
//create new serialized array
var newSerArr = [];
$.each(cacheObject, function (key, value) {
var obj = {};
obj[key] = value;
newSerArr.push(obj);
});
console.log(newSerArr);//looks like serializeArray
This one makes a different array and elements of same name are grouped together.
var form_data = $(".wpc_contact").serializeArray();
var form_array = {}; //final array where all the values will be stored
$.each(form_data, function(i, element) {
if(jQuery('input[name="'+element.name+'"]:checked').length>0)
{
replaced = element.name.replace('[]',''); //removing [] from the input name
form_array[replaced]={};
jQuery('input[name="'+element.name+'"]:checked').each(function(j,ind){
form_array[replaced][j] = jQuery(this).val();
});
}
else
{
form_array[element.name] = element.value;
}
});
console.log(form_array);
You can access as:
alert(form_array['wpc_chkbox'][0]); //no '[]' in the key
I have a set of number fields, each with a class "product-quantity", and a set of empty divs. the number fields are set with a data-attr small, medium, and goes up to 5xl. The empty div's are set with a data-attr small, medium, and goes up to 5xl as well because the small number field is associated with the small div and so one.
When you increase or decrease the number inside the small number field a div "small" should insert after the empty div with the attr small.
When you increase or decrease the number inside the medium number field a div "medium" should insert after the empty div with the attr medium.... and so on
additionally, all of the above belongs to a product x container, and there are multiple products on a page.
I have this jsfiddle that simulates what I am trying to do:
http://jsfiddle.net/7PhJZ/25/
however, right now when I add/subtract a number to the small number fields, it adds/subtracts a div to both the empty small/ medium div as well as in both products. and same for the medium.
I am having a hard time trying to associate which number field belongs to which empty div, which belongs to which product.
html:
<div id="product-1">
<div class="size-field">
<div id="size-label">
s
</div>
<div class="number-input">
<input id="Small" class="product-quantity" type="number" name="Small" min="0"
max="9999" data-product-id="1">
</input>
</div>
</div>
<div id="size-label">
m
</div>
<div class="number-input">
<input id="Medium" class="product-quantity" type="number" name="Medium"
min="0" max="9999" data-product-id="1">
</input>
</div>
<div class="name-number-header"><h5>HEADER<h5></div>
<div class="name-number-field-container" data-size="Small">small:
</div>
<div class="name-number-field-container" data-size="Medium">medium:
</div>
</div>
<br clear="all">
<div id="product-2">
<div class="size-field">
<div id="size-label">
s
</div>
<div class="number-input">
<input id="Small" class="product-quantity" type="number" name="Small" min="0"
max="9999" data-product-id="2">
</input>
</div>
</div>
<div id="size-label">
m
</div>
<div class="number-input">
<input id="Medium" class="product-quantity" type="number" name="Medium"
min="0" max="9999" data-product-id="2">
</input>
</div>
<div class="name-number-header"><h5>HEADER<h5></div>
<div class="name-number-field-container" data-size="Small">small:
</div>
<div class="name-number-field-container" data-size="Medium">medium:
</div>
</div>
js:
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'}).insertAfter($("[data-size]"));
}
});
$('.product-quantity').on('change', function () {
var val = $(this).val(),
ele = $(this).closest('[id^="product"]').find('[data-size="'+this.name+'"]');
ele.nextUntil('[data-size]').remove();
for (var i = 0; i < parseInt(val); i++) {
$('<div/>', {
'class': 'name-number-field'
}).insertAfter(ele);
}
});
FIDDLE
EDIT:
Based on the comments, what you're really trying to do is just add one if the value increments, and remove the last if the value decrements, and for that the approach would be somewhat different:
$('.product-quantity').each(function() {
$(this).data('val', this.value);
}).on('change', function () {
var val = $(this).val(),
old = $(this).data('val'),
ele = $(this).closest('[id^="product"]').find('[data-size="'+this.name+'"]'),
inc = val >= old;
if (inc) {
$('<div/>', {
'class': 'name-number-field'
}).insertAfter(ele);
}else {
$('.name-number-field', ele.parent()).last().remove();
}
$(this).data('val', this.value);
});
FIDDLE
Make Use of your data-product-id and hook the textbox's parent and target the required elements.
Try this,
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'})
.insertAfter($(this).parents('#product-' + $(this).data('product-id')).find("[data-size]"));
}
});
DEMO
Edit:
$('.product-quantity').on('change',function(){
$('.name-number-field').remove();
var val = $(this).val();
for (var i = 0; i < parseInt(val); i++){
$('<div/>',{'class':'name-number-field'})
.insertAfter($(this).parents('#product-' + $(this).data('product-id')).find("[data-size='"+ $(this).attr('name') +"'][data-size]"));
}
});
NEW - DEMO