select multiselect option limit up to 2 - javascript

I am using multiselect for different subject's I want to limit the select up to 2 and make the other's disabled in the same way if user deselect, Again the option must be available for the user.
<select multiple="multiple" class="subjects" name="subjects[]" style="float:left;width:205px;" size="5">
<option value='1'>subject1</option>
<option value='2'>subject2</option>
<option value='3'>subject3</option>
<option value='3'>subject3</option>
</select>
So far I have achieved to deselect only the last option which was selected after 2 and the code is as follow
/**
* Make sure the subject's limit is 2
*/
$(".subjects option").click(function(e){
if ($(this).parent().val().length > 2) {
$(this).removeAttr("selected");
}
});
Thank you.

Improved jQuery example, notice the (else enable) option, this fixes a bug on previous examples that disabled the select options permanently. Also removed the "Please select only two options." error message when possible.
http://jsfiddle.net/c9CkG/25/
jQuery(document).ready(function () {
jQuery("select").on("change", function(){
var msg = $("#msg");
var count = 0;
for (var i = 0; i < this.options.length; i++)
{
var option = this.options[i];
option.selected ? count++ : null;
if (count > 2)
{
option.selected = false;
option.disabled = true;
msg.html("Please select only two options.");
}else{
option.disabled = false;
msg.html("");
}
}
});
});

As an improvment on RobG's answer, you could unselect an option if it makes count > 2.
See: http://jsfiddle.net/c9CkG/3/ for a working example using jQuery.
function checkSelected(el) {
var msgEl = document.getElementById('msg');
var count = 0;
for (var i=0, iLen=el.options.length; i<iLen; i++)
el.options[i].selected? count++ : null;
// Deselect the option.
if (count > 2) {
el.options[i].selected = false;
el.options[i].disabled = true;
msgEl.innerHTML = 'Please select only two options';
}
}

Something like the following will do the job:
function checkSelected(el) {
var msgEl = document.getElementById('msg');
var count = 0;
for (var i=0, iLen=el.options.length; i<iLen; i++)
el.options[i].selected? count++ : null;
msgEl.innerHTML = count > 2? 'Please select only two options' : '';
}
</script>
<span>Please select a maximum of two options:</span>
<select multiple onchange="checkSelected(this);">
<option>0
<option>1
<option>2
<option>3
</select>
<br>
<span id="msg"></span>
I don't think it's a good idea to disable options, you only care that only two are selected when the form is submitted. Until then, it doesn't matter.

$(document).ready(function() {
var last_valid_selection = null;
$('#testbox').change(function(event) {
if ($(this).val().length > 5) {
alert('You can only choose 5!');
$(this).val(last_valid_selection);
} else {
last_valid_selection = $(this).val();
}
});
});

Related

Adding another option when the select dropdown is clicked?

