I'm trying to use select2 to have a multi-select dropdown list of states, but something is wrong.
Normally, when you type an option out, it's highlighted so that you can hit enter and select it. It underlines the option, but does not highlight it, so if I type "alabama" but hit enter, it will select "arkansas".
I'm using the latest version (3.5.1)
HTML
<label class="control-label" for="states">States:</label>
<input id="states" name="states" />
<input class="btn btn-primary" type="submit" value="Submit Search" />
JavaScript:
$("#states").select2({
width: 'resolve',
maximumSelectionSize: 5,
ajax: {
dataType:"json",
url:"getStates.cfm",
results: function(data) {
return {results:data};
}
},
multiple:true
});
Am I missing some sort of parameter? I could have sworn this was working fine the last time I used it. No console errors, and it click selects perfectly.
Note that the github page works just like I want (when you type, it selects the first option that matches)
In Select2 3.x, the highlighted result in the dropdown will always be the first result during searches. This will be changing in Select2 4.x, so the selected option will be selected if it is present.
You are looking for the results to be sorted differently. By default, Select2 orders options by the order that they have within the DOM, not by how relevant they are. The documentation provides an example of how to customize the sorting of results using the sortResults option.
Keep in mind that it is more efficient to sort the results on the server side when using AJAX, which is why Select2 does not do any further sorting. This would explain why "Arkansas" is being returned when searching for "Alabama".
I had the same problem. And solution was found when i found that every time i type into search box, each time it calls query function. That's it. So all i required to do fill results only if it matches at least one character in anyone of the text of the available options. The following way :
query : function(opts){
var res = [];
var fulloptions = ArrayFoundUponYourAjaxOrAnyStaticOptions;
var stripDiacritics = Select2.util.stripDiacritics;
for(var z=0,len=fulloptions.length;z<len;z++){
if(stripDiacritics(fulloptions[z].text.toUpperCase()).
indexOf(stripDiacritics(opts.term.toUpperCase())) >= 0){
res.push(fulloptions[z]);
}
}
opts.callback({ results : res }); // res is your filtered/matching rows out of which first one will get auto hightlighted
}
Related
I am kinda drawing a blank on this one facet, and I can't seem to quite figure it out.
So I have a simple HTML select => option element which is populated from the back-end (not really relevant tho)
My question is this:
Let's say I have a pre-made object such as this:
{
keyName1: 450,
keyName2: 800,
keyName3: 300
}
What I want to do is to check if the key name matches a name of an option value in my multi-select dropdown (the values come from an array, using 'ng-repeat' on the option), and if the option value matches the key, add the number value to some sort of increment variable, so I can display the total number of 'keyNames' found.
For example - if a user selects 'keyName1' the incrementer value will total 450. If a user selects 'keyName1' and 'keyName2' the incrementer value will total 1,250.
I am lost on how to accomplish this - right now it is reading only the very first item in the dropdown.
Here is the code doing that:
_.forEach($scope.widget.instance.settings.serviceContractTypes, function (type) {
// if item in array matches what is selected in multi-select option
if(type === $('#contractType:selected').text().trim()) {
// do stuff
}
});
Hope this all made sense, and thanks very much for any direction you might offer...
(does not have to utilize lodash, I'm just used to using it)
jQuery's :selected selector only works for HTML options:
"The :selected selector works for elements. It does not work for checkboxes or radio inputs; use :checked for them."
(https://api.jquery.com/selected-selector/)
You say "I have a simple HTML select => option element which is populated from the back-end (not really relevant tho)"
This could be relevant. By default, an HTML option tag does not support multiple selections; it has to explicitly be created as a select multiple in order to support that. Can you share the HTML code for the option to make it clear whether that's a problem or this is a red herring?
Also, can you echo $scope.widget.instance.settings.serviceContractTypes and share to make sure it's actually matching what's available in the text of the options?
ADDENDUM - Wait, I think I figured it out!
The $('#contractType:selected') selects all the selected options in #contractType and concatenates them. Then $('#contractType:selected').text().trim() trims this down to the first word, which is just the first selected option. You should do something like $('#contractType:selected').text().split(" ") and then check if each type is in the resulting list.
I have something in my mind, but I have no idea how to get it done, so I hope I can get some advise here.
I'm working on an activity registration app (using Laravel), where every activity will be registered. Very important is that we need to record who was invited and who actually attended. I already have this part running. My issue is more on the practical side.
I use jQuery Select2 for the multiple select fields for invitees and attendees. Imagine now that there's a group of users that need to be invited or attend virtually all activities, while the invitation or attendance of others depends on the type of activity. Using Select2, I can only select users one at a time and that sucks if you need to do that for, say, 50 users for virtually every activity.
What is the best way to have a "group" that can be selected, which selection fills in all the names of those in the group in the select field? Or is there a better way to get this done?
I'm seeing something in my head, where there are checkboxes next to the select field, representing the groups. When you tick a checkbox of a group, the select field is populated with all users who are part of that group.
I have no idea ow this can be done. I looked around and every search brings up select boxes populating select boxes. None handle checkboxes.
Any advise on how to get this done?
My PHP/MySql is intermediate, Javascript/Ajax is very basic.
One strategy would be to build a control (checkbox element) that will set or toggle the selection of your group of users whenever it's clicked. Say we have the following markup:
<select class="my-big-group-select" multiple="multiple">
<!-- assorted options here -->
</select>
<label>
<input type="checkbox" class="toggle-default-group" />
Use my default big group of users
</label>
The Select2 API allows you programmatic control over the component it generates.
You can read more about it here: https://select2.github.io/examples.html#programmatic
Here's one way to leverage this knowledge using jQuery with Select2:
<script>
var groupSelect = $('.my-big-group-select').select2();
var groupToggle = $('.toggle-default-group');
var myBigGroup = ["Aaron", "Beth", "Cindy"]; // assorted option values
groupToggle.on("click", function() {
if ($(this).is(':checked')) {
groupSelect.val(myBigGroup).trigger('change');
} else {
var currentlySelected = groupSelect.val();
if (currentlySelected) {
var filteredSelections = currentlySelected.filter(function(key) {
return myBigGroup.indexOf(key) < 0;
});
groupSelect.val(filteredSelections).trigger('change');
}
}
});
</script>
Here's a CodePen that shows it all in action: http://codepen.io/anon/pen/qNQKOd
Of course you can build on this to make additional enhancements (the ability to select multiple groups, for example).
As an alternative, you may consider other code libraries like Bootstrap Multiselect: https://davidstutz.github.io/bootstrap-multiselect/
Hope this points you in the right direction!
I'm trying to use an external checkbox to filter the table based on the contents of a column. The only related questions/solutions I've found are dealing with checkboxes inside the table used for sorting purposes.
Desired Functionality: For the sake of simplicity, let's say column 4 contains either a 0 or 1. When this external checkbox is checked, I'd like it to filter the results (where column 4 contains the value 1).
Working Alternative: When using an external select (dropdown), I can achieve the desired functionality. The select element (<select id="test_select" name="test_select" class="search" data-column="4">) has an option (<option value="1">1</option>) and then, inside the "widgetOptions" configuration, have filter_external: '.search'.
But a having a select with one option doesn't make sense as far as usability is concerned.
Any suggestions?
Use the "search" method to perform any queries on the table data.
Here is an example
HTML
<label><input id="findzeroes" type="checkbox"> Find Zeroes</label>
Script
$(function() {
$('#findzeroes').on('change', function(){
var query = [];
if (this.checked) {
// target 4th column (zero-based index)
query[3] = '0';
}
$('table').trigger('search', [ query ]);
});
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'filter']
});
});
Using a <select> instead of a checkbox will also work.
I wanted to turn a multiple column filter on and off with a checkbox, but found #Mottie's answer didn't do the trick because it doesn't allow for filter_external and data-column="7,8" type filtering.
So I just created a hidden field which has the data-column="7,8" attribute and use jQuery to change its value when the checkbox is changed, and also to trigger a keyup event.
$('#checkboxId').on('change', function(){
var filterTerm = $(this).prop('checked') ? '?' : ''
$('#hiddenFieldId').val(filterTerm).keyup()
})
I use a filter value of '?' which is a non space character, that could be anything you'd type into a normal filter field.
I am using the select2 plugin to convert a multiple select html element to a more presentable format. Also I don't think my question is very much dependent on the plugin.
What the plugin does internally is -
this.select.val(val);
where this.select points to the hidden multiple select element.
On feeding the function above a val of say - 2,4,0 ,
the value stored as confirmed when I do an alert(this.select.val()) is 0,2,4 , i.e. with automatic unwanted sorting according to the order of the options in the select element.. :/
DEMO - http://jsfiddle.net/rohanxx/DYpU8/ (thanks to Mark)
Is there a way to preserve the sort order after feeding in the value to my select element?
Thanks.
This is a very good question. I think this is more to do with the multiselect html element, rather than select2.
If you have a normal multiselect, there is no "order" sort of speak. You just have a list in the original order, with either each item selected or not.
I'm almost 100% sure there is a better way of doing this than the below, but for a workaround it should do just fine.
End result:
JavaScript code
// 'data' brings the unordered list, while 'val' does not
var data = $('#e1').select2('data');
// Push each item into an array
var finalResult = [];
for( item in $('#e1').select2('data') ) {
finalResult.push(data[item].id);
};
// Display the result with a comma
alert( finalResult.join(',') );
JSFiddle:
http://jsfiddle.net/DYpU8/4/
A little late for an answer but I actually found a way of doing this.
Keep in mine that this method will hide the options that are already selected, because for my use case it looked better, plus it needs to be that way in order the choices to be in the order the user made them.
$('.my-multi-select').select2('Your Options').on("select2:select", function (e) {
$('[data-option-id="' + e.params.data.id + '"]').insertBefore(_this.find('option:not(:selected):eq(0)'));
}).on("select2:open", function () {
_this.append(_this.find('option:not(:selected)').sort(function (a, b) {
return +a.getAttribute('data-sort-order') - +b.getAttribute('data-sort-order');
}));
});
And for the styles
.select2-results__option[aria-selected=true]{
display:none !important;
}
You will want to make sure you know how the jQuery .sort() function works for you to be able to modify this for your own needs.
Basically what this is doing is when you select an option, it gets hidden and then placed at the bottom of the other selected options, which are before the unselected options. And when you open the drop down, it sorts all of the unselected options by their pre-determined sort order.
I need to create a dynamic select field in Rails 3.2, where the options available in the second fields (states) depends on the value of the first (country). I've referred to the revised version of this Railscast, and am using the following code:
jQuery ->
$('#person_state_id').parent().hide()
states = $('#person_state_id').html()
$('#person_country_id').change ->
country = $('#person_country_id :selected').text()
escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(states).filter("optgroup[label='#{escaped_country}']").html()
if options
$('#person_state_id').html(options)
$('#person_state_id').parent().show()
else
$('#person_state_id').empty()
$('#person_state_id').parent().hide()
I need to make two changes to this code, which I think should be pretty straightforward for someone with stronger javascript skills than I have.
In the filtered list, I need to include a blank option. Currently selecting a country results in the first state state in the filetred list being selected. I need to leave the prompt "please select". How can I do this?
EDIT
SMathew's suggestions helped here. I'm using $('#person_state_id').html(options).prepend('<option></option>') which, together with a prompt attribute on the html tag, acheives the required result.
If no country is selected (ie the else statement) person_state_id should contain a complete, unfiltered list of all states. I've tried:
else
$('#person_state_id').html(states)
But this is not behaving as expected. I'm having these issues.
If I select a country that has associated state records, #person_state_id options are correctly filtered (and with smathews suggestion, a prompt is included).
If I select a country with no associated state records, #person_state_id contains all states, a blank option in the markup, but the first state option is selected by default. (It should be empty, with a blank option selected by default and a prompt displayed).
If I clear the selection in #person_country_id, #person_state_id contains an unfiltered list of all states (correct), and an empty option in the markup (correct) but the first state record is selected by default (should be a prompt).
How can I resolve these issues?
Thanks
Try
...
if (options) {
$('#person_state_id').html(options).prepend('<option>Please select</option>').parent().show()
} else {
$('#person_state_id').html(states).prepend('<option>Please select a state</option>').parent().show()
}
To deal with my second problem, I added the following coffeescript
jQuery ->
resetCountry = ->
$('#person_state_id').select2 "val", "0"
$('#person_country_id').bind("change", resetCountry);
This, coupled with smathew's answer, seems to be working
(I'm using select2 to format my select fields. You'll need a different approach to set the value if not using select2)