This is how I have my page set up, but no data is being displayed, and I'm not sure why:
JavaScript/knockout:
var getList = function () {
Ajax.Get({
Url: ...,
DataToSubmit: {id: properties.Id },
DataType: "json",
OnSuccess: function (roleData, status, jqXHR) {
bindModel(roleData);
}
});
};
// Binds the main ViewModel
var bindModel = function (data) {
var _self = viewModel;
ko.applyBindings(viewModel, $('#ListView')[0]);
};
var viewModel = {
ListRoleTypes: ko.observableArray([]),
.....
};
var roleViewModel = function (data) {
var _self = this;
_self.ContentRole = ko.observable(data.ContentRole);
_self.RoleName = ko.observable(data.RoleName);
_self.RoleRank = ko.observable(data.RoleRank);
_self.UserCount = ko.observable(data.UserCount);
};
This is my View page:
<div data-bind="foreach: ListRoleTypes">
<span data-bind="text: RoleName"></span>
</div>
Any thoughts on where I am going wrong?
you are calling bindmodel and passing in the roledata, but then in bindmodel, you dont do anything with it.
Ajax.Get({
Url: ...,
DataToSubmit: {id: properties.Id },
DataType: "json",
OnSuccess: function (roleData, status, jqXHR) {
bindModel(roleData);
}
});
};
// Binds the main ViewModel
var bindModel = function (data) {
// need to do something with viewmodel to handle the passed in data
viewmodel.initialize(data);
ko.applyBindings(viewModel, $('#ListView')[0]);
};
Related
I have a view model in knockout as follow. What i intend to achieve here is to make the ajax call into a reusable function as follow (and include it into separate js file).
However, I got the error message showing self.CountryList is not defined. How could this be resolved?
// Working
var ViewModel = function() {
var self = this;
self.CountryList = ko.observableArray([]);
self.LoadCountry = function() {
$.ajax({
url: '/api/MyApi',
type: 'GET',
dataType: 'json',
success(data): {
$.each(data, function (index, value) {
self.CountryList.push(value);
});
}
});
}
}
ko.applyBindings(new LoadCountry());
// Not working
function LoadCountryList() {
$.ajax({
url: '/api/MyApi',
type: 'GET',
dataType: 'json',
success(data): {
$.each(data, function (index, value) {
self.CountryList.push(value);
});
}
});
}
var ViewModel = function() {
var self = this;
self.CountryList = ko.observableArray([]);
self.LoadCountry = function() {
LoadCountryList();
}
}
ko.applyBindings(new LoadCountry());
Your LoadCountryList function in the second version has no concept of the object it should be operating on - ie it has no idea what self is, hence the error. The simple solution is for you to pass the object in when calling the function:
function LoadCountryList(vm) {
$.ajax({
url: '/api/MyApi',
type: 'GET',
dataType: 'json',
success(data): {
$.each(data, function (index, value) {
//reference the parameter passed to the function
vm.CountryList.push(value);
});
}
});
}
var ViewModel = function() {
var self = this;
self.CountryList = ko.observableArray([]);
self.LoadCountry = function() {
//pass ourselves to the function
LoadCountryList(self);
}
}
well clearly self.ContryList does not exist in your external file. One easy way to solve this is to pass in a reference to the appropriate "list" to push values to:
function LoadCountryList(countryList) {
$.ajax({
url: '/api/MyApi',
type: 'GET',
dataType: 'json',
success(data): {
$.each(data, function (index, value) {
countryList.push(value);
});
}
});
}
and in your view model:
var ViewModel = function() {
var self = this;
self.CountryList = ko.observableArray([]);
self.LoadCountry = function() {
LoadCountryList(self.CountryList);
}
}
I am a newbie in Knockout JS. i want to apply validations in KO. i have used plugin knockout.validation.min.js . I have implemented it like this but not working
My View Model
$(document).ready(function myfunction() {
ko.applyBindings(new EmployeeKoViewModel());
})
var EmployeeKoViewModel = function () {
var self = this;
self.EmpId = ko.observable()
self.Name = ko.observable("").extend({ required: { message: "please enter employee name " } });
self.City = ko.observable("").extend({ required: { message: "please enter employee city " } });
self.Employees = ko.observableArray();
//GetEmployees();
var EmpData = {
EmpId: self.EmpId,
Name: self.Name,
City: self.City,
};
function GetEmployees() {
$.ajax({
type: "GET",
url: "/Employee/About",
}).done(function (data) {
self.Employees(data);
}).error(function (ex) {
alert("Error");
});
}
self.save = function () {
var EmployeeKoViewModel.errors = ko.validation.group(self);
if (!EmployeeKoViewModel.errors().length <= 0) {
EmployeeKoViewModel.errors.showAllMessages();
return false;
}
$.ajax({
type: "POST",
url: "/Employee/Save",
data: ko.toJSON(EmpData),
contentType: "application/json",
success: function (data) {
self.EmpId(data.EmpId);
GetEmployees();
},
error: function () {
alert("Failed");
}
});
//Ends Here
};
}
I have created a fiddle it is working when i comment GetEmployees() method but not working with it
At this line
var EmployeeKoViewModel.errors = ko.validation.group(self);
you are trying to create a variable, but the syntax is like creating an object with a property which is of course invalid. In order to fix this you can initialize your object first:
var EmployeeKoViewModel = {};
EmployeeKoViewModel.errors = ko.validation.group(self);
if (!EmployeeKoViewModel.errors().length <= 0) {
EmployeeKoViewModel.errors.showAllMessages();
return false;
}
Here is a working jsFiddle
I am new to Jquery world.
I have these following codes:
$target.ajaxChosen({
type: 'GET',
url: '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?filterKey='+keyword,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
It seems the variable 'keyword' does not dynamically changed its value. The value for 'keyword' comes from an element with on change event. Would someone enlighten me about this on how to solve this? Thanks in advance.
its better you compose your url object just before call
function onclick(keyword)
{
var url = '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?
filterKey='+keyword;
ajaxCall(url);
}
function ajaxCall(url)
{
$target.ajaxChosen({
type: 'GET',
url: url,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
}
I have the following script. It runs, it passes the variables to the controller, the controller executes correctly, but for whatever reason the success function does not fire and therefore does not refresh my html. Instead the error fires off. Nothing is jumping out at me as to the cause. Thanks for the help!
$(function() {
$("#btnUpdateTick").unbind('click').click(function () {
var currenttick =
{
"TicketID":#Html.Raw(Json.Encode(Model.TicketID)),
"Title": $("#Title").val(),
"Creator": $("#Creator").val(),
"StatusID": $("#StatusID").val(),
"Description": $("#Description").val(),
"newComment":$("#txtAddComment").val(),
Cat:
{
"CatID":$("#ddCurrTickCat").val()
}
}
//var newcomment = $("#txtAddComment").val();
var conv = JSON.stringify(currenttick);
$.ajaxSetup({cache:false});
$.ajax({
url: '#Url.Action("UpdateTicket", "HelpDesk")',
data: JSON.stringify({ticket:currenttick}),
type: "POST",
dataType: "json",
contentType: "application/json",
success: function (data) {
$("#loadpartial").html(data);
},
error: function (data){alert("turd")}
});
});
});
My controller:
[HttpPost]
public PartialViewResult UpdateTicket(Tickets ticket)
{
////Tickets.UpdateTicket(currenttick);
if (ticket.newComment != "")
{
Comments.addCommentToTicket(ticket.TicketID, ticket.newComment,UserPrincipal.Current.SamAccountName.ToString());
}
Tickets model = new Tickets();
ViewBag.CategoryList = Category.GetCategories();
ViewBag.StatusList = TicketStatus.GetStatusList();
model = Tickets.GetTicketByID(ticket.TicketID);
model.TicketComments = new List<Comments>();
model.TicketComments = Comments.GetCommentsForTicketByID(ticket.TicketID);
//model.TicketComments = Comments.GetCommentsForTicketByID(ticketID);
//ViewBag.TicketComments = Comments.GetCommentsForTicketByID(ticketID);
return PartialView("TicketDetails", model);
}
Your controller is returning a view instead of json. You should be returning a JsonResult instead. Try this:
[HttpPost]
public JsonResult UpdateTicket(Tickets ticket)
{
////Tickets.UpdateTicket(currenttick);
if (ticket.newComment != "")
{
Comments.addCommentToTicket(ticket.TicketID, ticket.newComment,UserPrincipal.Current.SamAccountName.ToString());
}
Tickets model = new Tickets();
ViewBag.CategoryList = Category.GetCategories();
ViewBag.StatusList = TicketStatus.GetStatusList();
model = Tickets.GetTicketByID(ticket.TicketID);
model.TicketComments = new List<Comments>();
model.TicketComments = Comments.GetCommentsForTicketByID(ticket.TicketID);
//model.TicketComments = Comments.GetCommentsForTicketByID(ticketID);
//ViewBag.TicketComments = Comments.GetCommentsForTicketByID(ticketID);
return Json(model);
}
If you want to return Partial view from ajax call then modify ur ajax request as :
$.ajax({
url: '#Url.Action("UpdateTicket", "HelpDesk")',
data: JSON.stringify({ticket:currenttick}),
type: "POST",
dataType: "html",
success: function (data) {
$("#loadpartial").html(data);
},
error: function (data){alert("turd")}
});
Now "data" in ur success function will have html returned from PartialViewResult().
The following code works great with a hardcoded array (initialData1), however I need to use jquery .ajax (initialData) to initialize the model and when I do the model shows empty:
$(function () {
function wiTemplateInit(winame, description) {
this.WIName = winame
this.WIDescription = description
}
var initialData = new Array;
var initialData1 = [
{ WIName: "WI1", WIDescription: "WIDescription1" },
{ WIName: "WI1", WIDescription: "WIDescription1" },
{ WIName: "WI1", WIDescription: "WIDescription1" },
];
console.log('gridrows:', initialData1);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{UserKey: '10'}",
url: "WIWeb.asmx/GetTemplates",
success: function (data) {
for (var i = 0; i < data.d.length; i++) {
initialData.push(new wiTemplateInit(data.d[i].WiName,data.d[i].Description));
}
//console.log('gridrows:', initialData);
console.log('gridrows:', initialData);
}
});
var viewModel = function (iData) {
this.wiTemplates = ko.observableArray(iData);
};
ko.applyBindings(new viewModel(initialData));
});
I have been trying to work from the examples on the knockoutjs website, however most all the examples show hardcoded data being passed to the view model.
make sure your "WIWeb.asmx/GetTemplates" returns json array of objects with exact structure {WIName : '',WIDescription :''}
and try using something like this
function wiTemplateInit(winame, description)
{
var self = this;
self.WIName = winame;
self.WIDescription = description;
}
function ViewModel()
{
var self = this;
self.wiTemplates = ko.observableArray();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{UserKey: '10'}",
url: "WIWeb.asmx/GetTemplates",
success: function (data)
{
var mappedTemplates = $.map(allData, function (item) { return new wiTemplateInit(item.WiName, item.Description) });
self.wiTemplates(mappedTemplates);
}
});
}
var vm = new ViewModel();
ko.applyBindings(vm);
If you show us your browser log we can say more about your problem ( Especially post and response ). I prepared you a simple example to show how you can load data with ajax , bind template , manipulate them with actions and save it.
Hope this'll help to fix your issue : http://jsfiddle.net/gurkavcu/KbrHX/
Summary :
// This is our item model
function Item(id, name) {
this.id = ko.observable(id);
this.name = ko.observable(name);
}
// Initial Data . This will send to server and echo back us again
var data = [new Item(1, 'One'),
new Item(2, 'Two'),
new Item(3, 'Three'),
new Item(4, 'Four'),
new Item(5, 'Five')]
// This is a sub model. You can encapsulate your items in this and write actions in it
var ListModel = function() {
var self = this;
this.items = ko.observableArray();
this.remove = function(data, parent) {
self.items.remove(data);
};
this.add = function() {
self.items.push(new Item(6, "Six"));
};
this.test = function(data, e) {
console.log(data);
console.log(data.name());
};
this.save = function() {
console.log(ko.mapping.toJSON(self.items));
};
}
// Here our viewModel only contains an empty listModel
function ViewModel() {
this.listModel = new ListModel();
};
var viewModel = new ViewModel();
$(function() {
$.post("/echo/json/", {
// Data send to server and echo back
json: $.toJSON(ko.mapping.toJS(data))
}, function(data) {
// Used mapping plugin to bind server result into listModel
// I suspect that your server result may contain JSON string then
// just change your code into this
// viewModel.listModel.items = ko.mapping.fromJSON(data);
viewModel.listModel.items = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
});
})