Cloned bootstrap-selectpicker selections off by 1 - javascript

When I clone a bootstrap-select dropdown, the cloned dropdown seems to offset selections by 1. I.e., if I click the second option, the first one is selected.
For example:
If I click "New Castle" in the original dropdown, then "New Castle" is selected
If I click "New Castle" in the cloned dropdown, then "Kent" is selected
The error I get is:
bootstrap-select.js:2727 Uncaught TypeError: Cannot read property 'firstChild' of undefined
Why might this be happening?
A JSFiddle of the error is here: http://jsfiddle.net/jh4wztab/1/
Below is my code:
var count = 2;
$(document).on("click", "#clonejurisdiction", function() {
addselectpicker(count);
count++;
});
function addselectpicker(juriscount) {
juriscount = parseInt(juriscount)
var picker = $('#jurisdictionpicker');
var clone = picker.clone();
var pickercount = juriscount + 1;
clone.attr("id",'jurisdiction' + juriscount);
clone.find(".selectpicker").attr("id",'jurisdictionpicker' + juriscount);
clone.find("[data-id='jurisdiction_']").hide();
clone.appendTo(".juris_name");
clone.find('.selectpicker').selectpicker();
clone.find(":input").attr("placeholder", "Enter a State, County");
}
HTML
<div id="jurisdictionpicker">
<select class="selectpicker jurisdiction" data-live-search="true" data-size="8" title="Select County, State" id="jurisdiction_">
<optgroup label="Popular">
<option value='317'>Kent</option>
<option value='318'>New Castle</option>
<option value='1859'>New York</option>
</optgroup>
<optgroup label="Jurisdictions">
<option value='1'>Autauga</option>
<option value='2'>Baldwin</option>
<option value='3'>Barbour</option>
<option value='4'>Bibb</option>
</optgroup>
</select>
</div>
<button id="clonejurisdiction">
Clone
</button>
<BR><B>Cloned version:</B>
<div class="juris_name">
</div>

Your main problem is when trying to do var clone = picker.clone();, that code is not actually cloning your original HTML markup for your select element. When using Bootstrap and writing your HTML markup for a select element like <select class="selectpicker">, when you use the class selectpicker the bootstrap javascript transforms your original markup into bootstraps select markup using parts of your original HTML. Once the DOM is rendered, the select element you are interacting with in your browser is not code that you originally wrote at all, it is boostrap's transformation of your HTML. So when you trying to clone() the bootstrap select element and then calling selectpicker() on it, it was trying to force bootstrap to transform HTML that was not in a state that it expected it to be to transform it, and was causing your unexpected behavior.
One way to solve this problem is to make your original HTML markup reusable. An easy way to do this is templating. When doing this you can get your template and add whatever view data you need to it and then have bootstrap transform your template HTML on the fly using selectpicker()
Here is a modified version of you originally posted code using Mustache.js for templating purposes. This performs what you wanted without your original select picker bug:
Here is the updated JSFiddle.
javascript:
var count = 1;
$(document).ready(function() {
$("#someDiv").append(getJurisdictionPicker(count));
});
$(document).on("click", "#clonejurisdiction", function() {
var picker = getJurisdictionPicker(count);
$("#jurisName").append(picker);
});
function getJurisdictionPicker(juriscount) {
var template = $("#jurisdictionPickerTemplate").html();
var data = { counter : juriscount };
var templatedText = Mustache.render(template, data);
var temp = $(document.createElement("div")).html(templatedText);
temp.find(".selectpicker").selectpicker();
count++;
return temp;
}
HTML:
<script id="jurisdictionPickerTemplate" type="text/template">
<div id="jurisdictionpicker{{ counter }}">
<select class="selectpicker" data-live-search="true" data-size="8" title="Select County, State">
<optgroup label="Popular">
<option value='317'>Kent</option>
<option value='318'>New Castle</option>
<option value='1859'>New York</option>
</optgroup>
<optgroup label="Jurisdictions">
<option value='1'>Autauga</option>
<option value='2'>Baldwin</option>
<option value='3'>Barbour</option>
<option value='4'>Bibb</option>
</optgroup>
</select>
</div>
</script>
<div id="someDiv">
</div>
<button id="clonejurisdiction">
Clone
</button>
<BR><B>Cloned version:</B>
<div id="jurisName">
</div>
<BR><BR>
If I click "New Castle" in the original dropdown, then "New Castle" is selected<BR>
If I click "New Castle" in the <B>cloned</B> dropdown, then "Kent" is selected<BR>

