I am wanting to try to change or limit a drop down list using JavaScript, or some other solution. Unfortunately, I have no control over the way the HTML comes out that I am trying to change client side. The drop down list is generated server side, but we would like to give the user additional options to further limit the choices in the drop down list.
We can't edit what is generated, but we can insert HTML.
One suggested solution, which may not be possible, is to use JavaScript to limit the dropdown list. For example, the drop down follows the format of:
<SELECT ID="dropdown_1">
<OPTION VALUE="" >None
<OPTION VALUE="1000">AB-ITEM 1 DESCRIPTION
<OPTION VALUE="2001">AB-ITEM 2 DESCRIPTION
<OPTION VALUE="50" >AB-ITEM 8 DESCRIPTION
<OPTION VALUE="70" >BB-ITEM 3 DESCRIPTION
<OPTION VALUE="100" >BB-ITEM 5 DESCRIPTION
<OPTION VALUE="2" >ABB-ITEM 4 DESCRIPTION
</SELECT>
What I want to limit by the beginning of the text, so AB-, BB-, or ABB- in this case. The value has no rhyme or reason, it's just an index number. I don't think this is possible since this is just text, and not associated with an attribute.
One thought would be to be to:
Store the list into a JavaScript array
Keep only entries like 'TYPE-X%'
Delete original HTML list
Replace with new list stored in the Array
However, I'm not sure if this is possible, and if it is, what would be needed to create such code. Any help or references to functions or examples would be greatly appreciated.
Anything is possible (with jQuery):
$(document).ready(function() {
$("#dropdown_1 option").hide();
$("#dropdown_1 option").filter(":contains(TYPE-X)").show();
});
An advantage with this is that all of the options are still there, you just can't see them. So all it would take to return to the default list would be a call to:
$("#dropdown_1 option").show();
Edit for regex:
$(document).ready(function() {
$("#dropdown_1 option").hide();
$("#dropdown_1 option").filter(function() {
return $(this).text().match(/^AB-/);
}).show();
});
You can filter your list using a regex like seen above.
Edit: A note about jQuery, this in the filter function is the DOM element itself. In order to access the jQuery helper method text(), I first need to wrap that DOM element with the jQuery function, as edited above.
Thanks to BinaryTox1n, I was put on a good path to find an all-browser compatible solution to my question. However, it is a slightly different approach pieced together from other solutions on StackOverFlow.
The difference comes is how one deals with the OPTIONs. Though .hide() works on some browsers, it is not compatible with IE8 (and maybe some others). Alternatives and variations to .hide() also failed. Another problem with .hide() is that you also need to use .disable(). The last problem is that if you have several (20 or so) options and only 2 or 3 are visible, Chrome (and perhaps other browsers) do not render the dropdown box properly.
The best approach found is to .remove() unwanted options. No compatibility issues because the OPTION is simply removed. However, I also want to have the flexibility to add back options if needed. So the following is a version of what I'll be using:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var regex_str = "^AAB-";
var dd1 = $("#dropdown1 option");
//Clone the 'None', Current, and All options into respective variables.
//All options are stored in order to allow different selection criteria
var all_Opt = dd1.clone(true);
var none_Opt = dd1.filter(":contains(None)").clone(true);
var cur_Opt = dd1.filter(function(){
return $(this).text().match(regex_str);
}).clone(true);
//Remove all options and replace the 'None' and Current options
dd1.remove();
noneOpt.appendTo($("#dropdown1"));
curOpt.appendTo($("#dropdown1"));
});
</script>
The only thing I'd like to add is the ability for this to change using a different drop down box or some other trigger.
Related
I posted a similar question a few days ago, but it seems that the reference solution did not work as there seemed to be a bootstrap conflict, where the jQuery was affecting the select element instead of the additional divs generated by bootstrap
For reference, I have a 2 <select> elements which look like the following:
<select class="selectpicker form-control alternate-linked-select-box" id="input-room">
<option>...</option>
</select>
The intended, functionality I am trying to achieve, is to completely deselect the other element when the current <select> element has been changed.
The previously proposed solution with jQuery was this. I'll also include it here for reference:
var sels = $(".alternate-linked-select-box").on("change", e =>
sels.not(e.target).find("option:selected").prop("selected", false)
);
However, this does not work with bootstrap as the select elements do not seem to be affected.
Since then, I've also tried disabling everything to see if it had any affect, but to no avail.
$('.alternate-linked-select-box').selectpicker('val', '');
I presume I am doing something very wrong, as I have never really used bootstrap before. Any help is appreciated!
For example you have 2 selections with id input-room1 and input-room2, apply below code to reset room2 selection when room1 selection is changed.
$(document).ready(function(){
//init
$("#input-room1").prop("selectedIndex", -1);
$("#input-room2").prop("selectedIndex", -1);
})
$('#input-room1').on('change',function(){
$("#input-room2").prop("selectedIndex", -1);
})
So, I have this multiple choice select2 that gets its options via database query and I wanted to show in an input the number of options that are selected. However, I wanted to do it as soon as they are selected and I don't know how to do it. For example, if I choose 2 options and then, later, I decide to add one more, I want the input to change to 3 options selected. Any help is appreciated and if you have other ideas like how I can do similar stuff but not like how I described it your help is appreciated too. Thanks
<select name="select_areas_educ_form" id="select_areas_educ_form" class="form-control js-example-tokenizer" multiple="multiple">
<?php foreach ($areas_educacao as $area)
{
echo '<option value="'.$area['id_areaeducacao'].'">'.$area['cod'].' - '.$area['designacao'].'</option>';
}
?>
</select>
So, its much more simple than what I expected, so if anyone need the answer I'll leave it here. You just basically need to add an "onChange" in your select that calls a function. The function will count the number of options selected via jquery and after, change the placeholder of the input. Its very simple and now I can't explain how I didn't think of this before
function opcoes_select_areas_educ_form()
{
var n_opcoes = $("#select_areas_educ_form :selected").length;
document.getElementById("total_areas").placeholder = n_opcoes;
}
Does anyone have any solution to improve the speed when deleting/adding <option> from a <select> when it has 60k+ elements?
I've a form with two <select>, let's call them selectA and selectB. I want the values of selectB to change when selectA is changed. Like (code not functional, just for idea):
if selectA = option1
then selectB.options = [opt1_1, opt1_2, opt1_3, ...]
else if selectA = option2
then selectB.options = [opt2_1, opt2_2, opt2_3, ...]
...
I have a (quite huge) variable that gives me the list of option for selectB associated with selectA value.
I've found many example for that kind of thing and it works on small examples. For now, I've something like :
$(document).ready(function() {
$("#selectB").html("<option value='' slected='selected'>Choose SelectA first</option>");
$("#selectA").change(function() {
var val = $(this).val();
var options = //... string generated with all <option></options> depending on $val
$("#selectB").html(options)
});
});
Here comes the mess, as selectB is a list of IPv4 that can contain a full /16. So that's 60k+ elements to handle (ouch ^^ ). And that's why I don't want to have every option in the select but instead "pre-select" with selectA and then "sub-select" with selectB.
I want to have all possible IPs initially in the HTML form because of the following reason : Even if JS is not enabled, the user must be able to choose one IP (the server checks that the choice from selectA and selectB corresponds). And only if JS is enabled I remove everything from selectB and add only the values I want when selectA is changed. So you might say that anyway a user with no JS can't event choose an option without loading 1GB+ RAM of options and wait 5-10 min for every option to be loaded, but I also want the page to works if there is only a few options to display like 1k.
I've to admit I was amazed my browser (FF) handles the creation of the page quite quickly. But when JS delete all the options, everything freezes on :
$("#selectB").html("<option value='' slected='selected'>Choose SelectA first</option>");
What I've managed to debug is that what takes time is when the browser needs to unload/delete every options. Actually creating them is not that slow.
So I would like to know if there is a faster solution than what I'm doing right now. How can I speed up the deletion of all <option> in selectB ?
Any suggestion is welcome from a simple change in JS to change the whole structure of HTML to not use <select> but something else (I don't know).
I'm currently in trouble with a select/select2 and jQuery $.clone issue.
In a html form with html select boxes replaced with select2 but the select2 jQuery plugin is not really relevant for this issue.
I experience problems when I use jQuery $.clone(true, true) to get a copy of a form to work on it.
When I try the following:
window.clone = $('#formSelector').clone(true,true);
The selected values are cloned and get lost. See http://jsfiddle.net/straeger/ct31f34c/9/
Even If I try to remove select2 with the call the cloned select boxes do not hold the selected values.
$('select').select2('destroy');
window.clone = $('#formSelector').clone(true,true);
see: http://jsfiddle.net/straeger/dokenyss/1/
A small hack with a big drawback (if no ID is present) is to copy the selected values to the clone:
$clone.find('select')
.each(function(index, value){
var $el = $(value);
$el.val($element.find('#'+$el.attr('id')).val());
});
see: http://jsfiddle.net/straeger/ct31f34c/10/
My question is what would be the correct way to handle such a problem ?
Does anyone know a way to select the counterpart of the original element from the original jQuery element if I have no ID?
Or a way to persist the currently selected option ? via the attribute e.g.
<option value="c" selected>C Value</selected>
There are several questions very similar to this one yet I have been unable to come up with a solution.
I have a select list using angularJS. I need to use the title attribute so I have an ng-repeat to create the options, there is always a blank option even if I use ng-selected to always select the first option.
Even if I make a selection and the blank option goes away, if I then filter out that selected value the blank will reappear.
I have included a select list using ng-option (which does not include my needed tittle attribute) and a default value to show that the blank will appear after filter.
The behavior I desire would be to never have a blank option (always selecting first option would be fine) and to possibly have a directive per option for special handling of click events.
Thanks in Advance!
JS Fiddle: http://jsfiddle.net/32DFM/3/
<select size="3" ng-model="person.current">
<option ng-repeat="p in people | filter:person.SearchTerm"
ng-selected="$first"
value="{{p}}"
title="{{p.name}}">
{{p.name}}
</option>
</select>
I forked your fiddle (if I may be so blunt): http://jsfiddle.net/XsFe8/2/
This fixes it somewhat. Although I haven't gotten it to work properly together with the filter.
Anyway, what I do here, is to use the person.id as the value on each option.
<select ng-model="person.current">
<option ng-repeat="p in people | filter:person.SearchTerm" ng-selected="$first" value="{{p.id}}" title="{{p.name}}">
{{p.name}}
</option>
</select>
And set the initial calue on the person.current model:
$scope.person.current = $scope.people[1].id;
But it's still not 100% though. I'm a bit stumped to why the blank spaces appear when you filter the select....
An alternative that might or might not work, would be to use something like ng-repeat="p in filterPeople() and filter your array in a filterPeople function. But I'm not sure if this will change anything.
UPDATE: I tested out my suggestion above, here: http://jsfiddle.net/XsFe8/2/
If you set the selected object to be the first object in the filtered array, it works. I do this each time a new filtered array is created:
$scope.filterPeople = function () {
var array = filterFilter($scope.people, $scope.person.SearchTerm);
$scope.person.current = array[0].id;
return array;
};
It looks like things get hairy when another object than what is visible in the select is actually selected. This is kind of understandable :)
Your actual problem is the value in ngModel is referencing a value which doesn't exist in the select anymore.
A solution is to whenever you alter the select options, you also check the person.current to ensure that it points to a valid entry.
This also implies that you might want to move your filter into the controller, and set the options in the scope (you can use the $filter service in your code to get same behaviour there, https://docs.angularjs.org/api/ng/filter/filter). This way you can have a function in your controller checking if person.current is valid, and if not, set it to desired options (e.g. the first one).
the hairyness cited above is due to an empty array when all items are filtered out and is fixed by:
if(array.length>0)
$scope.person.current = array[0].id;
http://jsfiddle.net/b0z6vpr8/
Hope this helps