I try to binding two computed select with Knockout:
- the first select(DropDownLinee) is filled when on page load
- the second select(DropDownCorse) is filled when the user select an item on the first select
This is the example:
<select id="DropDownLinee" data-bind="options: ArrayLinee, optionsText: 'NomeLinea', optionsValue: 'NomeLinea', value: selectedLinea " data-toggle="dropdown"></select>
<select id="DropDownCorse" data-bind="options: ArrayCorse, optionsText: 'CodiceCorsa', optionsValue: 'CodiceCorsa', value: selectedCorsa " data-toggle="dropdown"></select>
function LineeViewModel() {
var self = this;
self.selectedLinea = ko.observable();
self.selectedCorsa = ko.observable();
self.ArrayLinee = ko.observableArray([]);
self.ArrayCorse = ko.observableArray([]);
$.getJSON('/Home/GetLines', function (data) {
self.ArrayLinee(data);
});
self.ArrayCorse = ko.computed(function () {
$.getJSON('/Home/GetRides',
{
LineaSelezionata: self.selectedLinea(),
DirezioneSelezionata: $('input[name=radio4]:checked', '.areaselezione').val()
},
function (data) {
debugger;
self.ArrayCorse(data);
});
});
}
lineeVM = new LineeViewModel();
ko.applyBindings(lineeVM);
I have this error when i check to load the 'DropDownCorse':
Uncaught Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
Can anyone help me to solve this problem???
Thank in advance greetings Donato
You want to use subscribe, not a computed.
self.selectedLinea.subscribe(function (newSelection) {
$.getJSON('/Home/GetRides',
{
LineaSelezionata: newSelection,
DirezioneSelezionata: $('input[name=radio4]:checked', '.areaselezione').val()
},
function (data) {
debugger;
self.ArrayCorse(data);
});
});
Related
I have the following client-side code:
var ProfileManager = function () {
self.SelectedLanguage = ko.observable();
self.SelectedLanguage.subscribe(function (newValue) {
alert("The person's new name is " + newValue);
});
var bindUIwithViewModel = function (viewModel) {
ko.applyBindings(viewModel);
};
}
and I later do bindUIwithViewModel(self);.
and a HTML select bound to SelectedLanguage:
<select id="selectAvailableLanguages" class="form-control language-select" data-bind="options: AvailableLanguages, optionsText: 'Code', value : SelectedLanguage"></select>
The select gets populated successfully, the value inside SelectedLanguage observable changes, but the alert just won't show up. Any ideas?
Also, don't know if related but the observe array inside __ko.mapping_ is an array[0]..
Please check the fiddle. Note, "AvailableLanguages" and "SelectedLanguage" properties should exist in the same context, i.e. belong the binded view model.
I've modified your JS code:
var ProfileManager = function () {
self.SelectedLanguage = ko.observable();
self.SelectedLanguage.subscribe(function (newValue) {
alert("The person's new name is " + JSON.stringify(newValue));
});
self.AvailableLanguages = [ { Code: 'c++', Person: 'John' }, { Code: 'c#', Person: 'Mark' } ]
}
ko.applyBindings(new ProfileManager());
I have a dropdown and data binded to it as below
HTML:
<div>
<label>Notice Type</label>
<select id="ntctype" data-bind="options: NoticeType, value: selectedNoticeType, optionsCaption:'Choose...', optionsValue:'NoticeTypeID', optionsText:'NoticeTypeDescription'"></select>
</div>
KO JS:
self.NoticeType = ko.observableArray([]);
self.selectedNoticeType = ko.observable();
$.getJSON("GetNoticeType", null, function (data) {
self.NoticeType(data);
}
);
the NoticeType array looks like this
[{"NoticeTypeID":1,"NoticeTypeDescription":"Close"},{"NoticeTypeID":2,"NoticeTypeDescription":"Open"}]
I would like to set the deafult value as Close after binding.I tried using optionsAfterRender & ko.applybindingstoNode none of them worked.
What would be the clean and neat approach to do this?
As mentioned in the comments you just need to set default value to value binded observable in viewModel
View Model :
function accountViewModel() {
var self = this;
self.NoticeType = ko.observableArray();
self.selectedNoticeType = ko.observable();
self.ajaxcall = function () {
self.NoticeType([{
"NoticeTypeID": 1,
"NoticeTypeDescription": "Close"
}, {
"NoticeTypeID": 2,
"NoticeTypeDescription": "Open"
}]);
self.selectedNoticeType = ko.observable(1);
}
self.ajaxcall();
}
Working fiddle here
I want to use select2 in knockout.js
for this i have a bindinghandler.
ko.bindingHandlers.select2 = {
init: function(element, valueAccessor, allBindingsAccessor) {
var obj = valueAccessor(),
allBindings = allBindingsAccessor(),
lookupKey = allBindings.lookupKey;
$(element).select2(obj);
if (lookupKey) {
var value = ko.utils.unwrapObservable(allBindings.value);
$(element).select2('data', ko.utils.arrayFirst(obj.data.results, function(item) {
return item[lookupKey] === value;
}));
}
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).select2('destroy');
});
},
update: function(element) {
$(element).trigger('change');
}
};
i use the handler like this:
<select id="itemselector" data-bind="options: items, optionsText: 'Name', OptionsValue:'Id', select2: {}"></select>
now to make custom templates i have to pass a format function to select2 like htis
function formatSelection(item) {
return '<b>' + item.text + '</b>';
}
but i can't figure out how to do this with that binding handle. Can someone explain me how to pass the formatfunction or a string template to the binding handler, so that it will be applied to select?
Just add your option(s) into the {} after the select2 binding declaration. For example:
<select id="itemselector" data-bind="options: items, optionsText: 'Name', optionsValue:'Id', select2: {formatResult: formatSelection}"></select>
Question back at you, the select2 binding that you are using, is a new version to me. How is the lookupKey being used?
I want to know what the previous value is from a Dropdown list.
In the following html I can set the Options and the currently selected.
<select data-bind="options: group_128,
optionsText: 'description',
value: selectedgroup_128,
event: { change: selectionChanged_group_128 }">
</select>
in the Javascript / viewModel I do :
selectionChanged_group_128 = function (data, event) {
self.addItemClicked2(self.selectedgroup_128, event)
};
At this point I want to know what the previous selected item was to send it to the addItemClicked2.
You could subscribe to the observable to get the value before it changed:
self.selectedgroup_128.subscribe(function(oldValue) {
self.selectedgroup_128.previousValue = oldvalue;
}, null, "beforeChange");
Now you can get the previous value like this:
self.selectedgroup_128.previousValue
Why not just change your model to store the new value as previous value?
http://jsfiddle.net/uLeDP/
var ViewModel = function() {
this.group_128 = ko.observable([{description:"first"},{description:"second"}]);
this.selectedgroup_128 = ko.observable("first");
this.prevgroup_128 = null;
this.selectionChanged_group_128 = function(val) {
alert("Now I'm " + this.selectedgroup_128().description + " but I was " + this.prevgroup_128);
this.prevgroup_128 = this.selectedgroup_128().description;
}
};
I'm having some problems with the value binding on a select tag in knockout.
I've got the following markup:
<select id="faultCode" data-bind="options: FaultCodes, optionsText: 'Description', value: FaultCode, optionsCaption: 'Choose a Fault Code'"></select>
<select id="causeCode" data-bind="options: CauseCodes, optionsText: 'Description', value: CauseCode, optionsCaption: 'Choose a Cause Code'"></select>
<select id="serviceAction" data-bind="options: ActionCodes, value: ActionCode, optionsText: 'Description', optionsCaption: 'Choose an Action Code'"></select>
<select id="plantClass" data-bind="options: PlantClasses, value: PlantClass, optionsText: 'Description', optionsCaption: 'Choose a Plant Class'"></select>
<select id="plantItem" data-bind="options: PlantItems, value: PlantItem, optionsText: 'Description', optionsCaption: 'Choose a Plant Item'"></select>
And my Javascript:
self.FaultCode = ko.observable();
self.ActionCode = ko.observable();
self.PlantClass = ko.observable();
self.PlantItem = ko.observable();
self.CauseCode = ko.observable();
self.FaultCodes = ko.observableArray();
self.ActionCodes = ko.observableArray();
self.PlantClasses = ko.observableArray();
self.PlantItems = ko.observableArray();
self.CauseCodes = ko.observableArray();
self.closeRequest = function () {
var fault = "";
var action = "";
var cause = "";
var pc = "";
var pi = "";
if (self.FaultCode() != undefined) {
fault = self.FaultCode();
}
if (self.ActionCode() != undefined) {
action = self.ActionCode();
}
if (self.CauseCode() != undefined) {
cause = self.CauseCode();
}
if (self.PlantClass() != undefined) {
pc = self.PlantClass();
}
if (self.PlantItem() != undefined) {
pi = self.PlantItem();
}
}
If the user chooses an option from all 5 of the select boxes and fires the closeRequest function, the FaultCode observable has a value of "" (Empty String) and the CauseCode observable has a value of undefined. The three other value observables all have the correct object as their value.
Are you sure that your FaultCode has a value when you are entering closeRequest or whatever?
console.log(self.FaultCode());
When you first get into that function. Also, you are saying if (self.FaultCode() != undefined) which is a loose comparison and not very good. If you are getting a value logged from the above console.log statement, this should fix it for you -
self.closeRequest = function () {
console.log(self.FaultCode());
var fault = "";
var action = "";
var cause = "";
var pc = "";
var pi = "";
if (self.FaultCode()) {
fault = self.FaultCode();
}
if (self.ActionCode()) {
action = self.ActionCode();
}
if (self.CauseCode()) {
cause = self.CauseCode();
}
if (self.PlantClass()) {
pc = self.PlantClass();
}
if (self.PlantItem()) {
pi = self.PlantItem();
}
}
As long as the observables aren't false, undefined, "", or null it will set fault equal to the observable.
When you use a double equal sign you are comparing the value loosely, use the triple equals for type comparison as well.