In a .net MVC app, trying to learn semantic UI. (2.2.13) I've been beating my head against the wall on this one.
I have a remote populated dropdown, that I'm trying to create a default value for at initial page load.
The API is working, returning expected data.
My problem is that when a user 'tabs' into the element, the forceSelection default of the apiSettings forces the selection of the first item in the dropdown, which in this case is not what my default value is. (In this case, say that CAT is the first option in the list)
The desired behavior is keeping 'DOG' as the selected value when tabbed through, and i would like to keep the functionality of 'forceSelection' to prevent a user from leaving the dropdown with something typed that isn't included in the dropdown options.
I'm THINKING that i need a way of passing the current (default) value, and making that the selected value when the dropdown is initialized?
Here's the .js, in a doc ready.
$('.quom').dropdown({
apiSettings: {
url: 'ActualUrlRemoved',
cache: false
},
fields: {
name: 'Animal_Name',
value: 'Animal_Name'
},
onShow: function (val) {
///set active based on val here??
// $(this).val('DOG');
}
});
And the HTML setting the default 'DOG' (and using the "" value as the label) :
<select id="animalTest" name="ANIMAL" class="ui fluid search selection dropdown quom">
<option value="">Animal*</option>
<option value="DOG" selected>DOG</option>
</select>
Figured it out. This works for me.
$('.quom').dropdown({
apiSettings: {
url: 'URLHERE',
cache: false
},
fields: {
name: 'Animal_Name',
value: 'Animal_Name'
},
onShow: function () {
current = $(this).val();
$(this).dropdown('set selected', current);
}
});
Related
I am loading the data in select2 dropdown on page load. On the UI I can see the dropdown being populated but when I clear the dropdown value and reload the value again, it is not getting populated, though I can see the data is available in the dropdown.
I have tried to use val() and then trigger the change. It did not change the value. I have verified that the value which is passed to the dropdown has the value in the dropdown list.
This is how I am trying to assign the value - $('#s1').val(v.Name);
This is how I am clearing the dropdown value - $("#s1").val("");
$scope.vendorlist = d.data;
d.data.forEach(function (v) {
vendors.push({ id: v.Id, text: v.Name });
});
$('#s1').select2({
placeholder: 'Select a field',
data: vendors,
}).on('select2:select', function (e) {
});
The dropdown should show the passed value in the dropdownbox.
I am disabling controls when the user is not in edit mode.
this.theForm = this.builder.group({
name: [{ value: this.model.name, disabled: !this.isEditMode}, Validators.required],
})
When they change to edit mode I want the control to be enabled. However, it seems that once this is set it will not change then the component value changes.
This was working when I had this in the markup:
<input [disabled]="!isEditMode" type="text" formControlName="name" />
This was causing a runtime warning suggesting that I handle it with the formControl.
This is the warning:
It looks like you're using the disabled attribute with a reactive form
directive. If you set disabled to true when you set up this control in
your component class, the disabled attribute will actually be set in
the DOM for you. We recommend using this approach to avoid 'changed
after checked' errors.
Is there a way to bind this value when I setup the control?
Do I need to loop though the controls and toggle this whenever it changes?
You can subscribe to the control change and update it there, something like this (off the top of my head):
ngOnInit() {
for (let nut of this.userSettings.nutrientData) {
this.foodSettingsForm.controls[nut.abbr].valueChanges
.subscribe(v => {
this.completeValueChange(nut.abbr, v, (mode=="edit" ? false : true));
});
}
}
completeValueChange(field: string, value: boolean, disable: boolean) {
this.myForm.controls[myField]
.setValue(({value: vale, disabled: disable}, { onlySelf: true });
}
I am giving the 3.5 -> 4.0 upgrade another go and 'almost' have this use case working like it was. What I am stuck on now is how to ALWAYS add a certain option to the ajax results list.
Here is what I have right now :
html:
<select id="vedit-filter" name="settings[filter]" class="form-control select2">
<option value="default" selected="">default</option>
</select>
js:
$("#vedit-filter").select2({
placeholder: "Select or enter application...",
allowClear: true,
multiple: false,
tags: true,
ajax: {
dataType: 'json',
delay: 1000,
type: 'post',
url: '/process/get_application_list.php',
data: function (term, page) {
return {
term: term, // search term
page_limit: 25, // page size
page: page // page number
};
},
results: function (data, page) {
var more = (page * 25) < data.total; // whether or not there are more results available
return {
results: data.results,
more: more
};
}
}
});
That will load 'default' as the initial selected option. If the user changes this then it is gone. I want a way for them to revert back to that initial selection if need be. Is the only way to include it in my returned results from ajax as an option? Or is there a way to do this on the js side?
UPDATE:
The default selection will always be dynamic, but in this example we are using a value/name of 'default'.
<select id="vedit-filter" name="settings[filter]" class="form-control select2">
<option value="default" selected="">default</option>
</select>
then in the js:
var default_filter = $("#vedit-filter").val(); //get the default loaded from the html
placeholder: {
id: default_filter, // or whatever the placeholder value is
text: default_filter // the text to display as the placeholder
},
I recently explained this on GitHub but didn't realize how much of a breaking change it was.
I want a way for them to revert back to that initial selection if need be.
Select2 provides the placeholder option, which can allow you to specify a placeholder like "Select an item" to the user if a selection is not already made. In order to support a <select>, which will select the first option by default (that's done by the browser), Select2 requires that a "placeholder" <option> exists. This also doubles as the option which Select2 uses to determine if the placeholder needs to be displayed.
In addition to the placeholder option, Select2 also allows the user to remove their selected option, which will revert the selection back to the placeholder option. This can be enabled through the allowClear option.
Is the only way to include it in my returned results from ajax as an option? Or is there a way to do this on the js side?
In your example, you are using a placeholder option with a value set on it. Because Select2 expects that the value is blank/empty by default, you need to tell Select2 what to look for when detecting the placeholder. This can be done by passing a data object into placeholder which Select2 will use when checking.
placeholder: {
id: 'default', // or whatever the placeholder value is
text: 'Select or enter application...' // the text to display as the placeholder
}
This will tell Select2 to display the placeholder when the value is set to default, which in your example appears to be the placeholder/default option.
What I am stuck on now is how to ALWAYS add a certain option to the ajax results list.
While I think we might have solved the XY problem here, I did want to note that adding a new option to the AJAX results list is as simple as overriding processResults. This is because processResults passes the list of data objects directly to Select2, which gives you a safe place to inject new options into the list.
You just need to .push the extra data object into the results and then pass them back to Select2.
I'm able to get this working except for two things that I just can't figure out:
Problem 1: I need to get both of the following but right now can only achieve one OR the other:
Select options need to have value and text
The selectedOption captured in the model needs to return the object of the selected option and not just the value of the option
I can affect which one of these works by including or excluding the following from my select markup:
...data-bind="optionsValue = 'Id'"...
How can I achieve both?
Problem 2: I need to set the selected option in the dropdown to an object I retrieve from a cookie containing the user's preferred value. My below implementation does not succeed in setting the selected value at all. What am I missing?
$(document).ready(function(){
var userOption = $.cookie("userPref") == null ? undefined : JSON.parse($.cookie("userPref"));
var model = function(){
this.options = ko.observableArray();
this.childOptions = ko.observableArray();
this.selectedOption = ko.observable(userOption); //this does nothing to set the value
this.selectedOption(userOption); //this also does nothing
this.options.subscribe(function(){
//this.selectedOption() returns an object if optionsValue is excluded from select databinding and returns option value if included
$.cookie("userPref", JSON.stringify(this.selectedOption());
this.childOptions(undefined);
this.childOptions(this.selectedOption() ? this.selectedOption().children : []);
}.bind(this));
};
var viewModel = new model();
ko.applyBindings(viewModel);
$.ajax({
type: "GET",
url: "myurl",
success: function(data){
viewModel.options(data);
}
});
});
<select data-bind="options: options, optionsText: 'text', optionsValue: 'Id', value: selectedOption, optionsCaption: 'Select Option'"></select>
You can't use the entire object as the value because an option value must be a simple type: string, int, etc. I suppose you could JSON encode the object (so it's a string) and set the value to that, but then you'd have to reciprocate on the backend and decode the posted string value back into an object and somehow work with that. However, said object would be disconnected from EF, so you'd have to fetch the object new from the database anyways in order to do anything meaningful with it. And, your second problem is the same as your first, you can't use a full object.
The way this is usually done is with ids. You make the option value the object's id. Then, you can set the selected option based on the object's id from the cookie. When you get to the backend, if you need to work with the object, you fetch it by the posted id. Anything else is not really a tenable situation.
Select2 loads all items from my list successful, the issue I found when try to select a specific value when page loads. Example:
:: put select2 in a specific html element, no value is selected even all items are loaded.
$('#my_id').select2();
:: When the page is loaded I'm trying to show a specific item selected, but doesn't work as expected, because even selected, the select2 doesn't show it.
$('#my_id').val('3'); //select the right option, but doesn't render it on page loads.
How to make a selected option to pop up when pages loads?
Thanks in advance.
#UPDATED
:: How I load all select2 items (sorry, its jade, not pure HTML):
label(for='category') Category
span.required *
select(id='category', style='width:230px', name='category')
option(value='') - Select -
each cat in categories
option(value='#{cat.id}') #{cat.description}
P.S.: All items from my list are loaded.
:: How I initialize the select2:
Just put the following line code on my javascript and it does successful:
$('#category').select2();
:: How I'm trying to select a specific value:
First attempt:
$('#category').select2(
{
initSelection: function(element, callback) {
callback($('#field-category').val());
}
}
);
Second attempt:
$('#category').val($('#field-category').val());
P.S.: #field-category has a value its a hidden input field and works OK.
You need to use the initSelection option to set the initial value.
If you are using a pre-defined select element to create the select2, you can use the following method
$('select').select2().select2('val','3')
Demo: Fiddle
add a trigger change after setting val:
$('#my_id').val('3').trigger('change');
A very simple way to tackle this problem is :
//Step1: Here assuming id of your selectbox is my_id, so this will add selected attribute to 1st option
$('#my_id option').eq(0).prop('selected',true);
//Step2: Now reinitialize your select box
//This will work, if you haven't initialized selectbox
$('#my_id').select2();
or
//This will work, if you have initialized selectbox earlier, so destroy it first and initialise it
$('#my_id').select2('destroy').select2();
This may help:
$('#mySelect2').val('1'); // Select the option with a value of '1'
$('#mySelect2').trigger('change'); // Notify any JS components that the value changed
You can find more on details here:
Thanks
Per here initSelection is deprecated in Select2 4.0 and later.
Using Select2 4.0.0 this worked for me:
$('#my_id').select2({val:3});
HT: #Kokizzu
Here is how to make val in select2 just select the corresponding element.
For some reason, select2 doesn't provide the function to look up selections by id.
init:
$("#thing").select2({data:sources, initSelection: function(item, callback) {
// despite select2 having already read the whole sources list when you
// do .val(n) you have to explicitly tell it how to find that item again.
var to_be_selected = null;
$.each(sources, function(index, thing) {
if (thing.id == item.val()) {
to_be_selected = thing;
return;
}
})
callback(to_be_selected);
}})
normal code
// to load the thing with id==3 from the initial sources list.
$("#thing").select2({'val': 3})
For me I was sending selected in the data set still default option was not getting selected. I had to do something like below to make it work -
$(".select").select2({
data: data_names
});
data_names.forEach(function(name) {
if (name.selected) {
$(".select").select2('val', name.id);
}
});
I had a multiple select2 box with multiple selections.
Step 1 was to put my string of school_ids into an array of integers corresponding to the id of each school, and remove a leading zero. I had to do this in a separate script tag.
<script>
var school_ids = <%= raw JSON.parse(#search.school_ids).map{|x| x.to_i} - [0]%>
</script>
Step two was to create the select box, then set the values, then trigger like so:
<script>
$(document).ready(function() {
$('.select2-multiple').select2({
placeholder: "Hit Enter After Selection",
width: 'resolve'
});
$('.select2-multiple').val(school_ids);
$('.select2-multiple').trigger('change');
</script>
trigger just select2 to set the value
$('#my_id').val('3').trigger("change.select2");
and this will trigger select2 with dropdown
$('#my_id').val('3').trigger("change");
I meet with the same problem, this works for me:
Using Select2 > 4.0.0
$('#select_id').val('3').trigger('change');
var option=$(this);
if(option.val()==data.StudentCourses.CourseId)
{
option.setAttribute('Selected');
}
});
i have initilized select2 because i just want few options selected from them.
If you are using select2 v4.0.0 or above, you can check select2 documentation
// Initialize select2 for all select tags
$('select').select2();
// Initialize select2 for a specific id
$('#my-id').select2();
// Initialize select2 for a class
$('.my-class').select2();
// Update the displayed value after changing the selected option.
$('#my-id').trigger('change');
$('.classname').each(function() {
$(this).siblings().find('.select2selection__rendered').text($(this).text())
})
in my case I were dealing with a class then I used this way to set showing content at select2
<option selected value="your_value">your_text</option>
u need to put this at each select box's first option