I have a form that looks like this:
<form>
<input name="foo" value="1" />
<input name="bar[1]" value="a" />
<input name="bar[2]" value="b" />
<input name="bar[3]" value="c" />
<select name="test" multiple>
<option value="1" selected>a</option>
<option value="2" selected>b</option>
<option value="3" selected>c</option>
</select>
</form>
I can serialize the form like this:
$('form').serialize();
Which produces:
"foo=1&bar%5B1%5D=a&bar%5B2%5D=b&bar%5B3%5D=c&test=1&test=2&test=3"
I would like to serialize the select elements as dictionaries, producing this instead:
"foo=1&bar%5B1%5D=a&bar%5B2%5D=b&bar%5B3%5D=c&test%5B1%5D=a&test%5B2%5D=b&test%5B3%5D=c"
This is what I have so far:
function serializeSelectListAsDictionary() {
var name = $(this).attr('name'),
obj = {};
if (!$(this).is('select') || !name) {
return '';
}
$(this).children('option:selected').each(function() {
var key = name + '[' + $(this).val() + ']',
value = $(this).html();
obj[key] = value;
});
return $.param(obj);
}
$.fn.serializeDictionary = function() {
var serialized;
if (this.is('select')) {
return serializeSelectListAsDictionary.apply(this);
}
serialized = this.serialize();
this.find('select').each(function() {
serialized = serialized.replace($(this).serialize(), serializeSelectListAsDictionary.apply(this));
});
return serialized;
};
This works well enough when I call it like this:
$('form').serializeDictionary();
But a problem arises when I try to select multiple elements. Say I added another select element to the form:
<form>
<input name="foo" value="1" />
<input name="bar[1]" value="a" />
<input name="bar[2]" value="b" />
<input name="bar[3]" value="c" />
<select name="test" multiple>
<option value="1" selected>a</option>
<option value="2" selected>b</option>
<option value="3" selected>c</option>
</select>
<select name="blah" multiple>
<option value="4" selected>d</option>
<option value="5" selected>e</option>
<option value="6" selected>f</option>
</select>
</form>
Then if I call my extension method like this:
$('select').serializeDictionary();
It produces:
"test%5B1%5D=a&test%5B2%5D=b&test%5B3%5D=c&test%5B4%5D=d&test%5B5%5D=e&test%5B6%5D=f"
The output should look like this:
"test%5B1%5D=a&test%5B2%5D=b&test%5B3%5D=c&blah%5B4%5D=d&blah%5B5%5D=e&blah%5B6%5D=f"
I think my serializeSelectListAsDictionary function is only being called on the first element, but I'm not sure how to fix this.
Fiddle: http://jsfiddle.net/t5aze4r9/1
The problem is on the serializeDictionary function. It assumes that it will only receive one element to serialize. It works in the case of $('form').serializeDictionary(); because it only matches one form element. But if you had two form you'll see the same issue as with $('select').serializeDictionary();.
The issue shows up when the selector is matching more than one element because you are only serializing the first one. You need some kind of iteration over the matched elements.
Here is a proposal that tries to keep as much as possible your code structure:
$.fn.serializeDictionary = function() {
var serialized = this.serialize();
// Here is the key! You need to iterate over all the matched elements.
this.each(function() {
if ($(this).is('select')) {
serialized = serialized.replace($(this).serialize(), serializeSelectListAsDictionary.apply(this));
} else {
$(this).find('select').each(function() {
serialized = serialized.replace($(this).serialize(), serializeSelectListAsDictionary.apply(this));
});
}
});
return serialized;
};
See updated code.
Related
I have the following code that is not working the way i want it to, apparently, am trying to multiply select option data attributes with input text area values but instead select option value are being used. I need to figure out why its so.
Here is my code;
<input id="count" min="1" value="1" class ="txtMult form-control" type="number" name="txtEmmail" />
<input type="text" value="" class ="txtMult" name="txtEmmail"/>
<span class="multTotal"></span>
<select class="selectpicker">
<option value="1" data-cubics='1'>multiply with 1</option>
<option value="5" data-cubics='5'>multiply with 5</option>
</select>
<span id="grandTotal">250</span>
$(function(){
$('.txtMult').change(function(){
var p=$(this).parent().parent()
var m=p.find('input.txtMult')
var mul=parseInt($(m[0]).val()*$(m[1]).val()).toFixed(2)
var res=p.find('.multTotal')
res.html(mul);
var total=0;
$('.multTotal').each(function(){
total+=parseInt($(this).html());
})
parseInt(total).toFixed(2);
$('#grandTotal').html(parseInt(total).toFixed(2));
});
})
$('.selectpicker').change(function() {
calcVal();
});
function calcVal(){
$(this).data('cubics')*$('.multTotal').html();
$("#grandTotal").html($(this).data('cubics')*$('.multTotal').html())
}
// call on document load
calcVal();
Don't use .html() to get the values, use .text() instead.
You need to get the selected option using this:
$("#grandTotal").html($(this).children(':checked')
$(function() {
$('.txtMult').change(function() {
var p = $(this).parent().parent()
var m = p.find('input.txtMult')
var mul = parseInt($(m[0]).val() * $(m[1]).val()).toFixed(2)
var res = p.find('.multTotal')
res.html(mul);
var total = 0;
$('.multTotal').each(function() {
total += parseInt($(this).text());
})
parseInt(total).toFixed(2);
$('#grandTotal').html(parseInt(total).toFixed(2));
});
})
$('.selectpicker').change(calcVal);
function calcVal() {
$("#grandTotal").html($(this).children(':checked').data('cubics') * $('.multTotal').text().trim())
}
// call on document load
calcVal();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div>
<input id="count" min="1" value="1" class="txtMult form-control" type="number" name="txtEmmail" />
<input type="text" value="" class="txtMult" name="txtEmmail" />
<span class="multTotal"></span>
<select class="selectpicker">
<option value="1" data-cubics='1'>multiply with 1</option>
<option value="5" data-cubics='5'>multiply with 5</option>
</select>
<span id="grandTotal">250</span>
</div>
</div>
Demo
Trying to change the input ID: List from A to B, but its not changing.
I am planning on creating many datalist with PHP from MySQL,
Select Company name, and see their employees in next list.
HTML:
change List:
<input type="text" id="List" list="A">
<br>
<br>
<input type="text" id="A" value="B">
<br>
<button onclick="change()">
Change List
</button>
<datalist id="A">
<option value="None">
<option value="1">
<option value="2">
</datalist>
<datalist id="B">
<option value="3">
<option value="4">
</datalist>
JAVASCRIPT:
function change() {
console.log("Started");
var x = document.getElementById('A').value;
document.getElementById('List').list = x;
var check = document.getElementById('List').list
if (check === x) {
console.log("Complete");
} else {
console.log("Failed");
}
}
Thank you, its now working.
Working
According to the Mozilla Developer Network docs, the list attribute is read-only and actually returns a reference to a DOM element (like a <datalist>):
list [Read only]
HTMLElement object: Returns the element pointed by the list attribute.
The property may be null if no HTML element found in the same tree.
Thus, you need to use setAttribute to set the list by id, and then use element.list.id to retrieve the correct value for check.
function change() {
console.log("Started")
var x = document.getElementById('A').value
document.getElementById('List').setAttribute('list', x)
var check = document.getElementById('List').list.id
if (check === x) {
console.log("Complete");
} else {
console.log("Failed");
}
}
change List:
<input type="text" id="List" list="A">
<br>
<br>
<input type="text" id="A" value="B">
<br>
<button onclick="change()">
Change List
</button>
<datalist id="A">
<option value="None">
<option value="1">
<option value="2">
</datalist>
<datalist id="B">
<option value="3">
<option value="4">
</datalist>
Since list is not a standard attribute, direct refering with the dot notation won't work. Use getAttribute and setAttribute functions instead.
function change() {
console.log("Started");
var x = document.getElementById('C'),
list = document.getElementById('List'),
check = list.getAttribute(list);
list.setAttribute('list', x);
if (check === x.getAttribute('list')) {
console.log("Complete");
} else {
console.log("Failed");
}
}
<input type="text" id="List" list="A">
<br>
<br>
<input type="text" id="C" value="B">
<br>
<button onclick="change()">
Change List
</button>
<datalist id="A">
<option value="None">
<option value="1">
<option value="2">
</datalist>
<datalist id="B">
<option value="3">
<option value="4">
</datalist>
Javascript
function change() {
document.getElementById('List').setAttribute('list', document.getElementById('A').id);
}
You need to set the value property on the dom element
document.getElementById('List').value = x;
var check = document.getElementById('List').value
if (check === x) {
console.log("Complete");
} else {
console.log("Failed");
console.log(check);
}
}
Im trying to get value from checkbox that has been checked, but for some reason the value is shuffled in some weird pattern
here jsfiddle (try to check fruit and then click disable)
<input id="checkedTree" type="text"/>
<select id="test-select" onchange="getCheckedTree()">
<option value="1" data-section="fruit">Banana</option>
<option value="2" data-section="fruit">Apple</option>
<option value="3" data-section="fruit">Avocado</option>
<option value="4" data-section="fruit">Pineapple</option>
<option value="5" data-section="fruit">PenPineappleApplePen</option>
<option value="6" data-section="animal">Tiger</option>
<option value="7" data-section="animal">Lion</option>
<option value="8" data-section="animal">Pitbull</option>
<option value="9" data-section="animal">OrangUtan</option>
<option value="10" data-section="animal">Marsupilami Yellow cartoon</option>
</select>
I need to know why is it happened, and how to fix it. i do know the other way to get proper value like this. But for my project case i need "for" method
Update 1-> update jsfiddle
Values shuffled because you are getting the input array index checkedText.value = selectobject[z].value; knowing that at the change event the order of your hidden inputs change which causes the wrong values . (you can check by setting test-select display :block after page loding )
Above a working snippet :
note that you can passe directly value (1,2,3.. ) to the checkedTree input to disable directly inputs .
$( document ).ready(function() {
var $select = $('#test-select');
$select.treeMultiselect({
enableSelectAll: true,
sortable: false,
searchable: true,
startCollapse: true
});
});
function getCheckedTree(){
var tempCtr=0;
var $checkedText = $("#checkedTree");
var selectobject = $("[id*=treemultiselect-0-]:checked");
$checkedText.val("");
for(i=0;i<selectobject.length;i++) {
if(tempCtr==0){
tempCtr=1;
$checkedText.val($(selectobject[i]).parent().data("value"));
}else{
$checkedText.val($checkedText.val() + $(selectobject[i]).parent().data("value"));
}
}
}
function funcDis(){
var $checkedText = $("#checkedTree");
if($checkedText.val().length>0) {
$checkedText.val().split("").forEach(function(val){
$(".tree-multiselect .item[data-value="+val+"] input").prop('disabled', true);
$("#test-select option[value="+val+"]").prop('disabled', true);
})
};
}
function enableAll(){
$(".tree-multiselect input").each(function(idx){
$(this).prop('disabled', false);
var val = $(this).parent().data("value");
$("#test-select option[value="+val+"]").prop('disabled', false);
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<link href="//cdn.rawgit.com/patosai/tree-multiselect/v2.1.3/dist/jquery.tree-multiselect.min.css" rel="stylesheet"/>
<script src="//cdn.rawgit.com/patosai/tree-multiselect/v2.1.3/dist/jquery.tree-multiselect.min.js"></script>
<input id="checkedTree" type="text"/> <button onclick="funcDis()">disable</button><button onclick="enableAll()">enable all</button>
<select id="test-select" onchange="getCheckedTree()">
<option value="1" data-section="fruit">Banana</option>
<option value="2" data-section="fruit">Apple</option>
<option value="3" data-section="fruit">Avocado</option>
<option value="4" data-section="fruit">Pineapple</option>
<option value="5" data-section="fruit">PenPineappleApplePen</option>
<option value="6" data-section="animal">Tiger</option>
<option value="7" data-section="animal">Lion</option>
<option value="8" data-section="animal">Pitbull</option>
<option value="9" data-section="animal">OrangUtan</option>
<option value="10" data-section="animal">Marsupilami Yellow cartoon</option>
</select>
PS:You can pass dirctly an array of value to funcDis and disable input at start up .
That's all ,I fiddle if you want.
I have a page that creates a number of inputs based on the user's selection of how many to create:
select id="noOfDirectors" name="amount" onchange="addInput();">
<option value="">How Many Directors</option>
<option value="1" >1</option>
<option value="2" >2</option>
<option value="3" >3</option>
<option value="4" >4</option>
<option value="5" >5</option>
<option value="6" >6</option>
<option value="7" >7</option>
<option value="8" >8</option>
<option value="9" >9</option>
<option value="10" >10</option>
</select>
<div id="inputs"></div><br/>
<button id="nod" onclick="return false">Submit</button>
The .js file creates the forms:
function addInput(){
noOfDirectors = $('#noOfDirectors').val();
var inputs = $('#inputs').empty();
inputs.innerHTML = "";
for(i = 0; i < noOfDirectors; i++) {
inputs.append('Director '+ (i+1) +' Name: <input type="text" name="directorName[' + i + ']" /><br/>Director '+ (i+1) +' Customer Number: <input type="text" name="directorECN['+i+']" /><br/><br/>');
}
$("#nod").show();
directors = $('[name^=directorECN]').map(function(i) {
//return this.name;
return this.value; // for real values of input
}).get();
}
$(document).ready(function() {
$('#nod').click(function() {
console.log(directors);
});
});
Now, I want to take each of those directorECN['+i+'] input names and add them to a globally declared array:
var directors = new Array ();
I am having a hard time figuring out a syntax that works without hard coding 10 (0-9) of each of the possible input names. Is there an easier way to do this?
Here is my UPDATED JSFiddle
Updated my JS above. Console is printing [""]
You can use .map() to get the array from name attribute of elements returned by Attribute Starts With Selector [name^=”value”].
var directors = $('[name^=directorECN]').map(function(i) {
//return this.name;
return this.value; // for real values of input
}).get();
Use .map() function over the attribute starts with selector [attribute^="value"]
var directors = $('[name^="directorECN"]').map(function () {
return this.name //to get value use this.value
}).get();
Updated Fiddle
Trying to set the radio inputs attribute to checked on select change.
Select HTML
<select onChange="jsFunction()" name="templateId" id="selectOpt" required="required">
<option value=""></option>
<option onclick="jsFunction()" value="slides_1">subject1</option>
<option onclick="jsFunction()" value="slides_2">subject2</option>
<option onclick="jsFunction()" value="slides_2">subject2</option>
</select>
jQuery
<script>
function jsFunction(){
var myselect = document.getElementById("selectOpt");
var mySlide = myselect.options[myselect.selectedIndex].value;
document.getElementById.mySlide.prop('checked', 'checked');
}
</script>
Radio HTML
<input type="radio" name="slides" check="checked" id="slides_1"/>
<input type="radio" name="slides" id="slides_2"/>
<input type="radio" name="slides" id="slides_3"/>
Thanks -Hector
For JS, see the function below.
For the HTML part, remove the onclick="jsFunction()" field on the options, and changed the last option to "slides_3".
See the working code at:
JSFiddle
JS:
function jsFunction() {
var selectedID = $('select#selectOpt').val();
$('input[type=radio]').filter('#'+selectedID).prop('checked', true);
}
HTML(updated):
<select onChange="jsFunction()" name="templateId" id="selectOpt" required="required">
<option value=""></option>
<option value="slides_1">subject1</option>
<option value="slides_2">subject2</option>
<option value="slides_3">subject3</option>
</select>
<div>
<input type="radio" name="slides" checked="checked" id="slides_1"/>
<input type="radio" name="slides" id="slides_2"/>
<input type="radio" name="slides" id="slides_3"/>
</div>
Import jquery:
<script type="text/javascript" src="you_jquery_file"></script>
You can download here: http://jquery.com/download/
Then change:
document.getElementById.mySlide.prop('checked', 'checked');
to:
$("#"+mySlide).prop('checked', 'checked');
For this particular problem, you don't need jQuery. Something like this will do:
function checkRadio(name, id) {
var rGroup = document.getElementsByName(name);
var theRadio = document.getElementById(id);
// uncheck the checked ones
for (var i=0;i<rGroup.length;i++) {
rGroup[i].checked = false;
}
// check the appropriate button
theRadio.checked = true;
}
// bind custom event to your select list
var mylist = document.getElementById('some_select_list');
mylist.addEventListener('change', function() {
var selected = this.options[this.selectedIndex].value;
checkRadio('radio_group_name', selected);
}, false);