Conditional removal of dropdown options based on checkbox selections - javascript

I've created a jsfiddle for this question, here: http://jsfiddle.net/navyjax2/9xpbyodq/
HTML
<span title="Fruit" class="ms-RadioText">
<input id="groupType_0" type="checkbox" checked="checked"/>
<label>Fruit</label>
</span><br>
<span title="Pies" class="ms-RadioText">
<input id="groupType_1" type="checkbox" />
<label>Pies</label>
</span>
<br><br>
<select id="Use_d8ffe43">
<option value="Apples">Apples</option>
<option value="Grapes">Grapes</option>
<option value="Both">Both</option>
</select><BR><BR>
JavaScript
$(document).ready(function () {
var whatSelected = new Array();
var piesOnly = false;
whatSelected.push('fruit'); // initial preset
var groupTypeField = $('input[id*="groupType"]');
groupTypeField.on('change', function () {
//alert(this.id);
var thisId = this.id.split('groupType_')[1];
//alert(thisId);
var thisChecked = this.checked;
var key = "";
if (thisId == 0)
key = "fruit";
else
key = "pies";
//alert(key);
if (whatSelected.indexOf(key) == -1 && thisChecked) {
whatSelected.push(key);
//alert('push: ' + key);
}
if (whatSelected.indexOf(key) != -1 && !thisChecked) {
//alert('pull: ' + key);
var index = whatSelected.indexOf(key);
//alert('index: ' + index);
if (index != -1) {
whatSelected.splice(index, 1);
//alert('pulled ' + key);
}
}
alert('after alteration: ' + whatSelected);
if (whatSelected.indexOf('pies') != -1) { // Pies checked
if (whatSelected.indexOf('fruit') != -1) { // Fruit checked, so not Pies only
piesOnly = false;
// Add "Grapes" and "Both" back, if gone
var exists = false;
$('select[id*="Use"] option').each(function () {
if (this.value == "Grapes") {
exists = true;
}
});
if (!exists) {
alert('added');
$('select[id*="Use"]').append('<option val="Grapes">Grapes</option>');
$('select[id*="Use"]').append('<option val="Both">Both</option>');
}
} else { // Fruit not checked
piesOnly = true;
// Remove Grapes and Both from dropdown
$('select[id*="Use"]').find('option[value="Grapes"]').remove(); $('select[id*="Use"]').find('option[value="Both"]').remove();
alert('removed');
}
} else { // Pies not checked
if (whatSelected.indexOf('fruit') != -1) { // Fruit checked, so not pies only
piesOnly = false;
} else {// nothing selected, revert to Fruit
alert('Must select an option.');
$('span[title*="Fruit"]').children(0).prop('checked', true);
$('span[title*="Pies"]').children(0).prop('checked', false);
piesOnly = false;
whatSelected.push('fruit'); // add it back
}
// Add "Grapes" and "Both" back to dropdown, if gone
var exists = false;
$('select[id*="Use"] option').each(function () {
if (this.value == "Grapes") {
exists = true;
}
});
if (!exists) {
alert('added');
$('select[id*="Use"]').append('<option value="Grapes">Grapes</option>');
$('select[id*="Use"]').append('<option value="Both">Both</option>');
}
}
});
});
Say I have 2 checkboxes, Fruit and Pies.
Say I have a dropdown, options: Apples, Grapes, Both
So if "Fruit" is selected, I expect all options to appear in the dropdown.
If "Pies" is selected, I only want "Apples", since who ever heard of a "Grape" pie? (or pie with "Both"?)
Fruit is the default selection, and at least one checkbox must be selected at all times. I have an array, "whatSelected", that tracks what checkboxes have been selected.
My code works to remove "Grapes" and "Both" from the dropdown if I select "Pies" and unselect "Fruit". (leaves "Apples" in the dropdown)
If I then re-select "Fruit", the options are all added back, correctly, through code I use to re-append the options using jQuery.
My issue is then, if I unselect "Fruit", it then DOES NOT remove "Grapes" and "Both", which are my appended options, on the dropdown. How can I remove these appended options? Thanks.

Actually I found my bug.... I have to do the appending in two places -- once if Fruit and Pies are selected, and another place, when Pie is not selected, but Fruit is. In one of the locations, I had...
$('select[id*="Use"]').append('<option val="Grapes">Grapes</option>');
$('select[id*="Use"]').append('<option val="Both">Both</option>');
Instead of val, I needed to use value. This solved my problem.
Rather than leave my jsfiddle broken, I updated it with this fix. But the code above is the original.
I thought about deleting this question, but thought there could be a lot of benefit to the coding community if I left this, since a lot of what is here are things often asked and could drive someone a little nutty on how to implement some of the things I did, here.