I need to add a new select option in my HTML when they click it
<select class="statusButtonChange statusButton " data-value="49506">
<option value="0" selected=""></option>
<option value="1">Close</option>
<option value="2" disabled="" style="color:grey;">Taken</option>
</select>
This new option is dynamic and will be coming from an API response... I'm parsing the var value from the API response but for now, I made it static just to test.
Right now, I have this:
$(document).ready(function () {
var k = 1
$(".statusButton").on('focus', function () {
var value = "Disable";
var new_v = "";
var html = $(".statusButton").html();
if (k == 1) {
if (value == "Disable") {
new_v = "<option value='Disable' >Disable</option>";
}
else if (value == "Enable") {
new_v = "<option value='Enable' >Enable</option>"
}
var full = html + "" + new_v;
$(".statusButton").html(full);
k = 2;
}
});
});
It is working on JSFiddle but when I try to integrate it on my website, it's not reading it, even just the console log. WHat am I doing wrong?
I'm not sure exactly what's wrong, but I think a better approach might be to use jQuery's append method (https://api.jquery.com/append/).
Consider:
...
$(".statusButton").on('focus', function () {
var value = "Disable";
var new_v = "";
var $statusButton = $(".statusButton");
if(k == 1){
if(value == "Disable")
{
$statusButton.append("<option value='Disable' >Disable</option>");
}
else if(value == "Enable")
{
$statusButton.append("<option value='Enable' >Enable</option>")
}
...
If you do things that way, you don't have to mess around with any extra .html calls.
This is short answer without creating too many variable.
$(document).ready(function() {
var k = 1
$(".statusButton").on('focus', function() {
var value = "Disable";
if (k == 1) {
if (value == "Disable") {
$(".statusButton").append("<option value='Disable' >Disable</option>");
} else if (value == "Enable") {
$(".statusButton").append("<option value='Enable' >Enable</option>")
}
k = 2;
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="statusButtonChange statusButton " data-value="49506">
<option value="0" selected=""></option>
<option value="1">Close</option>
<option value="2" disabled="" style="color:grey;">Taken</option>
</select>

Select prepended option by default

Okay I'm about to pull my hair out.
I'm hoping someone can help me.
I'm trying to prepend a "Select an Option" value to a dropdown menu and then make that the default selected option when the page loads.
For a brief background: I have been trying to combine Shopify's "Linked Options" and "Pick an Option" features. Sadly, when you try to implement both, the Linked Options feature overrides Pick an Option. (Pick an Option places a default "Select a ____" to the dropdown menu).
So I have taken a part of the Pick an Option and tried placing it in Linked Options.
Here is the code that I placed in that:
selector.prepend('<option value="">Select ' + {{ product.options[forloop.index0] | json }} + '</option>').val('');
And here is the entire code:
<script>
// (c) Copyright 2016 Caroline Schnapp. All Rights Reserved. Contact: mllegeorgesand#gmail.com
// See https://docs.shopify.com/themes/customization/navigation/link-product- options-in-menus
var Shopify = Shopify || {};
Shopify.optionsMap = {};
Shopify.updateOptionsInSelector = function(selectorIndex) {
switch (selectorIndex) {
case 0:
var key = 'root';
var selector = jQuery('.single-option-selector:eq(0)');
break;
case 1:
var key = jQuery('.single-option-selector:eq(0)').val();
var selector = jQuery('.single-option-selector:eq(1)');
break;
case 2:
var key = jQuery('.single-option-selector:eq(0)').val();
key += ' / ' + jQuery('.single-option-selector:eq(1)').val();
var selector = jQuery('.single-option-selector:eq(2)');
}
var initialValue = selector.val();
selector.empty();
var availableOptions = Shopify.optionsMap[key];
selector.prepend('<option value="">Select ' + {{ product.options[forloop.index0] | json }} + '</option>');
selector[0].selectedIndex = 0;
for (var i=0; i<availableOptions.length; i++) {
var option = availableOptions[i];
var newOption = jQuery('<option></option>').val(option).html(option).val('');
selector.append(newOption);
}
jQuery('.swatch[data-option-index="' + selectorIndex + '"] .swatch-element').each(function() {
if (jQuery.inArray($(this).attr('data-value'), availableOptions) !== -1) {
$(this).removeClass('soldout').show().find(':radio').removeAttr('disabled','disabled').removeAttr('checked');
}
else {
$(this).addClass('soldout').hide().find(':radio').removeAttr('checked').attr('disabled','disabled');
}
});
if (jQuery.inArray(initialValue, availableOptions) !== -1) {
selector.val(initialValue);
}
selector.trigger('change');
};
Shopify.linkOptionSelectors = function(product) {
// Building our mapping object.
for (var i=0; i<product.variants.length; i++) {
var variant = product.variants[i];
if (variant.available) {
// Gathering values for the 1st drop-down.
Shopify.optionsMap['root'] = Shopify.optionsMap['root'] || [];
Shopify.optionsMap['root'].push(variant.option1);
Shopify.optionsMap['root'] = Shopify.uniq(Shopify.optionsMap['root']);
// Gathering values for the 2nd drop-down.
if (product.options.length > 1) {
var key = variant.option1;
Shopify.optionsMap[key] = Shopify.optionsMap[key] || [];
Shopify.optionsMap[key].push(variant.option2);
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]);
}
// Gathering values for the 3rd drop-down.
if (product.options.length === 3) {
var key = variant.option1 + ' / ' + variant.option2;
Shopify.optionsMap[key] = Shopify.optionsMap[key] || [];
Shopify.optionsMap[key].push(variant.option3);
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]);
}
}
}
// Update options right away.
Shopify.updateOptionsInSelector(0);
if (product.options.length > 1) Shopify.updateOptionsInSelector(1);
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
// When there is an update in the first dropdown.
jQuery(".single-option-selector:eq(0)").change(function() {
Shopify.updateOptionsInSelector(1);
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
return true;
});
// When there is an update in the second dropdown.
jQuery(".single-option-selector:eq(1)").change(function() {
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
return true;
});
};
{% if product.available and product.options.size > 1 %}
var $addToCartForm = $('form[action="/cart/add"]');
if (window.MutationObserver && $addToCartForm.length) {
if (typeof observer === 'object' && typeof observer.disconnect === 'function') {
observer.disconnect();
}
var config = { childList: true, subtree: true };
var observer = new MutationObserver(function() {
Shopify.linkOptionSelectors({{ product | json }});
observer.disconnect();
});
observer.observe($addToCartForm[0], config);
}
{% endif %}
That looks like it'll take way too much time to grok. Snippet 1 demonstrates how to prepend an option to a select. Snippet 2 demonstrates how to use insertAdjacentHTML(). The attribute: selected which value can be: "selected" or true/false, purpose is to designate the default option. Details are commented in the code.
SNIPPET 1
// Reference the select
var sel = document.getElementById('sel');
// Create an option
var opt = document.createElement('option');
// Add a value
opt.value = '0';
// Add content
opt.textContent = '0';
// Make it default
opt.setAttribute('selected', true);
// Reference the first child of the select
var first = sel.firstChild;
// Insert box before the first
sel.insertBefore(opt, first);
<select id='sel' name='sel'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
</select>
SNIPPET 2
var sel = document.getElementById('sel');
sel.insertAdjacentHTML('afterbegin', '<option value="" selected=true>Select</option>');
// Reference the first child of select
var first = sel.firstChild;
// This commented out because I don't have the data to use it.
// first.textContent = "Select "+{{product.options[forloop.index0] || json}}+";
<script src='https://cdn.jsdelivr.net/handlebarsjs/4.0.5/handlebars.min.js'></script>
<select id='sel' name='sel'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
</select>
The first parameter of insertAdjacentHTML() is the location of insertion:
<section id='s1'>Content xxxxxxxxxxxxxxxxxxxxx</section>
▲-----------------▲----------------------------▲---------▲
beforebegin___afterbegin________________beforeend_afterend
The second parameter is the string that will be parsed into HTML. Basically inserAdjacentHTML() is innerHTML on steroids. Read about here.

javascript - drop down display on the second field based on selection in first field

I have two fields customer category and customer type,
when I select one element in customer category , I need to display only a set of elements from customer type in the drop down and rest should not appear.
how do write it in javascript. Here is the one I tried but it doesnot yield proper result.
var custcategory = document.getElementById("custcatid");
var custtypes = document.getElementById('custtypeid').options;
alert('yes');
var n = custtypes.length;
var allowedtype;
if (custcategory.options[custcategory.selectedIndex].value == "ANALOGUE") {
alert('ANALOGUE');
allowedtype = 'CATV,CATV RURAL';
}
else if (custcategory.options[custcategory.selectedIndex].value == "COMMERCIAL") {
alert('COMMERCIAL');
allowedtype = ' ,3ST HOTEL,4ST HOTEL,5ST HOTEL';
}
else if (custcategory.options[custcategory.selectedIndex].value == "DAS") {
alert('DAS');
allowedtype = ' ,DAS PHASE1,DAS PHASE2,DAS PHASE3,DAS PHASE4';
}
else if (custcategory.options[custcategory.selectedIndex].value == "DTH") {
alert('DTH');
allowedtype = ' ,DTH';
}
var idx = 0;
for (var i = 0; i < n; i++) {
var type = custtypes[i].value;
var found = allowedtype.search(type);
if (found <= 0) {
custtypes[i].style.display = 'none';
}
else if (idx == 0) {
idx = 1;
document.getElementById('ctl00_uxPgCPH_custtype').selectedIndex = i;
}
}
alert('Done..!');
If I understand correctly, you are trying to filter a second select element based on what is selected in the first select element?
If so I put together the following snippet which might help you out. It can be probably be optimised further but it should help to get you started I feel.
(function () {
var CLASSES = {
categories: '.select__category',
types : '.select__types'
},
map = {
ANALOGUE: [
'CATV',
'CATV RURAL'
],
COMMERCIAL: [
'3ST HOTEL',
'4ST HOTEL',
'5ST HOTEL'
],
DAS: [
'DAS PHASE 1',
'DAS PHASE 2',
'DAS PHASE 3'
]
},
categorySelect = document.querySelector(CLASSES.categories),
typeSelect = document.querySelector(CLASSES.types),
filterTypes = function(val) {
// Based on a value filter the types select.
var opts = typeSelect.options,
allowedOpts = map[val];
typeSelect.value = allowedOpts[0];
for(var i = 0; i < opts.length; i++) {
if (allowedOpts.indexOf(opts[i].value) === -1) {
opts[i].hidden = true;
} else {
opts[i].hidden = false;
}
}
};
filterTypes(categorySelect.value);
categorySelect.addEventListener('change', function(e) {
filterTypes(this.value);
});
}());
<!DOCTYPE html>
<head></head>
<body>
<select id="categories" class="select__category">
<option value="ANALOGUE">Analogue</option>
<option value="COMMERCIAL">Commercial</option>
<option value="DAS">Das</option>
</select>
<select id="types" class="select__types">
<option value="CATV">Catv</option>
<option value="CATV RURAL">Catv Rural</option>
<option value="3ST HOTEL">3st Hotel</option>
<option value="4ST HOTEL">4st Hotel</option>
<option value="5ST HOTEL">5st Hotel</option>
<option value="DAS PHASE 1">Das Phase 1</option>
<option value="DAS PHASE 2">Das Phase 2</option>
<option value="DAS PHASE 3">Das Phase 3</option>
</select>
</body>
If you run the snippet, you'll see that making changes to the first will update the second select accordingly based on the defined map.
Hope this can help you out!

Adding Option to Drop Down Value if it doesn't exist?

How can the code below be modified so as to allow a new value to be added to the drop down list, should the specified value not be found in the found in the drop down box?
Right now, I use the given function below to find a given value (option_name) in a drop down box.
I'd like to modify the negative flag (!flag) so as to instead of alerting me that it not has found the option_name, to basically add the new option_name in the existing drop down list.
ie.
get_position( 'drop', 'flower' )
<select id="drop" style="width: 200px;">
<option value="0"></option>
<option value="1">apples</option>
<option value="2">oranges</option>
<option value="3">pears</option>
<option value="4">mangos</option>
<option value="5">bananas</option>
<option value="6">kiwis</option>
</select>
function get_position(id,option_name) {
var flag = false;
for ( var i=0; i <= document.getElementById(id).options.length - 1; i++ ) {
if (document.getElementById(id).options[i].text === option_name) {
document.getElementById(id).selectedIndex = i;
flag = true;
}
}
}
you can use return false if any match found then add the record
function get_position(id,option_name) {
var flag = false;
var length=document.getElementById(id).options.length;
for ( var i=0; i <= length - 1; i++ ) {
if (document.getElementById(id).options[i].text == option_name) {
document.getElementById(id).selectedIndex = i;
return false;
}
}
//add item on drop down now
document.getElementById(id).options[length] = new Option( txt, length );
document.getElementById(id).selectedIndex = length;
}
if you can use Jquery then some thing like this
if($("#id option:contains('option_name')").length ==0)
{
$("#id").append(new Option("option text", "value"));
}

javascript selected options function not working in IE and safari

Any help on this would be MUCH appreciated!
I am having a problem with this javascript code in IE and Safari only.
It works fine in other browser e.g firefox and chrome.
I believe in IE and Safari it's not cycling through all the select option values correctly. e.g. in firefox there are two values for p, however in safari only 1 value.
JAVASCRIPT
<script type="text/javascript">
function selected(val, val1)
{
var len = document.getElementById('attribute122').length;
var p;
for(p=0;p<len;p++)
{
if(document.getElementById('attribute122')[p].label == val1)
{
document.getElementById('attribute122').value = document.getElementById('attribute122')[p].value;
document.getElementById('att_'+val).className = 'active';
}
else
{
if(document.getElementById('attribute122')[p].label !="Choose an Option...")
{
var chalpeveere = document.getElementById('attribute122')[p].label;
// alert(chalpeveere);
chalpeveere = chalpeveere.replace('.','_');
// alert(chalpeveere);
document.getElementById('att_' + chalpeveere).className = 'none';
}
}
}
}
</script>
HTML
<div class="input-box">
<select id="attribute122" class="required-entry super-attribute-select" name="super_attribute[122]">
<option value="">Choose an Option...</option>
<option value="3" price="0">Medium</option>
</select>
</div>
<div class="Medium">
<a id="att_Medium" class="none" href="javascript:selected('Medium', 'Medium')"> </a>
</div>
Some comments:
function selected(val, val1) {
var len = document.getElementById('attribute122').length;
Much better to store a reference to the element. If it's a select element, its length is the number of options. It's clearer to write it that way:
var select = document.getElementById('attribute122');
var len = select.options.length;
But I wouldn't set len here, see below.
It's much more common to use i, j, k, etc. as loop counters and to initialise them in the for expression. It's common to set the limit here too:
for (var i=0, len=select.options.length; i<len; i++) {
if (select[p].label == val1) {
Again, while you can access the options as properties of the select element, it's clearer to access them via the options collection. Also, the label property is more commonly known as text, so:
if (select.options[i].text == val1) {
.
document.getElementById('attribute122').value = document.getElementById('attribute122')[p].value;
Setting the selected option by setting the value of the select element is also very new behaviour, it is far more common to set the option to selected:
select.selectedIndex = i;
or
select.options[i].selected = true;
.
document.getElementById('att_'+val).className = 'active';
}
else
{
if(document.getElementById('attribute122')[p].label !="Choose an Option...")
{
Pesumably that is the first option, so you can just test:
if (select.selectedIndex != 0) {
.
var chalpeveere = document.getElementById('attribute122')[p].label;
becomes:
var chalpeveere = select.optoins[i].text;
.
// alert(chalpeveere);
chalpeveere = chalpeveere.replace('.','_');
// alert(chalpeveere);
document.getElementById('att_' + chalpeveere).className = 'none';
}
}
}
}
So the tidied code becomes:
function selected(val, val1) {
var select = document.getElementById('attribute122');
var options = select.options;
for(var i=0, iLen=options.length; i<iLen; i++) {
if (options[i].text == val1) {
options[i].selected = true;
document.getElementById('att_'+val).className = 'active';
} else {
if (select.selectedIndex != 0) {
var chalpeveere = options[i].text;
// alert(chalpeveere);
chalpeveere = chalpeveere.replace('.','_');
// alert(chalpeveere);
document.getElementById('att_' + chalpeveere).className = 'none';
}
}
}
}
In the HTML:
<a id="att_Medium" class="none" href="javascript:selected('Medium', 'Medium')">foo</a>
If you want a button, use a button:
<button id="att_Medium" class="none" onclick="
selected('Medium', 'Medium')
">Set selected</button>
or use a style span.

Categories