I have implemented HTML opt group select box.
After selecting a top element and scroll down, again when I am selecting an item which is located at the bottom of the select box.scroll position is automatically changing to top.this is not good in terms of usability.I spent lot of times to fix this issue.but still i couldnt.
https://jsfiddle.net/nsandaruwa/tj1f2gyx/5/
$('option').mousedown(function(e) {
e.preventDefault();
var originalScrollTop = $(this).parent().scrollTop();
console.log(originalScrollTop);
$(this).prop('selected', $(this).prop('selected') ? false : true);
var self = this;
$(this).parent().focus();
setTimeout(function() {
$(self).parent().scrollTop(originalScrollTop);
}, 0);
return false;
});
body {
padding: 15px;
}
.select-checkbox option::before {
content: "\2610";
width: 1.3em;
text-align: center;
display: inline-block;
}
.select-checkbox option:checked::before {
content: "\2611";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple="" class="form-control select-checkbox" size="5">
<optgroup label="One">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
<optgroup label="Two">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
<optgroup label="Three">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
</select>
Better?
$('option').mousedown(function(e) {
e.preventDefault();
const that = this;
$(this).prop('selected', $(this).prop('selected') ? false : true);
setTimeout(function() { that.scrollIntoView() },10)
return false;
});
body {
padding: 15px;
}
.select-checkbox option::before {
content: "\2610";
width: 1.3em;
text-align: center;
display: inline-block;
}
.select-checkbox option:checked::before {
content: "\2611";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple="" class="form-control select-checkbox" size="5">
<optgroup label="One">
<option>Dog 1</option>
<option>Cat 1</option>
<option>Hippo 1</option>
<option>Dinosaur 1</option>
<option>Another Dog 1</option>
</optgroup>
<optgroup label="Two">
<option>Dog 2</option>
<option>Cat 2</option>
<option>Hippo 2</option>
<option>Dinosaur 2</option>
<option>Another Dog 2</option>
</optgroup>
<optgroup label="Three">
<option>Dog 3</option>
<option>Cat 3</option>
<option>Hippo 3</option>
<option>Dinosaur 3</option>
<option>Another Dog 3</option>
</optgroup>
</select>
Related
I have used HTML multi-group selectbox as below code snippet shown.
Refer following fiddler for the code
https://jsfiddle.net/nsandaruwa/tj1f2gyx/18/
When selecting a specific option in the select box.since I have used scrollIntoView function, the frame is recentering on the current selection. This behavior is annoying for the user when it comes to user experience.
I want this multi-group select box tobe no scroll when selecting specific option.
is there any function to achieve this behavior?
HTML:
<select multiple="" class="form-control select-checkbox" size="5">
<optgroup label="One">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
<optgroup label="Two">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
<optgroup label="Three">
<option>Dog</option>
<option>Cat</option>
<option>Hippo</option>
<option>Dinosaur</option>
<option>Another Dog</option>
</optgroup>
</select>
CSS:
body {
padding: 15px;
}
.select-checkbox option::before {
content: "\2610";
width: 1.3em;
text-align: center;
display: inline-block;
}
.select-checkbox option:checked::before {
content: "\2611";
}
Jquery:
$('option').mousedown(function(e) {
e.preventDefault();
const that = this;
$(this).prop('selected', $(this).prop('selected') ? false : true);
setTimeout(function() { that.scrollIntoView() },10)
return false;
});
$('option').mousedown(function(e) {
e.preventDefault();
var originalScrollTop = $(this).parent().parent().scrollTop();
$(this).prop('selected', $(this).prop('selected') ? false : true);
var self = this;
$(this).parent().parent().focus();
setTimeout(function() {
$(self).parent().parent().scrollTop(originalScrollTop);
}, 0);
return false;
});
Fiddle URL for the solution
https://jsfiddle.net/nsandaruwa/0sphnk5z/1/
I have this multi-select
$('#hide_col').change(function() {
var arr = $(this).val();
localStorage.setItem('hide', arr);
var hide_cols = localStorage.getItem('hide');
var hide;
for (hide = 0; hide <= 28; hide++) {
if (hide_cols.includes('row' + hide)) {
$('.row' + hide).hide();
} else {
$('.row' + hide).show();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="input-group" style="direction: rtl; margin-top: 5px;width: 600px;">
<select name="hide" data-live-search="true" id="hide_col" class="selectpicker w-25 check_info js-example-basic-multiple" multiple data-style="btn-info">
<option value="row1">סטטוס/יום</option>
<option value="row2">תאריך</option>
<option value="row3">שידור/ משחק</option>
<option value="row4">ליגה/סוג שידור</option>
<option value="row5">שידור</option>
<option value="row6">ערוץ</option>
<option value="row7">הערות אישיות</option>
<option value="row8">מיקום</option>
<option value="row9">חדר</option>
<option value="row10">שדר/פרשן</option>
<option value="row11">קווים/פאנל</option>
<option value="row12">עורך</option>
<option value="row13">במאי/עוזר במאי</option>
<option value="row14">מפיק</option>
<option value="row15">טכנאי</option>
<option value="row16">בקליינר/עוזר צלם</option>
<option value="row17">מספר מצלמות/צלמים </option>
<option value="row18">מפקח קול</option>
<option value="row19">REPLAY</option>
<option value="row20">CG</option>
<option value="row21">רשם</option>
<option value="row22">מפיק אופטיוב/טכנאי אופטיוב</option>
<option value="row23">מאפרת/מלבישה</option>
<option value="row24">שיבוץ ציוד</option>
<option value="row25">רכבים/נגררים</option>
<option value="row26">קופה</option>
<option value="row27">כרטיס</option>
<option value="row28">שלח הודעה/מחק שידור</option>
</select>
</div>
how can I trigger the function to select the values from the array after the page is reloading and trigger the hide action as well?
the array is stored in the local store
if I use the $('#hide_col').val('.row'+hide);
inside the function, after the page is loading I get only the last result in the array selected and the hide action is not triggerd
Example cannot run here.. but it should work.
The key change is $('select[name*="hide"] > option[value="row'+hide+'"]').hide();
$( document ).ready(function() {
var arrStr = localStorage.getItem('hide');
hideSelected(arrStr.split(','))
});
$('#hide_col').change(function() {
var arr = $(this).val();
localStorage.setItem('hide', arr);
hideSelected(arr);
});
function hideSelected(arr){
var hide;
for (hide = 0; hide <= 28; hide++) {
if (arr.includes('row' + hide)) {
$('select[name*="hide"] > option[value="row'+hide+'"]').hide();
} else {
$('select[name*="hide"] > option[value="row'+hide+'"]').show();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="input-group" style="direction: rtl; margin-top: 5px;width: 600px;">
<select name="hide" data-live-search="true" id="hide_col" style='height:400px' class="selectpicker w-25 check_info js-example-basic-multiple" multiple data-style="btn-info">
<option value="row1">סטטוס/יום</option>
<option value="row2">תאריך</option>
<option value="row3">שידור/ משחק</option>
<option value="row4">ליגה/סוג שידור</option>
<option value="row5">שידור</option>
<option value="row6">ערוץ</option>
<option value="row7">הערות אישיות</option>
<option value="row8">מיקום</option>
<option value="row9">חדר</option>
<option value="row10">שדר/פרשן</option>
<option value="row11">קווים/פאנל</option>
<option value="row12">עורך</option>
<option value="row13">במאי/עוזר במאי</option>
<option value="row14">מפיק</option>
<option value="row15">טכנאי</option>
<option value="row16">בקליינר/עוזר צלם</option>
<option value="row17">מספר מצלמות/צלמים </option>
<option value="row18">מפקח קול</option>
<option value="row19">REPLAY</option>
<option value="row20">CG</option>
<option value="row21">רשם</option>
<option value="row22">מפיק אופטיוב/טכנאי אופטיוב</option>
<option value="row23">מאפרת/מלבישה</option>
<option value="row24">שיבוץ ציוד</option>
<option value="row25">רכבים/נגררים</option>
<option value="row26">קופה</option>
<option value="row27">כרטיס</option>
<option value="row28">שלח הודעה/מחק שידור</option>
</select>
</div>
This question is already asked here and it's perfectly answered, but the problem is it doesn't work properly in Safari like it does in Chrome. In Safari, neither optgroup nor option support display: none.
Is there any way to get it to work like it does in Chrome?
Here is codepen Snippet
$.each($('#u-address > optgroup'), function() {
$(this).clone().empty().appendTo('#m-address');
});
myOgVisibility();
//for dblclick
$('#u-address').dblclick(function() {
$.each($('#u-address option:selected'), function() {
var og = $(this).parent().attr('class');
$(this).remove().appendTo('#m-address .' + og);
$(this).removeAttr('selected');
});
myOgVisibility();
});
$('#m-address').dblclick(function() {
$.each($('#m-address option:selected'), function() {
var og = $(this).parent().attr('class');
$(this).remove().appendTo('#u-address .' + og);
$(this).removeAttr('selected');
});
myOgVisibility();
});
function myOgVisibility() {
$.each($('.showUniOgrp > optgroup'), function() {
if ($(this).html().trim() === "") {
//$(this).detach();
//$(this).css({'display': 'none'});
//$(this).attr('disabled', 'disabled').hide();
$(this).css({
'height': '0px !important',
'display': 'none'
});
} else {
//$(this).appendTo('#m-address');
//$(this).css({'display': 'block'});
//$(this).removeAttr('disabled').show();
$(this).css({
'height': 'auto',
'display': 'block'
});
}
});
}
select {
display: inline-block;
width: 30%;
height: 200px;
border-radius: 5px;
overflow: hidden;
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="u-address-fields">
<select size="15" multiple="multiple" class="showUniOgrp" id="u-address">
<optgroup class="og-swe" data-opt="qq" label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup class="og-ger" data-opt="qq" label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</optgroup>
<optgroup class="og-ita" data-opt="qq" label="Italian Cars">
<option value="ferrari">Ferrari</option>
<option value="lamborghini">Lamborghini</option>
</optgroup>
</select>
</div>
<div class="my-address-fields">
<select size="15" multiple="multiple" class="showUniOgrp" id="m-address">
</select>
</div>
You're gonna need a third select with all the optgroups and options which is hidden. You can use it in different ways to achieve what you want but here's one way:
You have all the info in the hidden select (#h-address) and once an option is selected you add a class to it (.slctd) and if unselected you remove the class. Then populate the two visible selects and remove undesired parts from each.
$.each($('#h-address > optgroup'), function() {
$(this).clone().appendTo('#u-address');
});
$('#u-address').dblclick(function() {
$.each($('#u-address option:selected'), function() {
$('#hidden-fields option[value=' + $(this).val() + ']').addClass('slctd');
showFields();
});
});
$('#m-address').dblclick(function() {
$.each($('#m-address option:selected'), function() {
$('#hidden-fields option[value=' + $(this).val() + ']').removeClass('slctd');
showFields();
});
});
function showFields() {
$('#u-address').empty();
$('#m-address').empty();
$.each($('#h-address > optgroup'), function() {
$(this).clone().appendTo('#u-address');
$(this).clone().appendTo('#m-address');
});
$('#u-address option.slctd').remove();
$('#m-address option:not(.slctd)').remove();
$.each($('.showUniOgrp > optgroup'), function() {
if ($(this).html().trim() === "") {
$(this).remove(); //or detach()
}
});
}
select {
display: inline-block;
width: 30%;
height: 200px;
border-radius: 5px;
overflow: hidden;
float: left;
}
#hidden-fields {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="u-address-fields">
<select size="15" multiple="multiple" class="showUniOgrp" id="u-address"></select>
</div>
<div class="my-address-fields">
<select size="15" multiple="multiple" class="showUniOgrp" id="m-address"></select>
</div>
<div id="hidden-fields">
<select size="15" multiple="multiple" class="showUniOgrp" id="h-address">
<optgroup class="og-swe" data-opt="qq" label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup class="og-ger" data-opt="qq" label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
<option value="bmw">BMW</option>
</optgroup>
<optgroup class="og-ita" data-opt="qq" label="Italian Cars">
<option value="ferrari">Ferrari</option>
<option value="lamborghini">Lamborghini</option>
</optgroup>
</select>
</div>
Haven't tested on Safari, but it should work.
I use the selec2 plugin and I want to remove an option from my main option list. When I click on "x" button by this code, it removes just from plugin list. After close/open it recovers.
Can anyone help me?
jsfiddle
HTML:
<select id="select">
<option value="Provider 1">Provider 1</option>
<option value="Provider 2">Provider 2</option>
<option value="Provider 3">Provider 3</option>
<option value="Provider 4">Provider 4</option>
<option value="Provider 5">Provider 5</option>
</select>
JS:
function format(state) {
if (state.id == null) {
return state.text;
}
var $option = $("<span></span>");
var $preview = $('<span class="select2-item-remove">×</span>');
$preview.on('mouseup', function (e) {
e.stopPropagation();
});
$preview.on('click', function (e) {
$(this).closest('li').remove();
});
$option.text(state.text);
$option.append($preview);
return $option;
}
$("#select").select2({
templateResult: format,
escapeMarkup: function (m) { return m; }
});
You have to remove also the option element.
So here is your fiddle updated:
https://jsfiddle.net/beaver71/0wz9m7gz/
$(document).ready(function () {
function format(state) {
if (state.id == null) {
return state.text;
}
var $option = $("<span></span>");
var $preview = $('<span data-opt="'+state.element.id+'" class="select2-item-remove">×</span>');
$preview.on('mouseup', function (e) {
e.stopPropagation();
});
$preview.on('click', function (e) {
$(this).closest('li').remove();
var opt = $(this).data('opt');
$("#"+opt).remove();
});
$option.text(state.text);
$option.append($preview);
return $option;
}
$("#select").select2({
templateResult: format,
escapeMarkup: function (m) { return m; }
});
});
.select2-results__option {
position: relative;
}
.select2-item-remove {
position: absolute;
right: 9px;
top: 5px;
z-index: 1100;
z-index: 9999;
cursor: default;
display: block;
font-weight: bold;
font-size: 15px;
padding: 0 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.full.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.css" rel="stylesheet"/>
<select id="select" multiple="multiple" style='width:300px'>
<option id="opt1" value="Provider 1">Provider 1</option>
<option id="opt2" value="Provider 2">Provider 2</option>
<option id="opt3" value="Provider 3">Provider 3</option>
<option id="opt4" value="Provider 4">Provider 4</option>
<option id="opt5" value="Provider 5">Provider 5</option>
</select>
Edit, yes I am aware of this question but that answer is not completely working for my case
I'm looking for a solution for this case
When a user selects an option from one select box the option should be hidden for the other select boxes.
When a selected option changes or is removed (select a blank option) the previously selected option should become available again to the other select boxes.
The problem with my current code:
When an option changes, the previous option is not "released" to the other select boxes so they can not use it again until the page reloads.
Basically, results in previously selected options are dissapearing from other select boxes.
I included a fiddle so you can see it for youself.
$(document).ready(function() {
// this "initializes the boxes"
$('.update-select').each(function(box) {
var value = $('.update-select')[box].value;
if (value) {
$('.update-select').not(this).find('option[value="' + value + '"]').hide();
}
});
// this is called every time a select box changes
$('.update-select').on('change', function(event) {
var prevValue = $(this).data('previous');
$('.update-select').not(this).find('option[value="' + prevValue + '"]').show();
var value = $(this).val();
if (value) {
$(this).data('previous', value);
console.log($(this).data('previous', value));
$('.update-select').not(this).find('option[value="' + value + '"]').hide();
}
});
});
* {
box-sizing: border-box;
font-size: 1em;
font-family: sans-serif;
}
body {
display: flex;
float: right;
}
body div {
margin: 20px;
}
select {
border: 2px solid #78909c;
padding: 10px;
border-radius: 5px;
outline: none
}
select:focus {
border: 2px solid #ff9800;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h3>stock 1</h3>
<select name="tracker[stockitems][0]" class="update-select">
<option value=""></option>
<option value="1" selected>tracker 1</option>
<option value="3">tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
<div>
<h3>stock 2</h3>
<select name="tracker[stockitems][1]" class="update-select">
<option value=""></option>
<option value="1">tracker 1</option>
<option value="3" selected>tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
<div>
<h3>stock 3</h3>
<select name="tracker[stockitems][2]" class="update-select">
<option value=""></option>
<option value="1">tracker 1</option>
<option value="3">tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
It's as simple as this. Just .show() all the option's and reinitialize the select's using your previous code.
$(document).ready(function() {
function intializeSelect() {
// this "initializes the boxes"
$('.update-select').each(function(box) {
var value = $('.update-select')[box].value;
if (value) {
$('.update-select').not(this).find('option[value="' + value + '"]').hide();
}
});
};
intializeSelect();
// this is called every time a select box changes
$('.update-select').on('change', function(event) {
$('.update-select').find('option').show();
intializeSelect();
});
});
* {
box-sizing: border-box;
font-size: 1em;
font-family: sans-serif;
}
body {
display: flex;
float: right;
}
body div {
margin: 20px;
}
select {
border: 2px solid #78909c;
padding: 10px;
border-radius: 5px;
outline: none
}
select:focus {
border: 2px solid #ff9800;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h3>stock 1</h3>
<select name="tracker[stockitems][0]" class="update-select">
<option value=""></option>
<option value="1" selected>tracker 1</option>
<option value="3">tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
<div>
<h3>stock 2</h3>
<select name="tracker[stockitems][1]" class="update-select">
<option value=""></option>
<option value="1">tracker 1</option>
<option value="3" selected>tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
<div>
<h3>stock 3</h3>
<select name="tracker[stockitems][2]" class="update-select">
<option value=""></option>
<option value="1">tracker 1</option>
<option value="3">tracker 2</option>
<option value="4">test tracker1</option>
<option value="6">another tracker</option>
<option value="9">the last tracker</option>
</select>
</div>
This is my solution:
$(document).ready(function() {
$(document).on('change', '.update-select', function(e) {
$('option').show();
var selectedOptionsGlobal = [];
$.each($('.update-select'), function(key, select) {
var selectedOptionValue = $(select).val();
if (selectedOptionValue !== "") {
selectedOptionsGlobal.push(selectedOptionValue);
}
});
for (var i = 0; i < selectedOptionsGlobal.length; i++) {
$('option[value="'+selectedOptionsGlobal[i]+'"]').hide();
}
});
});