Related

Conditional on Multi Select for certain options only

I have a multiselect where I need to show/hide another select based on options selected in the first select. There are 3 options that should cause the other select to appear - all other options should not cause anything to change.
I have it working if individually the options are selected. However if one of the options is selected along with any other options it doesn't work.
DUE to CMS constraints I am unable to add classes to the options.
This is my current jQuery code.
$('#freeform_how_would_you_best_describe_your_companys_research_activity').change(function() {
var selectedItems
if ($(this).val() == 'Drug Discovery/Development' || $(this).val() == 'Therapeutics' || $(this).val() == 'Vaccines' ) {
$('label[for="freeform_tell_us_more_about_your_research_activity"], select#freeform_tell_us_more_about_your_research_activity').slideDown();
} else {
$('label[for="freeform_tell_us_more_about_your_research_activity"], select#freeform_tell_us_more_about_your_research_activity').slideUp();
}
});
Please advise
Multiselect .val() returns array not a single value. Take it in account.
$('#sel').change(function() {
var arr = $(this).val();
if (arr.indexOf('one') > -1 || arr.indexOf('two') > -1 || arr.indexOf('three') > -1) {
console.log('do this');
} else
console.log('do that');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="sel" multiple size="5">
<option>one</option>
<option>two</option>
<option>three</option>
<option>else</option>
</select>
Some additionaly googling and expermenting later I found a solution
$('#freeform_how_would_you_best_describe_your_companys_research_activity').change(function() {
var values = $(this).val();
console.log(values)
if(values.includes("Vaccines")|| values.includes("Therapeutics") || values.includes("Drug Discovery/Development")){
$('label[for="freeform_tell_us_more_about_your_research_activity"], select#freeform_tell_us_more_about_your_research_activity').slideDown();
} else {
$('label[for="freeform_tell_us_more_about_your_research_activity"], select#freeform_tell_us_more_about_your_research_activity').slideUp();
}
});

Set multi select options from stored localstorage values

I am trying to set multiple select options to selected, based on the corresponding localstorage value.
Storing the values in an array in localstorage is working, but I need help selecting the options in a form based on these values..
The values in localstorage are collected from checkboxes like so:
jQuery(document).ready(function(){
var checkboxValues = JSON.parse(localStorage.getItem('checkboxValues')) || {},
checkboxes = jQuery(".add-selectie :checkbox");
checkboxes.on("change", function(){
checkboxes.each(function(){
checkboxValues[this.id] = this.checked;
});
localStorage.setItem("checkboxValues", JSON.stringify(checkboxValues));
});
jQuery.each(checkboxValues, function(key, value) {
jQuery('#' + key).prop('checked', value);
});
});
This saves the values in an array with the key "checkboxValues" in localstorage like so:
{"value1":true,"value2":true,"value3":false}
But how do I pre populate select options in a form if the value is found in localstorage AND set to true?
I made this pen containing all above code + a demo form. Any help would be greatly appreciated!
The code below should give you snippets to update selected state of option elements by reading values from localStorage.
Please note that there is a security issue in using localStorage in stackoverflow execution context so
I created a custom singleton/static class CustomLocalStorage having similar methods.
Additionally I've used a complete object OptionValueObject to back
the properties of checkbox and select elements.
var CustomLocalStorage = (function() {
var items = {};
function getItem(itemKey) {
for (var _itemKey in items) {
if (_itemKey === itemKey) {
return JSON.parse(items[itemKey]);
}
}
return null;
}
function setItem(itemKey, itemValue) {
items[itemKey] = JSON.stringify(itemValue);
}
return {
getItem: getItem,
setItem: setItem
}
})();
function OptionValueObject(id, label, value) {
this.id = id; // Used to identify checkboxes
this.label = label; // Not used in this example
this.value = value; // To bind it to select > option > value property
this.checked = true; // To bind it to checkbox > checked property
}
$(document).ready(function() {
function initialize() {
initializeData();
initializeUi();
}
function initializeData() {
var optionValueObjects = [];
optionValueObjects.push(new OptionValueObject(1, 'Label of option 1', 'value1'));
optionValueObjects.push(new OptionValueObject(2, 'Label of option 2', 'value2'));
optionValueObjects.push(new OptionValueObject(3, 'Label of option 3', 'value3'));
CustomLocalStorage.setItem('options', optionValueObjects);
}
function initializeUi() {
var optionValueObjects = CustomLocalStorage.getItem('options');
for (var i = 0; i < optionValueObjects.length; i++) {
var optionValueObject = optionValueObjects[i];
var id = optionValueObject.id;
// Checkbox: Identify element and set UI related property
var checkboxElement = $('#checkbox' + id);
checkboxElement.prop('checked', optionValueObject.checked);
console.log(optionValueObject.value);
// Option: Identify element and set UI related property
var optionElement = $("#optionsSelect > option[value='"+ optionValueObject.value +"']");
optionElement.prop('selected', optionValueObject.checked);
}
}
function handleEvents() {
function checkboxChangeHandler() {
// Get the object, update the checked property and save it back
// 1. Get the object
var id = $(this).prop('id');
var optionValueObjects = CustomLocalStorage.getItem('options');
var optionValueObject = optionValueObjects.filter(function(optionValueObject) {
if (('checkbox' + optionValueObject.id) === id) {
return optionValueObject;
}
})[0];
// 2. Update the checked property
var checked = $(this).prop('checked');
optionValueObject.checked = checked;
// Bind the checked property to options selected property
var optionElement = $("#optionsSelect > option[value='"+ optionValueObject.value +"']");
optionElement.prop('selected', optionValueObject.checked);
// 3. Save it back
CustomLocalStorage.setItem('options', optionValueObjects);
}
$('#checkbox1').change(checkboxChangeHandler);
$('#checkbox2').change(checkboxChangeHandler);
$('#checkbox3').change(checkboxChangeHandler);
}
initialize();
handleEvents();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="add-selectie">
<input id="checkbox1" class="selector" type="checkbox"><label for="checkbox1">Value 1</label>
<input id="checkbox2" class="selector" type="checkbox"><label for="checkbox2">Value 2</label>
<input id="checkbox3" class="selector" type="checkbox"><label for="checkbox3">Value 3</label>
</div>
<form>
<select id="optionsSelect" multiple="multiple">
<option value="value1">Value 1</option>
<option value="value2">Value 2</option>
<option value="value3">Value 3</option>
</select>
</form>

Not abled to assign old value for ng-select?

html
<select ng-model="selectedName" ng-change="retrieveSelectedClass(selectedName, '{{selectedName}}')" ng-options="item.name group by item.groupName for item in names"
class="code-helper" id="code-helperId">
<option value="">Select Option</option>
</select>
JavaScript
$scope.retrieveSelectedClass = function(newValue, oldValue) {
if (!globalEditor1.isClean()) {
var r = confirm("You have unsaved changes, are you sure you want to proceed ?");
if (r != true) {
oldValue = JSON.parse(oldValue);
var oldValueObject = {
name: oldValue.name,
id: oldValue.id,
groupName: oldValue.groupName,
lineNumberError : oldValue.lineNumberError,
isCompilationError : oldValue.isCompilationError,
dataNotMatching : oldValue.dataNotMatching,
timeStampNotMatching : oldValue.timeStampNotMatching
};
$scope.selectedName = oldValueObject;
$scope.isPaneShown = false;
return;
}
}
}
So what the js does, it checks if the editor is clear then alerts the user. If the user selects cancel, then the selected value in the ng-select should remain as old value and not the new value which got selected by the user.
But the selected value in ng-select becomes blank when the user clicks cancel?
And idea where am I making mistake? Or how to implement this?
Because in angularjs an object has an objectHash (named $$objectHash you see that if you debug). It's an identifier, and you can't assign to select an object that isn't in select options.
I write a Plunker with an example. I think this would be helpful to you
https://plnkr.co/edit/YpwhgKSy24kFyYtjRKsv
$scope.retrieveSelectedClass = function(newValue, oldValue){
// your control, i do simple control because i don't understand exatly what you need
if(angular.isUndefined(oldValueSelected.id) && oldValue.indexOf('"id"') !== -1){
oldValueSelected = JSON.parse(oldValue);
}
}
$scope.clearSelect = function(){
// check if old value isn't empty
if(angular.isDefined(oldValueSelected.id)){
// filter names array and get object of old value
var possibleOldValues = $filter('filter')($scope.names, {id: oldValueSelected.id}, true);
if(possibleOldValues.length > 0){
$scope.selectedName = possibleOldValues[0];
}
}
else{
$scope.selectedName = {};
}
}

How to re-order the value of a multiple select based on user selection order

How can I re-order the comma delimited value of a select multiple element based on the order in which the options were selected by the user instead of the order of the options in the html?
For example:
<select multiple>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
... If the user selects "3", then "1", then "2", the returned value of the select will be "1,2,3". How can I make it return "3,1,2"?
Note, I am using jQuery and HTML5, so I can use those tools if needed.
Thanks!
This records the click of each elements add saves it to an array. When an item is deselected it is removed from the array.
var vals = [];
$(document).ready(function(e) {
$('#selector').change(function(e) {
for(var i=0; i <$('#selector option').length; i++) {
if ($($('#selector option')[i]).prop('selected') ) {
if (!vals.includes(i)) {
vals.push(i);
}
} else {
if (vals.includes(i)) {
vals.splice(vals.indexOf(i), 1);
}
}
}
})
$("#final").click(function(e) {
var order = '';
vals.forEach(function(ele) {
order += $($('#selector option')[ele]).val() + ',';
})
console.log(order);
})
})
Codepen: http://codepen.io/nobrien/pen/pydQjZ
None of the proposed solutions floated my boat, so I came up with this:
My solution is to add an html5 attribute to the multiselect element, data-sorted-values, to which I append new values, and remove un-selected values, based on the latest change.
The effect in the end is that data-sorted-values can be queried at anytime to get the current list of user-ordered values. Also, all selected options hold an attribute of "selected".
I hope this can help someone else out there...
https://jsfiddle.net/p1xelarchitect/3c5qt4a1/
HTML:
<select onChange="update(this)" data-sorted-values="" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Javasript:
function update(menu) {
// nothing selected
if ($(menu).val() == null)
{
$.each($(menu).find('option'), function(i)
{
$(this).removeAttr('selected');
$(menu).attr('data-sorted-values', '');
});
}
// at least 1 item selected
else
{
$.each($(menu).find('option'), function(i)
{
var vals = $(menu).val().join(' ');
var opt = $(this).text();
if (vals.indexOf(opt) > -1)
{
// most recent selection
if ($(this).attr('selected') != 'selected')
{
$(menu).attr('data-sorted-values', $(menu).attr('data-sorted-values') + $(this).text() + ' ');
$(this).attr('selected', 'selected');
}
}
else
{
// most recent deletion
if ($(this).attr('selected') == 'selected')
{
var string = $(menu).attr('data-sorted-values').replace(new RegExp(opt, 'g'), '');
$(menu).attr('data-sorted-values', string);
$(this).removeAttr('selected');
}
}
});
}
}
try this https://jsfiddle.net/ksojitra00023/76Luf1zs/
<select multiple>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<div id="output"></div>
$('select').click(function(){
$("#output").append($(this).val());
});
var data = '3,1,2';
var dataarray=data.split(",");
var length =dataarray.length;
for(i=0;i<length;i++){
// Set the value
$('#select').multiSelect('select',dataarray[i]);
}

How to get checkbox value in multiselect onchange event

I implement jquery multiselect and its working properly now i need to add extra feature that when a user select another option in dropdown ( check another checkbox ) then i want to get the value of the related option
in above picture in did not insert checkbox it is automatically inserted by jquery now i want that if i select the check =box with XYZ then i want to get the value of XYZ which is the id of XYZ
here is how i implemented it
<select multiple="multiple" id="CParent" name="parent" class="box2 required">
#foreach (var item in Model.Categories.OrderBy(c => c.Name))
{
if (Model.Coupon.Categoryid.Id == item.Id)
{
<option selected="selected" value="#item.Id">#item.Name</option>
}
else
{
<option value="#item.Id">#item.Name</option>
}
}
</select>
and it is how it looks like after rendering in browser source
Thanks in advance for helping me .
what i tried yet
$('#CParent input:checked').change(function () {
var parentid = $(this).val()+'';
var array = parentid.split(",");
alert(array);
getchildcat(array[array.length -1]);
});
});
Edit
Code to initialize multiselect
$("#CParent").multiselect({
header: "Choose only THREE items!",
click: function () {
if ($(this).multiselect("widget").find("input:checked").length > 3) {
$(warning).show();
warning.addClass("error").removeClass("success").html("You can only check three checkboxes!");
return false;
}
else if ($(this).multiselect("widget").find("input:checked").length <= 3) {
if ($(warning).is(":visible")) {
$(warning).hide();
}
}
}
});
try this
$('#CParent').val();
this will give you the selectbox value
OR
from docs
var array_of_checked_values = $("#CParent").multiselect("getChecked").map(function(){
return this.value;
}).get();

Categories

Resources