I have have following selections:
<select id="custom-headers" multiple="multiple" class="searchable custom-headers">
<option data-invoice-number="36655" value="1187">RAPCY3</option>
<option data-invoice-number="87172" value="1188">1188</option>
<option data-invoice-number="79190" value="1189">CXETHD</option>
<option data-invoice-number="24584" value="1190">ZDAC2X</option>
<option data-invoice-number="49694" value="1191">2T8SRJ</option>
<option data-invoice-number="11290" value="1192">XDCH5J</option>
<option data-invoice-number="96188" value="1193">83EYS8</option>
<option data-invoice-number="33819" value="1194">WE5PEW</option>
<option data-invoice-number="56529" value="1195">CJEQWM</option>
<option data-invoice-number="55643" value="1196">RAPCY3</option>
<option data-invoice-number="72334" value="1197">1197</option>
<option data-invoice-number="14563" value="1198">CXETHD</option>
<option data-invoice-number="58963" value="1199">ZDAC2X</option>
<option data-invoice-number="44810" value="1200">2T8SRJ</option>
<option data-invoice-number="88482" value="1201">XDCH5J</option>
<option data-invoice-number="9731" value="1202">83EYS8</option>
<option data-invoice-number="41170" value="1203">WE5PEW</option>
<option data-invoice-number="1911" value="1204">CJEQWM</option>
</select>
I need to gather up both the values and invoice-number into one array..
jQuery works fine only for Reslist:
o.reservations = [];
$('.custom-headers option:selected').each(function (i, selected) {
o.reservations[i] = $(selected).val();
});
Giving me back an array of 1187, 1188, 1189 i need something like
reslist => 1187, 1188, 1189, invoices => 36655, 87172, 79190
Tried:
o.reservations = [];
$('.custom-headers option:selected').each(function (i, selected) {
o.reservations[i] = $(selected).val();
o.reservations[i] = $(selected).data('invoice-number');
});
Not sure how to define the keys in js?
$('.custom-headers option:selected').each(function (i, selected) {
o.reservations.push({
value: $(selected).val(),
number: $(selected).data('invoice-number')
});
});
This will populate the following array:
[{value: 1187, number: 36655}, {value: 1188, number: 87172}, ...]
var arr = {"reslist":[], "invoices":[]};
$('.custom-headers option:selected').each(function (i, selected) {
arr.reslist.push($(this).val());
arr.invoices.push($(this).data("invoice-number"));
});
Use map.
console.log($('#custom-headers option').map(function(option){
var $this = $(option);
return { invoice-number: $this.data('invoice-number'), value: $this.val() };
}));
Related
I have a select with options and values:
<select id="sid">
<option value="sValue1">sText1</option>
...
</select>
I need to create an associated array for all pairs:
var data = {"sText1":"sValue1",...};
Is there ready/simplifies tools to do that?
It's a basic for ... on ... iteration.
Take note that if there are multiple <option> with the same label, the last one will take place in the result object.
const select = document.getElementById('sid');
const objContainer = document.getElementById('sid-obj');
const options = select.getElementsByTagName('option');
const selectObj = {};
for (const opt of options) {
let optObj = {};
optObj[opt.textContent] = opt.value;
Object.assign(selectObj, optObj);
}
// print result in code
objContainer.textContent = JSON.stringify(selectObj);
<select id="sid">
<option value="">Default</option>
<option value="sValue1">sText1</option>
<option value="sValue2">sText2</option>
<option value="sValue3">sText3</option>
<option value="sValue4">sText4</option>
<option value="sValue5">sText4</option>
</select>
<h2>Result:</h2>
<code id="sid-obj" />
Add a function to the select which will be called on change and on change get the value and the text from the selected option
function getValue(elem) {
let obj = {};
obj[elem.options[elem.selectedIndex].text] = elem.value
console.log(obj)
}
<select id="sid" onchange='getValue(this)'>
<option value="sValue1">sText1</option>
<option value="sValue2">sText2</option>
<option value="sValue3">sText3</option>
</select>
Sorry for being late to the party but here is a jQuery solution for the same.
var arr = {};
$("#sid option").each(function() {
let text = $(this).text();
arr[text] = $(this).val();
});
// print result
$('#sid-obj').append(JSON.stringify(arr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="sid">
<option value="">Default</option>
<option value="sValue1">sText1</option>
<option value="sValue2">sText2</option>
<option value="sValue3">sText3</option>
<option value="sValue4">sText4</option>
<option value="sValue5">sText4</option>
</select>
<h2>Result:</h2>
<code id="sid-obj" />
The Issue
I am trying to convert form inputs to a json object but having difficulty trying to achieve this, below is a snippet of the HTML which I have and the JSON which I'm trying to get.
{
"2019-01-23": [
{
id: 1,
period: 'am'
},
{
id: 2,
period: 'pm'
}
]
}
<select name="dates[2019-01-23][0][id]">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select name="dates[2019-01-23][0][period]">
<option selected>am</option>
<option>pm</option>
</select>
<select name="dates[2019-01-23][1][id]">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
<select name="dates[2019-01-23][1][period]">
<option>am</option>
<option selected>pm</option>
</select>
What I've tried
var inputs = $(':input').serializeArray();
var json = [];
$.each(inputs, function(key, input) {
var names = input.name.split(/\[(.*?)\]/);
var data = [];
data[names[1]] = [];
data[names[1]][names[3]] = { id: null, period: null };
if(names[5] == 'id') {
data[names[1]][names[3]].id = input.value;
}
if(names[5] == 'period') {
data[names[1]][names[3]].period = input.value;
}
json.push(data);
});
But this doesn't quite achieve what I'm after (multiple of the same date) and I'm getting a bit lost now, I'm sure there must be a way of doing this a lot easier.
First, match is more appropriate for your case than split.
Furthermore, since json is object literal, it should be initialised with empty object ({}), not array.
push is not quite appropriate for your case. It's better to use direct assignment instead.
So the code might look like this:
var inputs = $(':input').serializeArray();
var json = {};
$.each(inputs, function(key, input) {
var keys = input.name.match(/([^\[\]]+)/g).slice(1);
var date = keys[0], i = keys[1], id = keys[2];
if (!json[date]) json[date] = [];
if (!json[date][i]) json[date][i] = {};
json[date][i][id] = input.value;
});
console.log(JSON.stringify(json));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<select name="dates[2019-01-23][0][id]">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select name="dates[2019-01-23][0][period]">
<option selected>am</option>
<option>pm</option>
</select>
<select name="dates[2019-01-23][1][id]">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
<select name="dates[2019-01-23][1][period]">
<option>am</option>
<option selected>pm</option>
</select>
I am trying to save the values of multiple multi selects as one object ...
Here is what I am trying to do. I have 3 select boxes and am using the ChosenJS library for better ui.
All 3 multi-selects are using the same model (should this change?)
HTML
<div id="app">
<select multiple v-chosen v-model="choices" name="filters1" id="filters1">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select multiple v-chosen v-model="choices" name="filters2" id="filters2">
<option value="4">Option 4</option>
<option value="5">Option 5</option>
<option value="6">Option 6</option>
</select>
<select multiple v-chosen v-model="choices" name="filters3" id="filters3">
<option value="7">Option 7</option>
<option value="8">Option 8</option>
<option value="9">Option 9</option>
</select>
<pre>
Selected Options: {{choices}}
</pre>
</div>
JS
Vue.directive('chosen', {
twoWay: true,
bind: function () {
return this.vm.$nextTick((function (_this) {
return function () {
return $(_this.el).chosen({
inherit_select_classes: false,
width: '100%'
}).change(function (ev) {
var i, len, option, ref, values;
if (_this.el.hasAttribute('multiple')) {
values = [];
ref = _this.el.selectedOptions;
for (i = 0, len = ref.length; i < len; i++) {
option = ref[i];
values.push(option.value);
}
console.log(values);
return _this.set(values);
} else {
return _this.set(_this.el.value);
}
});
};
})(this));
},
update: function (nv, ov) {
return $(this.el).trigger('chosen:updated');
}
});
var app = new Vue({
el:'#app',
data: {
choices: []
}
})
My expected outcome would be:
Selected Options: ['2','3','6','8']
Is this possible?
I created a fiddle to show where I am at.
http://jsfiddle.net/tyLa562h/3/
No, you can't. Only radio buttons and checkboxes can have same model. So, here what you can do it by using a computed option: (choice1, choice2, choice3 are all three different model)
computed: {
allChoices: function() {
return this.choice1 + this.choice2 + this.choice3; // return how you want
}
}
You can even use getter/setter method if you want.
I have a dropdown that allows users to filter their query.
<select id="bike_category_filter" multiple="multiple">
<optgroup label="Gender">
<option value="Mens">Mens</option>
<option value="Womens">Womens</option>
</optgroup>
<optgroup label="Type">
<option value="Mountain Bike">Mountain Bike</option>
<option value="Hybrid">Hybrid</option>
<option value="Road">Road</option>
</optgroup>
</select>
I am looking to send selected options in a hash, for example
{ gender: 'Mens', style: ['Mountain Bike', 'Road'] }
So upon click of option Men || Womens i would like to add that with the key Gender and for any of the types I would like to add to style: ['values here'].
How would I achieve such a thing, and what methods can I use from the jQuery library?
var result = {
gender: '',
style: []
};
$('#bike_category_filter').change(function() {
var selected = $('option:selected', this),
val = selected.val(),
index = '';
if (!val) {
return;
}
switch (selected.parent()[0].label) {
case 'Gender':
result.gender = val;
// reset style for selected gender
result.style = [];
break;
case 'Type':
(index = result.style.indexOf(val) === -1)
? result.gender && result.style.push(val)
: result.style.splice(index, 1);
break;
}
$(this).val(result.style.concat([result.gender]));
$('code').html(JSON.stringify(result));
});
select {
height: 130px;}
code {
display: block;
margin: 15px 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="bike_category_filter" multiple="multiple">
<optgroup label="Gender">
<option value="Mens">Mens</option>
<option value="Womens">Womens</option>
</optgroup>
<optgroup label="Type">
<option value="Mountain Bike">Mountain Bike</option>
<option value="Hybrid">Hybrid</option>
<option value="Road">Road</option>
</optgroup>
</select>
<code></code>
The basic algorithm is:
each time the user selects/deselects a value:
reset result to an empty object
for each <optgroup> tag:
store the value of the label attribute in the variable groupName
initialize a new empty groupSelections array
for each <option> tag within the <optgroup> that has been selected by the user:
add the value of the option to groupSelections
set result[groupName] = groupSelections
At the end, you should have one property in the result object for each optgroup, and each of those properties should be an array listing the values of the selected options within that optgroup.
Here it is in code:
var result;
$('#bike_category_filter').change(function() {
result = {};
$(this).find('optgroup').each(function() {
var groupName = $(this).attr('label');
var groupSelections = [];
$(this).find('option:selected').each(function() {
groupSelections.push($(this).val());
});
result[groupName] = groupSelections;
});
$('#result').html(JSON.stringify(result));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="bike_category_filter" multiple="multiple" style="width:150px;height:150px;">
<optgroup label="Gender">
<option value="Mens">Mens</option>
<option value="Womens">Womens</option>
</optgroup>
<optgroup label="Type">
<option value="Mountain Bike">Mountain Bike</option>
<option value="Hybrid">Hybrid</option>
<option value="Road">Road</option>
</optgroup>
</select>
<p><code id="result"></code></p>
You can do this:
var styles = {
"men": ['Mountain Bike', 'Road'],
"women": [...]
};
$( "select" ).change(function () {
var gender = $( "select option:selected" ).val();
$("your elment").addClass(styles[gender].join(" "));
});
I would recommend you to create a style object as above and set the genders as the key and the array as the value.
When ever a user change is selection the change callback will be called and then this $( "select option:selected" ).val(); will return the value of the selected element (in our case the gender).
styles is an object when you use this syntax styles["men"] you will get the value for the men key.
I am using the SumoSelect dropdown for multiselect options. But i cannot get the selected values array.
Below the sample code :
<script type="text/javascript">
$(document).ready(function () {
window.testSelAll = $('.testSelAll').SumoSelect({okCancelInMulti:true, selectAll:true });
$('.btnOk').on('click', function(){
var obj = [];
$('option:selected').each(function () {
obj.push($(this).index());
alert("Selected Values=="+$(this).val());
});
for (var i = 0; i < obj.length; i++) {
$('.testSelAll')[0].sumo.unSelectItem(obj[i]);
}
});
});
</script>
<select multiple="multiple" placeholder="Share Your Friends" onchange="console.log($(this).children(':selected').length)" class="testSelAll">
<option value="1">Volvo</option>
<option value="2">Saab</option>
<option value="3">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
<option value="porsche">Porche</option>
<option value="ferrari">Ferrari</option>
<option value="mitsubishi">Mitsubishi</option>
</select>
If you want the selected values instead of the text, just change .text() to .val().
If you want to get the array, see below with working example at the bottom.
jQuery
$(document).ready(function() {
$('.testSelAll').SumoSelect({
okCancelInMulti: true,
selectAll: true
});
$('.btnOk').on('click', function() {
var obj = [],
items = '';
$('.testSelAll option:selected').each(function(i) {
obj.push($(this).val());
$('.testSelAll')[0].sumo.unSelectItem(i);
});
for (var i = 0; i < obj.length; i++) {
items += ' ' + obj[i]
};
alert(items);
});
});
HTML
<select multiple="multiple" class="testSelAll">
<option value="car1">Volvo</option>
<option value="car2">Saab</option>
<option value="car3">Mercedes</option>
<option value="car4">Audi</option>
</select>
Working JSFIDDLE
You can get them from underlying hidden select element.
using jquery eg.
$('.select1 option:selected')
I think the cleanest way to do this. Is to take advantage of html5 select element underlying SumoSelect.
HTML
<select multiple="multiple" class="testSelAll" id="multi-select">
<option value="car1">Volvo</option>
<option value="car2">Saab</option>
<option value="car3">Mercedes</option>
<option value="car4">Audi</option>
</select>
Javascript
var values = $('#multi-select').val();
This line will return a string list of the values selected.