I have the following binding in js fiddle.
<div class="container body-content">
<div>Name : <span data-bind="text: Name"></span>
</div>The select control should be below
<select multiple data-bind="selectPicker: teamID, optionsText: 'text', optionsValue : 'id', selectPickerOptions: { optionsArray: teamItems, disabledOption: IsDisabled }"></select>
<div>Selected Value(s)
<div data-bind="text: teamID"></div>
</div>
</div>
I am thinking of doing this disabledOption: IsDisabled and then adding
this.teamItems = ko.observableArray([{
text: 'Chris',
id: 1,
IsDisabled: false
}, {
text: 'Peter',
id: 2,
IsDisabled: false
}, {
text: 'John',
id: 3,
IsDisabled: false
}]);
I would like to know how to disable an option in the select.
In the knockout docs, there's an example that shows how you can disable an item using an optionsAfterRender method.
About the method you can pass to it:
It has to be in your viewmodel, not in your items
It takes in the option HTML node, and the item it's bound to
So step one is to find a place to store which items are disabled. The easiest option would be to store it inside your teamItems' objects:
{
text: 'Chris',
id: 1,
disable: ko.observable(true)
}
Now, we need to add a method that takes in an item and creates a binding. We can take this straight from the example:
this.setOptionDisable = function(option, item) {
ko.applyBindingsToNode(option, {
disable: item.disable
}, item);
}
Finally, we need to tell knockout to call this method:
<select multiple data-bind="optionsAfterRender: setOptionDisable, ...
Note that after changing a disable property in one of your items, you'll have to call teamItems.valueHasMutated manually.
Here's an updated fiddle:
http://jsfiddle.net/nq56p9fz/
Related
I have a list of fields
fields: [
{
id:0,
label: 'dropdown 1',
value: 0,
options: [{ id: 0, value: 0, label: 'Option 1' }]
},
{
id: 1,
label: 'dropdown 2',
value: 0,
options: [
{ id: 0, value: 0, label: 'Hide dropdown 1' },
{ id: 1, value: 1, label: 'Show dropdown 1' }
]
}
]
that are filtered before being shown like so:
<div v-for="field in fields.filter(ffield => showField(ffield))" :key="field.id">
<b-form-select v-model="field.value" #change="changed(field)">
<option v-for="option in field.options" :key="option.id" :value="option.value">
{{ option.label }}
</option>
</b-form-select>
</div>
I can hide 'dropdown 1' based on the selected option in 'dropdown 2'. This is managed by the 'showField' function:
function showField(field) {
return field.value !== 'dropdown 1' || fields[1].value === 1
}
Lets say dropdown 1 is hidden and I select the second option Show dropdown 1. Vue's reactivity runs the showField function for all items in the list before running the changed event on the affected field. So now dropdown 1 is visible and then the eventhandler is called.
But what's really weird is that the parameter field in the changed function corresponds to the value of fields[0] even though I selected an option in 'dropdown 2' or fields[1].
What is going on?
I understand that this doesn't happen when dropdown 1 is after dropdown 2 in the list.
I tried modifying node_modules/bootstrap-vue/esm/components/form-select/form-select.js rendering function but this must be some internal thing that's causing it and I'm not familiar enough to keep digging.
Maybe I disregarded some pattern for this sort of thing?
The filter in the v-for came in because we used v-if="showField(field)" together with the v-for and that was incorrect.
How can I avoid this?
The issue is that when I bind options to the dropdown, "ui dropdown" makes it disappear and nothing is in the cell in my browser(it dosent use the css properly in jsfiddle). If i remove that css then i see the out of the box dropdown.
creating a table with a viewmodel collection and want a dropdown of values for the individual risks
//part of the viewmodel
var ViewModel = {
Collection: ko.observableArray(),
availableRisks: ['L', 'H'],
using
$('.ui.dropdown').dropdown();
doesn't help.
Sample code that dosent work with the dropdown:
http://jsfiddle.net/7vh2t33m/2/
There are bindings for jQuery UI and knockout, use them. http://gvas.github.io/knockout-jqueryui/
Rule of thumb, in a knockout application nothing may touch the DOM except knockout, or without informing knockout. Therefore, mixing knockout with jQuery UI without anything that bridges the gap between them will not work.
Taken from the example in knockout-jqueryUI selectmenu binding documentation:
var ViewModel = function () {
this.items = ko.observableArray([
{ id: '1', text: 'First' },
{ id: '2', text: 'Second' },
{ id: '3', text: 'Third' },
{ id: '4', text: 'Fourth' }
]);
this.value = ko.observable('1');
};
ko.applyBindings(new ViewModel());
and in the view
<!-- ko foreach: items -->
<input type="radio" name="radios" data-bind="attr: { value: id }, checked: $parent.value" />
<!-- /ko -->
<br/>
<select data-bind="value: value, selectmenu: { width: 300 }, options: items, optionsValue: 'id', optionsText: 'text'">
</select>
<br />
I am new to knockoutJs, as i am trying to display the selected values by binding. But am facing issues with duplicate values.
For example:
As per the below example snippet, If i select one from the dropdown, the binding result is displaying name "one" as selected, this is correct.
{name:"one",price:32.50}, {name:"two",price:32.50},
After that if I select other option from drop down i.e name two, the binding result is not displaying name two as selected, instead it is keep displaying the name="one" only, which is in-correct.
Observation: I see that this is happening due to the same price set for all the option values, if I update them with different prices the options values are binding properly.
Here my confusion is that why the binding logic is not applying properly when the price value is same but the name is different.
I am trying to achieve this by below code.
Html
<select data-bind="options: beforeEventPedersensDropoffCustomerLocation,optionsCaption: 'Please Choose Closest Location',
optionsText: 'name', optionsValue: 'price', value: selectedPricebepdcl" id="before_event_pedersens_dropoff_customer_location_time" ></select>
Js
self.beforeEventPedersensDropoffCustomerLocation = [
{name:"one",price:32.50},
{name:"two",price:32.50},
{name:"three",price:32.50},
{name:"four",price:32.50},
{name:"five",price:32.50},
{name:"six",price:32.50},
{name:"seven",price:0}
];
self.selectedPricebepdcl = ko.observable("");
console.log()
self.beforeEventVal = ko.computed(function() {
if(self.selectedPricebepdcl() !== "")
return ko.utils.arrayFirst(self.beforeEventPedersensDropoffCustomerLocation, function(time) {
return self.selectedPricebepdcl() === time.price;
});
return null;
}, this);
Result
<p data-bind="with: beforeEventVal">
<span data-bind="text: name"></span>
</p>
<p data-bind="with: beforeEventVal">
<span data-bind="text: price"></span>
</p>
Can anyone help me on this.
The problem is that you have set optionsValue: 'price', so the only information you have about which item is selected is the price. Then you try to use that to find the selected item from among the available items, but you cannot do that because it is not a unique identifier.
Instead, if you don't specify optionsValue, Knockout will use the entire item as the value of the select. That also lets you do away with looking up the selected value, because you have the selected value.
function VM() {
self = this;
self.beforeEventPedersensDropoffCustomerLocation = [{
name: "one",
price: 32.50
},
{
name: "two",
price: 32.50
},
{
name: "three",
price: 32.50
},
{
name: "four",
price: 32.50
},
{
name: "five",
price: 32.50
},
{
name: "six",
price: 32.50
},
{
name: "seven",
price: 0
}
];
self.selectedBepdcl = ko.observable("");
self.selectedName = ko.pureComputed(() => {
const sb = self.selectedBepdcl();
return sb && sb.name ? sb.name : '';
});
}
ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: beforeEventPedersensDropoffCustomerLocation,
optionsCaption: 'Please Choose Closest Location',
optionsText: 'name',
value: selectedBepdcl" id="before_event_pedersens_dropoff_customer_location_time">
</select>
<p data-bind="with: selectedBepdcl">
<span data-bind="text: name"></span>
</p>
<p data-bind="with: selectedBepdcl">
<span data-bind="text: price"></span>
</p>
Pretend this is hidden:
<input data-bind="value: selectedName">
I'm having trouble understanding why my Angular <select> doesn't add the default value to the category I want.
I have an object that is returned from our database in Parse; the object is like this ( this is the "selected" option ):
$scope.item.category = { id: 'uosDHIF', className: 'Category', name: 'Projects' }
And I have a list of categories also:
$scope.categories = [{ id: 'uosDHIF', className: 'Category', name: 'Games' }, { id: 'uosDHIF', className: 'Category', name: 'Random' }, { id: 'uosDHIF', className: 'Category', name: 'Projects' }]
In my HTML what I have it's a select like this:
<select name="category" class="form-control mb-10" ng-model="item.category" ng-options="category.name for category in categories"></select>
I can select a new category and it's assigned to the item, and then I can save the item with item.save() but what I have trouble doing is that the selected (ng-model) doesn't seem to work, when I enter the page the first time I always get the default blank option even if I have the category when I check in the console.
Also, I was able to make it work with a simple object that I have created myself, but this object is returned from our database in Parse, so I'm not sure if this is the problem or I'm just missing something in there.
Thank you for your help.
Note: I have read other StackOverflow problems similar to mine but they doesn't help with mine.
In fact, on ng-options, you have to specify the value for the model (category as category.name => you choose category for ng-model but display it by his name).
The matching occurs by reference so you need the same object (category : $scope.categories[0]).
You can try:
JS
$scope.categories = [
{ id: 'uosDHIF', className: 'Category', name: 'Games' },
{ id: 'uosDHIF', className: 'Category', name: 'Random' },
{ id: 'uosDHIF', className: 'Category', name: 'Projects' }
];
$scope.item = {
category : $scope.categories[0]
};
HTML
<select name="category" class="form-control mb-10" ng-model="item.category" ng-options="category as category.name for category in categories"></select>
Please change the html as below.. Hope this is helpful.
ng-model="item.category.id" ng-options="category.id as category.name for category in categories">
http://jsfiddle.net/WcJbu/
When I select a person, I want the favoriteThing selector to display their current selection.
<div ng-controller='MyController'>
<select ng-model='data.selectedPerson' ng-options='person.name for person in data.people'></select>
<span ...> likes </span>
<select ... ng-model='data.favoriteThing' ng-options='thing.name for thing in data.things'></select>
</div>
$scope.data.people = [{
name: 'Tom',
id: 1,
favorite_thing_id: 1
}, {
name: 'Jill',
id: 2,
favorite_thing_id: 3
}];
$scope.data.things = [{
name: 'Snails',
id: 1
}, {
name: 'Puppies',
id: 2
}, {
name: 'Flowers',
id: 3
}];
Do I need to set up a service and add watches, or is there a [good] way to use the favorite_thing_id directly in the select?
Change the second select to this:
<select ng-show='data.selectedPerson' ng-model='data.selectedPerson.favorite_thing_id'
ng-options='thing.id as thing.name for thing in data.things'></select>
Adding the thing.id as to the ng-options will allow you to select the data.things entries based on their id's instead of their references. Changing the ng-model to data.selectedPerson.favorite_thing_id will make angular automatically change to the correct option based on selectedPerson.favorite_thing_id.
jsfiddle: http://jsfiddle.net/bmleite/4Qf63/
http://jsfiddle.net/4Qf63/2/ does what I want - but it's pretty unsatisfying.
$scope.$watch(function() {
return $scope.data.selectedPerson;
}, function(newValue) {
if (newValue) {
$scope.data.thing = $filter('filter')($scope.data.things, {id: newValue.favorite_thing_id})[0];
}
})
I'd like to see all of that be possible from within the select statement.
Maybe I'll try to write a directive.
association = {key: matchValue}
So that I can do
<select ... ng-model='data.thing' ng-options='t.name for t in data.things' association='{id: "data.selectedPerson.favorite_thing_id"}'></select>