Binding options and optionsText in Select dropdown in knockout.js - javascript

I read everything here and different websites and don't understand my problem. Looks like it should work, but it doesn't. I am getting [Object object] as options.
Html
<select data-bind="options: Cities, optionsText: Cities.CityNameRu"></select>
Knockout
function CityModel(data) {
this.CityId = ko.observable(data.CityId);
this.CityNameRu = ko.observable(data.CityNameRu);
this.CityName = ko.observable(data.CityName);
}
function IndexModel() {
var self = this;
self.Cities = ko.observableArray([]);
self.GetCities = function () {
$.ajax({
type: "GET",
url: '/FetchCities',
dataType: "json",
success: function (data) {
self.SuccessfullyRetrievedModelsFromAjax(data);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
});
};
this.SuccessfullyRetrievedModelsFromAjax = function (models) {
ko.utils.arrayForEach(models, function (model) {
self.Cities.push(new CityModel(model));
});
};
self.GetCities();
}
Json Response
[{"CityId":1,"CityName":"philadelphia","CityNameRu":"Филадельфия"},{"CityId":2,"CityName":"new-york","CityNameRu":"Нью Йорк"}

The value of optionsText is the string name of the property within each options array element to use for the text, so you should change your binding to:
<select data-bind="options: Cities, optionsText: 'CityNameRu'"></select>

Related

Cascading dropdown in knockout.js

I'm trying to populate another dropdownlist from a dropdown list, i keep getting error "TypeError: Unable to process binding "value: function (){return CompanySelected }" and "http://localhost/xxx/api/Transaction/LoadInsurancePolicies/undefined 400 (Bad Request)". Insurance Policy must be populated when Insurance company is chosen. this is the code below
self.InsuranceCompanyId = ko.observable();
self._companySelected= ko.observable(null);
self.CompanySelected = ko.computed({
read: function () {return this._companySelected() },
write: function (value) {
$.ajax({
url: baseUrl + 'api/Transaction/LoadInsurancePolicies/' +
value.InsuranceCompanyId,
type: 'GET',
headers: { 'Access-Control-Allow-Origin': '*' },
dataType: 'json',
success: function (data) {
if (data.Successfull == 1)
{
self.AllPolicies(data.Model); } },
error: function (request, error) {
}
});
this._companySelected(value);
},
owner: this
});
self.AllInsuranceCompanies = ko.observableArray([]);
self.AllPolicies = ko.observableArray([]);
self.LoadInsuranceCompanies = function () {
$.ajax({
url: baseUrl + 'api/Transaction/LoadInsuranceCompanies',
type: 'GET',
headers: { 'Access-Control-Allow-Origin': '*' },
dataType: 'json',
success: function (data) {
// console.log(data);
if (data.Successfull == 1) {
self.AllInsuranceCompanies(data.Model);
console.log(data);
}
},
error: function (request, error) {
console.log(error);
}
});
}
self.LoadInsuranceCompanies();
this is my view
<div class="form-group" data-bind="visible:(InputOption()==0)">
<label for="InputTxt" class="control-label col-md-4">Insurance
Company</label>
<div class="col-md-8">
<select data-bind="options: AllInsuranceCompanies,
optionsText: 'Name',
optionsValue:'Id',
optionsCaption: 'Choose...',
value:CompanySelected,
valueUpdate:'change'" class="form-control">
</select>
</div>
</div>
<div class="form-group" data-bind="visible: (InputOption()==0)">
<label for="InputTxt" class="control-label col-md-
4">InsurancePolicy</label>
<div class="col-md-8">
<select data-bind="options: AllPolicies,
optionsText: 'Name',
optionsValue:'Id',
value: selectedPolicy,
optionsCaption: 'Choose...'" class="form-control">
</select>
</div>
</div>
The following are probably the problems in your code.
self.CompanySelected is defined before self.AllPolicies. This will cause to have a runtime error since ko.computed automatically runs when it is defined. This is based on knockout documentation. Solution: try defining all ko.observable before all ko.computed or atleast put self.AllPolicies before self.CompanySelected.
Since the ko.computed automatically runs, and the value of self.CompanySelected is undefined, you will also have an undefined InsuranceCompanyId in your api call and this will result in Bad request 400. Solution: try adding a guard before calling your api. if(value){....}
In your html bindings, you put optionsValue: 'Id'. This will result in knockout trying to find an Id property in your model which probably does not exist. Solution: remove optionsValue:'Id' from your bindings so that the value when changing option will be the model object itself and not just the Id.
Here is a sample fiddle: https://jsfiddle.net/przquhcf/1/ which implements the solutions above.
Note: I just substituted setTimeout for your api calls since i dont have access to them. Dont worry about this part.
Your solution gave me an idea.I passed a function(value) and the value will be the selected Id,add it to the api as a parameter and it gets me the results.
self.insuranceCompanyId = ko.observable('');
self.selectedPolicy = ko.observable();
self._companySelected = ko.observable();
self.CompanySelected = ko.pureComputed({
read: function () {
return this._companySelected()
},
write: function (value) {
console.log("inside write", value)
if (value) {
console.log('data');
$.ajax({
url: baseUrl + "api/Transaction/LoadInsurancePolicies/" +
value,
type: 'GET',
headers: { 'Access-Control-Allow-Origin': '*' },
dataType: 'json',
success: function (data) {
if (data.Successfull == 1) {
self.AllPolicies(data.Model);
console.log(value);
}
},
error: function (request, error) {
console.log(error);
}
});
this._companySelected(value);
}
},
owner: this
});
self.LoadInsuranceCompanies();

How to know subcategory of category Dropdown Selection?

How can i Categorized in database uisng dropdownlist onces
I click INVORG category and show the available in DEPTCODE?
using Json
[HttpPost]
public JsonResult GetDEPTCODE(string id)
{
List<SelectListItem> states = new List<SelectListItem>();
///
//I got Error Code, can you please define my wrong code and correct thanks
states = from u in _db.USERGROUPs where u.INVORG == id
select(new SelectListItem {Text =u.INVORG, Value = u.DEPTCODE});
return Json(new SelectList(states, "Value", "Text"));
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
//Dropdownlist Selectedchange event
$("#INVORG").change(function () {
$("#DEPTCODE").empty();
$.ajax({
type: 'POST',
url: '#Url.Action("GetDEPTCODE")', // we are calling json method
dataType: 'json',
data: { id: $("#INVORG").val() },
// here we are get value of selected INVORG and passing same value
success: function (states) {
// states contains the JSON formatted list
// of states passed from the controller
$.each(states, function (i, state) {
$("#DEPTCODE").append('<option value="' + state.Value + '">' +
state.Text + '</option>');
// here we are adding option for States
});
},
error: function (ex) {
alert('Failed to retrieve states.' + ex);
}
});
return false;
})
});
</script>
change your method to HttpGet as you are getting data.
[HttpGet]
public ActionResult GetDEPTCODE(string id)
{
List<SelectListItem> items= new List<SelectListItem>();
return Json(new { data = items}, JsonRequestBehavior.AllowGet);
}
change your script as below
$("#INVORG").change(function () {
$("#DEPTCODE").empty();
$.ajax({
type: 'GET',
url: '#Url.Action("GetDEPTCODE")', // we are calling json method
dataType: 'json',
data: { id: $("#INVORG").val() },
// here we are get value of selected INVORG and passing same value
success: function (data) {
// states contains the JSON formatted list
// of states passed from the controller
$("#DEPTCODE").html('');
$.each(data["data"], function (key, value) {
$("#DEPTCODE").append($("<option>
</option>").val(value.Value).html(value.Text));
});
},
error: function (ex) {
alert('Failed to retrieve states.' + ex);
}
});
return false;
})

Kendo Autocomplete doesn't bind model

I try to bind a object in the Kendo Autocomplete widget.
the trouble is that the model turns in a string when i fill the options, and when i change the scope the input show me the text [object object] because the model isn't a string. is a object Example:
Cliente : {NombreMostrar:''}
How i can link properly the model in way when i change the scope model, show me the name in the input, and when a selected a item from widget update correctly the object model.
<input kendo-auto-complete k-ng-model="Credito.Cliente" k-options="ClientesBusqueda" style="width: 100%;" />
$scope.ClientesBusqueda = {
dataTextField: 'NombreMostrar',
dataSource: {
type: "get",
serverFiltering: true,
transport: {
read: {
url: "/Cliente/Buscar",
dataType: "json",
cache: false
},
parameterMap: function (data, action) {
var newParams = {
clienteNombre: data.filter.filters[0].value
};
return newParams;
}
},
schema: {
data: function (response) {
var clientes = response.clientes.map(function (cliente) {
cliente.NombreMostrar = (cliente.RazonSocial || [cliente.ApellidoPaterno, cliente.ApellidoMaterno, cliente.PrimerNombre, cliente.SegundoNombre].join(' ')).toUpperCase();
cliente.RFC = cliente.RFC.toUpperCase();
return cliente;
});
return clientes;
}
}
}
}
I answer to myself i found a solution in this link, him create a directive for bind model to the control.
https://codereview.stackexchange.com/questions/61638/custom-angular-directive-for-data-binding-on-teleriks-kendo-ui

not able to retain model value, if item added in select observable array

{model : {"firstName":"David","lastName":"Bawa","state":"AL"}}
{"allStates":[{"id":1,"value":"AL","text":"ALABAMA"},{"id":2,"value":"AK","text":"ALASKA"}}
<select name="state" data-bind="options: allStates,optionsValue : 'value', optionsText: 'text' ,value: model.state,optionsCaption: 'Choose...'" id="ddlState"></select>
var registrationModel = {
staticData: function () {
var self = this;
self.allStates = ko.observableArray();
self.hearUsAll = ko.observableArray();
registrationService.getAllStates().done(function (result) {
if (result != null) {
$.each(result.List, function (i, v) {
self.allStates.push(v);
});
}
});
}
}
and my registration service is
var registrationService = {
getAllStates: function () {
return service.staticService.get('GetAllStates');
}}
and my static service is
var service={
staticService: {
get: function (method) {
var results = store.fetch(method);
if (results) {
var dfd = new $.Deferred();
dfd.resolve(results);
return dfd.promise();
}
return $.ajax({
type: 'GET',
url: "http://xxxx/Service1.svc/" + method,
dataType: "json",
success: function (result) { if (result) { store.save(method,result) } }
}).promise();
}
states are populating from server through ajax, it works fine if I wait for allstates to be fetched and then apply bindings.
as you can see I am getting a pre-selected value of state in model. But when I do not wait for states to be populated and call apply bindings it will not work. it changes my state variable to null. I am getting my view model from mapping plugin.
Please help.

knockout.js observableArray is not recognized as a function

I have been using knockout.js for a while now, and haven't encountered this problem before. Usually, when I try to push a new js object to an observableArray, it works without an issue, but for some reason, this time around I'm getting this error:
TypeError: self.Students.push is not a function
Here is a snippet of my code:
window.ApiClient = {
ServiceUrl: "/api/students",
Start: function () {
var viewModel = ApiClient.ViewModel(ngon.ClientViewModel);
ko.applyBindings(viewModel);
viewModel.get();
}
};
ApiClient.ViewModel = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, this);
this.get = function (id) {
if (id == undefined) {
return ApiClient.Service.get(self.PageSize(), self.PageNumber(), function (data) {
self.Students(data);
});
}
}
this.post = function () {
return ApiClient.Service.post(self.DetailedStudent, function (data) {
self.Students.push(data);
});
}
return this;
}
ApiClient.Service = function () {
var _get = function (pageSize, pageNumber, callback) {
sv.shouldShowLoading = false;
var queryParams = String.format("?pageSize={0}&pageNumber={1}", pageSize, pageNumber);
$.ajax(ApiClient.ServiceUrl + queryParams, {
dataType: "json",
type: "get",
success: callback
});
}
var _post = function (student, callback) {
$.ajax(ApiClient.ServiceUrl, {
data: ko.mapping.toJSON(student),
type: "post",
contentType: "application/json; charset-utf-8",
statusCode: {
201 /*Created*/: callback,
400 /*BadRequest*/: function (jqxhr) {
var validationResult = $.parseJSON(jqxhr.responseText);
alert(jqxhr.responseText);
}
}
});
}
return {
get: _get,
post: _post
};
}();
$(document).ready(function () {
ApiClient.Start();
});
My student object is a very simple C# object that has Id, FirstName, LastName. The get() function works without any issues, it's just the callback function from the post() that cannot push the resulting data. Also, the data being returned back from the server looks correct:
{"Id":"rea","FirstName":"asdf","MiddleName":null,"LastName":"rrr"}
I solved this! It's because the initial viewModel, when being instantiated by the page's view model object had 'null' for its Students property.
knockout.js requires non-null values for all fields that are to be auto mapped.

Categories