Related

Show div if select option item is selected. Problem with reloading

Hi I have HTML bootstrap code:
$(document).ready(function() {
$("#us-state").find('select').change(function() {
var $val = $(this).val();
if ($val === 'US') {
$('.us-state-select').show();
} else {
$('.us-state-select').hide();
}
});
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="col-sm mb-5 us-state-select">
<label>USA STATE</label>
<select name="order_from_address_state" class="form-select">
<option>Choose country</option>
<option value="AL" name="<AL>" selected>Alabama</option>
<option value="AK" name="AK">Arkansas</option>
</select>
</div>
<div class="col-sm mb-5" id="us-state"><label>Send from country</label>
<select name="order_from_address_country" class="form-select">
<option>Send from</option>
<option value="US" name="US">USA</option>
<option value="CA" name="CA" selected>Canada</option>
</select>
</div>
(Also available on JSFiddle)
My problem is simple.
I am using foreach to show all countries and statesm but...
check the jsfiddle.
if country is selected different to the US and its load with this different country, it shows div us-state-select and if u click on different countries, it dissapears and works as expected.
But I dont want to show div with states in the case that page is loaded and its selected different country than US. How to do that?
its obvious on fiddle, I selected canada and on page load there is div with states and when click on different value for example: Send from at country box, states dissapear and it works as expected then.
Please, can you give me some advice?
I am newbie at jquery, thx.
Change your JS to be like this:
I am basically checking this logic once the page is ready and I also added some refactor in your code to help readability
$(document).ready(function() {
const checkValues = () => {
var value = $("#us-state").find('select').val();
console.log(value)
if(value === 'US'){
$('.us-state-select').show();
}else{
$('.us-state-select').hide();
}
}
$("#us-state").ready(checkValues);
$("#us-state").find('select').change(checkValues);
});

Change a options value when selected from options

i have a drop-down that has values which are exceeding the current div's width. i want to show only a part of the text when that option is selected. i tried extending the width but the form structure is getting messed up.
<div class="calci-input">
<select id="g-suite-pac-id" name="g-suite-package">
<option value="2.40">$2.40/month</option>
<option value="4.00">$4.00/month</option>
<option value="2.00">$2.00/month(12 months)</option>
<option value="3.33">$3.33/month (12 months)</option>
</select>
</div>
how can i achieve this using jQuery ?
the expected output is that when the option $2.00/month(12 months) is selected it shows as $2.00/month in the drop-down.
The solution comes with the onchange and onmousedown event. Using jQuery's selectors we can get the selected option and change its display HTML.
//you really don't need jQuery, but we can wrap it in there.
//wrap in ready function to make sure page is loaded
$(document).ready(function() {
$("select#g-suite-pac-id").on("change", function() {
var text = $(this).children("option").filter(":selected").text()
var edited = text.match(/^.+?\/month/); //use regex | ^ start, .+? lazy search for everything until /month
//save
$(this).children("option").filter(":selected").data("save", text);
//change
$(this).children("option").filter(":selected").text(edited);
});
$("select#g-suite-pac-id").on("mousedown", function(e) {
//restore a saved value
var selected = $(this).children("option").filter(":selected");
if (selected.length > 0)
{
if (selected.data("save"))
{
selected.text(selected.data("save"));
selected.removeData("save");
}
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="calci-input">
<select id="g-suite-pac-id" name="g-suite-package">
<option value="2.40">$2.40/month</option>
<option value="4.00">$4.00/month</option>
<option value="2.00">$2.00/month(12 months)</option>
<option value="3.33">$3.33/month (12 months)</option>
</select>
</div>
Set width of select component to any fixed width like below:
<div class="calci-input">
<select id="g-suite-pac-id" name="g-suite-package" style="width:96px">
<option value="2.40">$2.40/month</option>
<option value="4.00">$4.00/month</option>
<option value="2.00">$2.00/month(12 months)dffsdfsdfdsfsdfdsfdsfsd</option>
<option value="3.33">$3.33/month (12 months)</option>
</select>
</div>
try above code, it shows text that can fit in 96px width.

Select2 jquery plugin show number of selected items in the result instead of tags

I am using Select2 jQuery Plugin.
https://select2.github.io/ for reference
When I am using the multiple dropdown option. The result of selected items is shown as tags in a box but, I just want to show the number of items selected.
Is it possible with Select2 jQuery plugin
HTML
<select multiple style="width:100%">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
<option value="5">Name5</option>
<option value="6">Name6</option>
<option value="7">Name7</option>
</select>
JS
$('select').select2();
I want output as below
instead of tag like output.
Example working Fiddle
You can add this code after initializing select2
$('select').on('select2:close', function (evt) {
var uldiv = $(this).siblings('span.select2').find('ul')
var count = $(this).select2('data').length
if(count==0){
uldiv.html("")
}
else{
uldiv.html("<li>"+count+" items selected</li>")
}
Ref: jsfiddle
Reference to select2 events: Here
Edit: If you want to display a blank when user deselects everything,
Use this fiddle: here
Edit: Updated to remove flaw in deselection of data and changed it to main answer.
Fiddle: here
Selectors can certainly be improved, but as a blueprint, adding a counter element on change and hiding the tags like this seems to work as asked.
$('select').select2({closeOnSelect: false}).on("change", function(e) {
$('.select2-selection__rendered li:not(.select2-search--inline)').hide();
$('.counter').remove();
var counter = $(".select2-selection__choice").length;
$('.select2-selection__rendered').after('<div style="line-height: 28px; padding: 5px;" class="counter">'+counter+' selected</div>');
});
.counter{
position:absolute;
top:0px;
right:5px;
}
.select2-search--inline{
background-color:Gainsboro;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet"/>
<select multiple style="width:100%" id="mySelect">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
<option value="5">Name5</option>
<option value="6">Name6</option>
<option value="7">Name7</option>
</select>
although the answer is given.
you can try this code. first initialize than on close call it.
jQuery('.multi-select-pbwp').select2();
$('.multi-select-pbwp').on('select2:close', function() {
const $select = $(this);
const numSelected = $select.select2('data').length;
$select.next('span.select2').find('ul').html(function() {
return `<li class="class="select2-selection__choice">${numSelected} selected</li>`;
})
});

Add/Removing Options with JQuery

I'd like to add and remove options from one drop down menu using JQuery given a selected option in another.
HTML:
<form action='quickLook.py' method = 'post'>
First DropDown Menu
Specify Channel:
<select id='bolometer'>
<option selected id='Dual' value = 'Dual' >Dual
<option id='Top' value = 'Top' >Top
<option id='Bottom' value = 'Bottom' >Bottom
</select>
Second DropDown Menu
<br>Specify Data to Display:
<select id='target'>
<option selected id='Spectrum' value = 'Spectrum'>Spectrum
<option id='Interferogram' value = 'Interferogram'>Interferogram
<option id='SNR' value = 'SNR'>SNR
<option id='Diff_Band' value = 'Diff_Band'> Diff_Band
</select>
<input type='submit' value= 'Query Images'>
</form>
I'd like to do something like this is JQuery:
$("#Dual").click(function() {
$("#target").append("#Diff_Band");
$("#target").remove("#Interferogram");
$("#target").remove("#SNR");
});
$("#Top").click(function() {
$("#target").append("#Interferogram");
$("#target").append("#SNR");
$("#Diff_Band").remove();
});
I want to append or remove the already written html.
What is the best way to do this?
Thank you for your time!
This is a similar problem I've encountered before working with Safari. A solution is to use .detach() instead of remove() as it keeps all jQuery data associated with the removed elements. Check this jsfiddle: http://jsfiddle.net/Ueu62/

Display options in a drop-down based on what is selected in another drop-down

I want to display options in a drop down menu based on what is already selected in another drop down menu. I have 16 options in the first drop-down, so I want to show different options in the second drop down for each selection in the first. I would like to do this using javascript or jquery.
Here is the first drop down in my html file:
<div>
<label for="failureReason">Failure Reason:</label> <select
id="failureReason" data-theme="a" data-icon="arrow-d" data-iconpos="right">
<option value="1">Damage</option>
<option value="9">Calibration Failure</option>
<option value="5">Component Failure</option>
<option value="93">Customer Request</option>
<option value="5">Error on Potted SUT</option>
<option value="41">Installation Error</option>
<option value="6">Interference</option>
<option value="46">Network Issue</option>
<option value="3">No Fault Found</option>
<option value="8">No Power/Fuse Blown</option>
<option value="23">Non-AMCS Issue</option>
<option value="49">OBC HW Issue</option>
<option value="30">OBC SW Issue</option>
<option value="2">Training Issue</option>
<option value="68">Truck Not Available</option>
<option value="51">Routine Maintenance</option>
</select>
<!-- Put in options for failure reason -->
</div>
And I want to display different options inside this drop-down depending on what has been selected for "Failure Reason":
<div>
<label for="solutionId">Solution Id:</label> <select
id="solutionId" data-theme="a" data-icon="arrow-d" data-iconpos="right">
<option value="1">Repaired</option>
<option value="2">Restarted</option>
<option value="3">Reinstalled Software</option>
<option value="4">Replaced Loadcell</option>
<option value="5">Replaced SUT</option>
</select>
<!-- Put in options for Solution Id -->
</div>
I've seen other examples, but nothing like what i'm trying to achieve. I need to be able to get the "value" of whatever option is shown and chosen for use in other parts of my javascript file.
EDIT:
I realise my question is a bit confusing. I'll try to be more clear.
If "damage" is selected for failure reason, I want to show:
<div>
<label for="solutionId">Solution Id:</label> <select
id="solutionId" data-theme="a" data-icon="arrow-d" data-iconpos="right">
<option value="1">Repaired</option>
<option value="3">Reinstalled Software</option>
<option value="4">Replaced Loadcell</option>
</select>
<!-- Put in options for Solution Id -->
</div>
But if "calibration failure" is chosen, I want to show:
<div>
<label for="solutionId">Solution Id:</label> <select
id="solutionId" data-theme="a" data-icon="arrow-d" data-iconpos="right">
<option value="1">Repaired</option>
<option value="2">Restarted</option>
<option value="5">Replaced SUT</option>
</select>
<!-- Put in options for Solution Id -->
</div>
JS fiddle solution:
http://jsfiddle.net/ZjhWV/1/
Not the best solution, but working one. Make a some list of text contents from first select and link them with available options from second one.
I used textContent from first one and linked it with option values from second one. But you can make link based on different property of the option (id, value, text content... ).
You can get text content from currently selected option with this.options[this.selectedIndex].textContent.
PS: In case that array is empty, all options are available...
javascript:
var subselectContains = {
"Damage": [1, 3, 5],
"Calibration Failure": [],
"Component Failure": [2],
"Customer Request": [],
"Error on Potted SUT": [1],
"Installation Error": [],
"Interference": [],
"Network Issue": [],
"No Fault Found": [],
"No Power/Fuse Blown": [],
"Non-AMCS Issue": [],
"OBC HW Issue": [],
"OBC SW Issue": [],
"Training Issue": [],
"Truck Not Available": [],
"Routine Maintenance": []
};
var failureReson = $("#failureReason");
var solutionOptions = $("#solutionId option");
failureReson.change(function () {
var visibleOptions = subselectContains[this.options[this.selectedIndex].textContent];
if (visibleOptions.length != 0) {
solutionOptions.hide();
solutionOptions.each(function () {
for (var i = 0; i <= visibleOptions.length; i++) {
if (this.value == visibleOptions[i]) {
$(this).show();
}
}
});
} else {
solutionOptions.show();
}
});
EDIT: My solution is just a short version. It works only when you change first select and it doesn't affect the currently selected option. But I'm sure you can solve this on your own ;)
Hope already you got answer but it is easy answer. check this post I don't have reputation to comment so posting as answer . check this answer its good and clear.
Javascript change drop-down box options based on another drop-down box value
Use a .change event on the first drop down, grab the value, and do what you need:
$("#failureReason").change(function() {
var selected = this.value;
var second = $("#solutionId option:selected").val();
});
First you have to define the combinations.
var combinations = {
"option1": ["option1-a", "option1-b", "option1-c"],
"option2": ["option2-a", "option2-b", "option2-c"],
"option3": ["option3-a", "option3-b", "option3-c"]
}
So in your first drop down you would add a .change event that would find the new value, then fill the second drop down with those options.
$('#failureReason').change(function(){
var template = '<option>Solutions</option>'; // will hold html for second drop down.
solutions = combinations[$(this).val()];
$.each(solutions, function(i, solution){
template += '<option value="' + solution + '">' + solution + '</option>'
});
$('#solutionId').html(template);
});
If you'll notice, I just gave each option the same value as the text displayed. It would be fairly simple to give each option a custom value.
JSFiddle:
http://jsfiddle.net/2hwp9/

Categories