I am trying to bind an array of values from a check box list to a model that has a property type of byte. So I am returned {"1", "2" , "3"} from check box selections I am needing this in byte format before it reaches my model so it can be passed properly to my model.
Property byte { get; set; }
My Knockout Viewmodel where self.DaysList = ko.observableArray(); is my check box list property.
function ScheduledCommand() {
//data
var self = this;
// An observable is a “JavaScript object that can notify subscribers about changes.”
// When the contents of an observable change, the view is automatically updated to match.
self.ScheduledCommandId = ko.observable();
self.NextOccurence = ko.observable();
self.CommandType = ko.observable();
self.CommandAssembly = ko.observable();
self.IntervalAmount = ko.observable();
self.IntervalType = ko.observable();
self.Catchup = ko.observable();
self.Retry = ko.observable();
self.SendToQueue = ko.observable();
self.Enabled = ko.observable();
self.SelectedCommand = ko.observable();
self.DaysList = ko.observableArray();
var Command = {
ScheduledCommandId: self.ScheduledCommandId,
NextOccurence: self.NextOccurence,
CommandType: self.CommandType,
CommandAssembly: self.CommandAssembly,
IntervalAmount: self.IntervalAmount,
IntervalType: self.IntervalType,
Catchup: self.Catchup,
Retry: self.Retry,
SendToQueue: self.SendToQueue,
Enabled: self.Enabled,
SelectedCommand: ko.observable(),
DaysList: ko.observableArray(),
};
self.Command = ko.observable();
self.Commands = ko.observableArray();
self.get = function () {
$.ajax({
url: '/api/Values',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Commands(data); //Put the response in ObservableArray
$("#btnGetCommands").hide();
$("#commandlist").show();
$("#btnHideCommands").show();
}
});
}
self.hidecommands = function ()
{
$("#btnGetCommands").show();
$("#btnHideCommands").hide();
$("#commandlist").hide();
}
//ko.bindingHandlers.bootstrapPopover = {
// init: function (element, valueAccessor, allBindingsAccessor, Command) {
// var options = valueAccessor();
// var defaultOptions = {};
// options = $.extend(true, {}, defaultOptions, options);
// $(element).popover(options);
// }
//};
self.create = function (formElement) {
if (Command.NextOccurence() != "" && Command.CommandType() != "" && Command.CommandAssembly() != "") {
$.ajax({
url: '/api/Values',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Command),
success: function (data) {
// alert('added');
self.Commands.push(data);
self.DaysList("");
self.NextOccurence("");
self.CommandType("");
self.CommandAssembly("");
self.IntervalAmount("");
self.IntervalType("");
self.Catchup("");
self.Retry("");
self.SendToQueue("");
self.Enabled("");
alert("Command " + self.CommandType() + " successfully created.")
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
}
else {
alert('Please Enter All the Values !!');
}
},
self.selectCommand = function (command) {
self.SelectedCommand(command.ScheduledCommandId)
alert(command.ScheduledCommandId);
},
document.getElementById("btnGetCommands").onclick
}
$(document).ready(function () {
// When the DOM is fulled loaded, call the ko.applyBindings function and pass
// in a new instance of the commandViewModel:
$("#btnHideCommands").hide();
$("#commandlist").hide();
ko.applyBindings(new ScheduledCommand());
// The ko.applyBindings method activates Knockout and wires up the view-model to the view.
});
My API Controller Method this has no value for DaysList
public HttpResponseMessage Post(ScheduledCommand model)
{
repo.Add(model);
var response = Request.CreateResponse<ScheduledCommand>(HttpStatusCode.Created, model);
string uri = Url.Link("DefaultApi", new { id = model.ScheduledCommandId });
response.Headers.Location = new Uri(uri);
return response;
}
Finally my check box list.
#foreach (var item in ViewData["checklist"] as IEnumerable<SelectListItem>)
{
<div class="checkbox">
<label>
<input type="checkbox" data-bind="attr: { value: #item.Value}, checked: $root.DaysOfWeek">
#item.Text
</label>
</div>
}
The Knockout side of it is good it returns what I want but I can not convert it to a byte.
Thank you for your time!
What I wanted to do was try to convert a knockout observable array to a byte before it was passed to server in order to satisfy the parameter type(small int). Instead, what I did was create a "placeholder"(string array) property and convert it to a byte to satisfy my data property.
I was just hoping to remove the additional step using javascript.
Related
I am getting a 500 error when I try and delete an item in my list using ajax.
From using the console on Chrome combined with Fiddler, a null reference on the Id is the issue. Debugging through Chrome's console shows that the announcement object does have an Id.
I was under the impression 500 errors came from the server, but I have a break point on the function path it's calling and not getting hit.
Is there anything that is staring me in the face as to why this would be setting the announcement.Id to null?
controller:
public JsonResult DeleteAnnouncement(int Id)
{
if(repository.DeleteAnnouncement(Id))
{
return Json(repository.GetAllAnnouncements(), JsonRequestBehavior.AllowGet);
}
return Json(null);
}
repository:
public bool DeleteAnnouncement(int Id)
{
var model = (from a in db.DbAnnouncement
where a.Id == Id
select a).SingleOrDefault();
if (model.Id != 0)
{
db.DbAnnouncement.Remove(model);
db.SaveChanges();
return true;
}
else
{
return false;
}
}
js script:
<script type="text/javascript">
function AnnouncementViewModel() {
//Make the self as 'this' reference
var self = this;
//Declare observable which will be bind with UI
self.Id = ko.observable("");
self.Title = ko.observable("");
self.Details = ko.observable("");
self.DTCreated = ko.observable("");
self.LastUpdated = ko.observable("");
self.CreatedUser = ko.observable("");
self.UpdatedUser = ko.observable("");
self.VersionNum = ko.observable("");
self.StartDT = ko.observable("");
self.ExpiryDT = ko.observable("");
self.Enabled = ko.observable("");
self.GroupID = ko.observable("");
self.URLLink = ko.observable("");
var Announcement = {
Id: self.Id,
Title: self.Title,
Details: self.Details,
DTCreated: self.DTCreated,
LastUpdated: self.LastUpdated,
CreatedUser: self.CreatedUser,
UpdatedUser: self.UpdatedUser,
VersionNum: self.VersionNum,
StartDT: self.StartDT,
ExpiryDT: self.ExpiryDT,
Enabled: self.Enabled,
GroupID: self.GroupID,
URLLink: self.URLLink
};
self.Announcement = ko.observable();
self.Announcements = ko.observableArray(); // list of announcements
// Delete announcement
self.delete = function (Announcement) {
if (confirm('Are you sure to Delete "' + Announcement.Title + '"?')) {
$.ajax({
url: '#Url.Action("DeleteAnnouncement","Announcement")',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
//data: ko.toJSON(Announcement.Id),
data: {Id: Announcement.Id},
success: function (data) {
self.Announcements.remove(Announcement);
alert("Record Deleted Successfully");
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
}
}
}
$(document).ready(function () {
var viewModel = new AnnouncementViewModel();
ko.applyBindings(viewModel);
});
You are using ajax contentType as Json but not really sending a json object to server. Use
data: JSON.stringify({ Id: Announcement.Id() }),
and decorate your mvc action with [HttpPost]
[HttpPost]
public JsonResult DeleteAnnouncement(int Id)
{}
I have a viewModel with a function
function resetForm(){
loanSystem("lis");
status("");
processor("");
fileType("funded");
orderDate("");
loanNumber("");
team("");
borrower("");
tracking("");
};
And a button on page with
<button type="reset" data-bind="click: resetForm">Reset</button>
But I am getting error:
Unable to process binding "click: function(){ return resetForm}. resetForm is not defined.
But I know my resetForm() works because it is called in my init function and if I change values in my resetForm() it show on initial page load. Any ideas?
var homeViewModel = (function () {
var loanSystem = ko.observable("lis");
var status = ko.observable("");
var processor = ko.observable("");
var fileType = ko.observable("funded");
var orderDate = ko.observable("");
var loanNumber = ko.observable("");
var team = ko.observable("");
var borrower = ko.observable("");
var tracking = ko.observable("");
var isLoanSystem = ko.computed(function () {
return (loanSystem() == "lps");
});
var isCalendar = ko.computed(function () {
return (isLoanSystem() && fileType() == "cancelled");
});
function resetForm(){
loanSystem("lis");
status("");
processor("");
fileType("funded");
orderDate("");
loanNumber("");
team("");
borrower("");
tracking("");
};
function submitFileInformation() {
if (!ValidInputs()) {
return;
}
var fileData = {
loanSystem: loanSystem(),
status: status(),
processor: processor(),
fileType: fileType(),
orderDate: orderDate(),
loanNumber: loanNumber(),
team: team(),
borrower: borrower(),
tracking: tracking()
};
$.ajax({
type: "POST",
url: "/ComplianceProcessing/Ajax.ashx",
data: JSON.stringify(fileData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
if (data === false) {
alert("There was an error writing the file to the database.");
return;
}
alert('Data has been successfully saved.');
resetForm();
},
failure: function() {
alert('Failure');
}
});
}
return {
init: function() {
resetForm();
},
loanSystem: loanSystem,
isLoanSystem: isLoanSystem,
status: status,
processor: processor,
fileType: fileType,
isCalendar: isCalendar,
orderDate:orderDate,
loanNumber: loanNumber,
team: team,
borrower: borrower,
tracking: tracking
};
})();
Your resetForm is not exprosed from your viewmodel which makes it esentally private so Knockout cannot find it.
The solution is very easy, just include the resetForm in your returned object (which is your "public API"):
return {
init: function() {
resetForm();
},
loanSystem: loanSystem,
isLoanSystem: isLoanSystem,
status: status,
processor: processor,
fileType: fileType,
isCalendar: isCalendar,
orderDate:orderDate,
loanNumber: loanNumber,
team: team,
borrower: borrower,
tracking: tracking,
resetForm: resetForm //add this line
};
How do I dynamically pass a property reference as a method arguments ?
This is what ajax success function response data look like:
{
users: {
data: {}
},
countries: {
data: {}
},
states: {
data: {}
}
}
This is example how i store the data previously:
var users = ko.observable();
var countries = ko.observable();
var states = ko.observable();
var store = function(data, observable)
{
observable(data);
}
$.ajax({
//... ajax options...
success: function(response)
{
// This is how i store the data previously
store(response.users.data, users);
store(response.countries.data, countries);
store(response.states.data, states);
}
});
And this is example what I have try so far:
$.ajax({
//... ajax options...
success: function(response)
{
// This is how i want to achieve
ko.utils.objectForEach(response, function(key, data)
{
store(data.data, key);
});
}
});
But unfortunately I just only pass the text string to the 2nd arguments of store method.
Any help and suggestions would be appreciated!
Thank you.
Make them properties of an object, then use strings:
var obj = {
users: ko.observable(),
countries: ko.observable(),
states: ko.observable()
};
var store = function(data, observable)
{
var prop = obj[observable];
if (prop) { // Just being defensive
prop(data);
}
};
$.ajax({
//... ajax options...
success: function(response)
{
var key;
for (key in response) {
store(response[key].data, key);
}
}
});
{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.
I'm new to web application development and i need to bind values which i retrieved from json object. i tried several ways but couldn't able to bind values to my combo box.
<script type="text/javascript">
var ViewModel = {
CheckIn : ko.observable(),
CheckOut: ko.observable(),
Lunch: ko.observable(),
Rest: ko.observable(),
WorkOnProject: ko.observable(),
Projects: ko.observableArray()
};
this.GetProjects = function () {
$.ajax({
type: "POST",
url: 'TimeRecord.aspx/ReturnComplexType',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (arg) {
for (var i = 0; i < arg.d.length ; i++) {
var value = arg.d[i].ProjectCode;
var option = new Option(arg.d[i].ProjectCode, arg.d[i].ProjectCode);
Select1.add(option, null);
}
},
error: function (arg) {
}
});
};
ko.applyBindings(ViewModel);
</script>
My HTML Code:
<tr>
<td class="auto-style1">Project Code </td>
<td ><select id="Select1" data-bind='options: Projects' style="width: 312px"></select>
<button data-bind='click: GetProjects'>Cancel</button>
</td>
</tr>
My Sever Side Coding :
[WebMethod]
public static object ReturnComplexType()
{
List<Project> projects = new List<Project>();
Project p = new Project();
p.ProjectID = 1;
p.ProjectCode = "ABC";
p.ProjectName = "Test";
projects.Add(p);
Project p2 = new Project();
p2.ProjectID = 2;
p2.ProjectCode = "DEF";
p2.ProjectName = "xsd";
projects.Add(p2);
return projects;
}
Your structure is way off, you're mixing object instances with function on the window object..
This is one way of solving it
ViewModel = function() {
this.CheckIn = ko.observable();
this.CheckOut = ko.observable();
this.Lunch = ko.observable();
this.Rest = ko.observable();
this.WorkOnProject = ko.observable();
this.Projects = ko.observableArray()
};
ViewModel.prototype = {
GetProjects: function () {
$.ajax({
type: "POST",
url: 'TimeRecord.aspx/ReturnComplexType',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
this.Projects(data);
}.bind(this),
error: function (arg) {
}
});
};
};
ko.applyBindings(new ViewModel());
What I did was to move the GetProjects function to the model object
Your select box is bound to the Projects observable but you don't set an explicit text/value
<select id="Select1" data-bind='options: Projects, optionsText: 'ProjectName', optionsValue:'ProjectID', value: SelectedProjectId"' style="width: 312px"></select>
The SelectedProjectId would be another observable in your model if you need to save the value somewhere.
The other thing you'll want to change is filling the actual observable array instead of select box directly.
<script type="text/javascript">
function ViewModel() {
var self = this;
self.CheckIn = ko.observable();
self.CheckOut = ko.observable();
self.Lunch = ko.observable();
self.Rest = ko.observable();
self.WorkOnProject = ko.observable();
self.Projects = ko.observableArray();
};
var VM = new ViewModel();
ko.applyBindings(ViewModel);
$.ajax({
type: "POST",
url: 'TimeRecord.aspx/ReturnComplexType',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (arg) {
for (var i = 0; i < arg.d.length ; i++) {
VM.Projects.push(d[i]);
}
},
error: function (arg) {
}
});
</script>
After you get things binding right you'll probably want to swap out the VM.Projects.push() for a speedier way.
Calling .push() when you're filling up arrays on initial load triggers a ton of notifications that can really make the page crawl.