I've been working on a single page app based on Knockoutjs' excellent mail example of creating a 'single page app'. Steve Sanderson's example uses jQuery templates that reside in the page for all the forms in the example.
I'm trying to incorporate an .ascx into this scenario: the user clicks on a row from the listing which brings up the record by .load-ing the .ascx. On submit the form data successfully goes to the controller but the return doesn't hit the success, failure or even completed methods of the .ajax call. Instead the browser alerts the user to download the response.
I've been steadily working on this and found some additonal info that might shed some more light. The submit button does not run to the viewModel.updateWorksheet
method. It submits the form directly to the controller. Am I doing something wrong with the knockoutjs data-bind="submit: provViewModel.updateWorksheet"
attribute on the form tag?
The controller receives the json in the following method:
public JsonResult WorksheetUpdateAjax( WorksheetDTO worksheetDTO)
{
//(some code here)
try
{
_wksRepos.Update();
}
catch (Exception e)
{
return Json(e.Message, JsonRequestBehavior.AllowGet);
}
return Json("Successfully updated", JsonRequestBehavior.AllowGet);
}
The form tag and Submit button look like this:
<form name="wokrsheetAddOrEdit"
class="ui-widget"
data-bind="submit: viewModel.updateWorksheet" action="/WorksheetUpdateAjax">
<br /><br />
(html here)<br /><br />
<button type="submit">Update</button>
<br />
</form>
Here's the viewModel declaration (lots left out)
viewModel = {
updateWorksheet: function () {
$.validator.unobtrusive.parse("#worksheetForm");
if (!$('#worksheetForm').valid()) {
return false;
}
var worksheetJson = ko.toJSON({
worksheetDTO: provViewModel.selectedWorksheet
});
//ko.utils.postJson($("form").wokrsheetAddOrEdit, worksheetJson); -- tried this but does the same
$.ajax({
url: $("form").worksheetAddOrEdit,
type: "POST",
data: worksheetJson,
dataType: "json",
success: function (data) {
// here I'd like to return to the app
},
failure: function (data) {
alert(data);
return false;
}
});
}
}
I found the answer...
Since .load() is used the ko.applyBindings has to be reset:
viewModel.selectedWorksheet = ko.dependentObservable(function () {
var worksheetIdToFind = this.selectedWorksheetId();
var worksheetToReturn = ko.utils.arrayFirst(viewModel.currentProvWorksheets(), function (item) { return item.Id == worksheetIdToFind; });
if (worksheetIdToFind) {
$("#worksheetForm").load("/Provider/GetWorksheetForm/" + worksheetIdToFind,
function () {
var theForm = document.forms.worksheetAddOrEdit;
ko.applyBindingsToNode(theForm, null, provViewModel);
});
}
return worksheetToReturn; }, viewModel);
(also my misspelling of worksheetAddOrEdit in the form name didn't help my sanity much either)