knockout binding mvc not working - asp.net-mvc

I experimenting something with mvc and knockout.js but maybe a have binding problem.
My viewmodel is:
var urlPath = window.location.pathname;
var currencyVm = function () {
var self = this;
var validationOptions = { insertMessages: true, decorateElement: true, errorElementClass: 'errorFill' };
ko.validation.init(validationOptions);
//ViewModel
self.ID = ko.observable(0);
self.Id_Region = ko.observable("");
self.Description = ko.observable("");
self.Symbol = ko.observable("");
self.PayPalCode = ko.observable("");
self.IFSCode = ko.observable("");
self.isGridVisible = ko.observable(true);
self.isEditVisible = ko.observable(false);
self.isAddVisible = ko.observable(false);
//Objects ---------------------------------------------
self.Currency = ko.observable();
self.Currencys = ko.observableArray([]);
//Methods ---------------------------------------------
//Edit
self.editCurrency = function (dataItem) {
self.isGridVisible(false);
self.isEditVisible(true);
self.ID = ko.observable(dataItem.ID);
self.Id_Region = ko.observable(dataItem.Id_Region);
self.Description = ko.observable(dataItem.Description);
self.Symbol = ko.observable(dataItem.Symbol);
self.PayPalCode = ko.observable(dataItem.PayPalCode);
self.IFSCode = ko.observable(dataItem.IFSCode);
//var vm = ko.mapping.fromJS(dataItem);
//self.Currency(vm);
};
//Add
self.addCurrency = function () {
self.isGridVisible(false);
self.isAddVisible(true);
self.isEditVisible(false);
self.reset();
}
// Cancel Edit
self.cancelEdit = function () {
self.isEditVisible(false);
self.isGridVisible(true);
}
// Cancel Add
self.cancelAdd = function () {
self.isAddVisible(false);
self.isGridVisible(true);
}
//Reset
self.reset = function () {
self.ID(0);
self.Id_Region("");
self.Description("");
self.Symbol("");
self.PayPalCode("");
self.IFSCode("");
}
//Actions --------------------------------------------------
var Currency = {
ID: self.ID,
Id_Region: self.Id_Region,
Description: self.Description,
Symbol: self.Symbol,
PayPalCode: self.PayPalCode,
IFSCode: self.IFSCode
};
//Create
self.createCurrency = function () {
$.ajax({
url: "/Currency/CreateCurrency",
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Currency),
success: function (data) {
self.isEditVisible(false);
self.isAddVisible(false);
self.isGridVisible(true);
$("#gridCurrencies").data("kendoGrid").dataSource.read();
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
}
// Update
self.updateCurrency = function () {
$.ajax({
url: "/Currency/UpdateCurrency",
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Currency),
success: function (data) {
self.isEditVisible(false);
self.isEditVisible(false);
self.isGridVisible(true);
$("#gridCurrencies").data("kendoGrid").dataSource.read();
}
})
}
//Delete
self.deleteCurrency = function (currency) {
$.confirm({
title: "Delete",
content: "Sure to delete ?",
confirm: function () {
$.ajax({
url: "/Currency/DeleteCurrency",
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(currency),
success: function (data) {
$("#gridCurrencies").data("kendoGrid").dataSource.read();
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
},
cancel: function () {
}
});
}
};
in the view I call applybinding and then based on selected row of the Telerik grid I call editCurrency or deleteCurrency.
<script>
var viewModel = null;
$(function () {
viewModel = new currencyVm();
ko.applyBindings(viewModel);
});
function deleteCurrency(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.deleteCurrency(dataItem);
}
function editCurrency(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.editCurrency(dataItem);
}
</script>
In the markup I have the html elements with the bindings:
Thi is the div for add:
<div class="panel panel-default" data-bind="visible: isAddVisible" style="display:none">
<div class="panel-heading">Add New Currency</div>
<div class="panel-body">
<div class="row">
<div class="col-md-3">
#Html.LabelFor(model => model.IFSCode)
<input type="text" data-bind="value: $root.IFSCode, valueUpdate: 'keypress'" class="form-control " />
</div>
<div class="col-md-3">
#Html.LabelFor(model => model.PayPalCode)
<input type="text" data-bind="value: $root.PayPalCode, valueUpdate: 'keypress'" class="form-control " />
</div>
<div class="col-md-3">
#Html.LabelFor(model => model.Symbol)
<input type="text" data-bind="value: $root.Symbol, valueUpdate: 'keypress'" class="form-control " />
</div>
</div>
<div class="row">
<div class="col-md-9">
#Html.LabelFor(model => model.Description)
<input type="text" data-bind="value: $root.Description" class="form-control" />
</div>
</div>
<br />
<div class="row">
<div class="col-md-3">
<input data-bind="click: $root.createCurrency" type="button" class="btn btn-success btn-sm" value="#DbRes.T("Save", "Common")" />
<input data-bind="click: cancelAdd" type="button" class="btn btn-warning btn-sm" value="#DbRes.T("Cancel", "Common")" />
</div>
</div>
</div>
the edit div is like the add div but use different binding like data-bind="value: IFSCode"
The problem is that in add mode it work but when I edit I dont see nothing
in the textbox elements.
Also I use the to debug,
in add mode I can see the observables updating while I type something in textbox,
in edit mode the observables are emtpy and remain while typeing something.
May some body help please to understand what appen to this code
Your help is very appreciated.

Related

How to load jqgrid on button click and send parameters to the action in jqGrid 4.6.0 in MVC

I want to load every year's data in jqgrid when I click on a button and after loading a modal form and selecting the year from drop down list. a diagram of the steps
but i don't know how to do this.
And this is my source code :
<!-- Page content -->
<div class="w3-content" style="max-width: 100%">
<div class="container" style="width:40%;margin-top:2%">
Filter
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
</div>
<div class="modal-body">
<form id="myForm" dir="rtl">
<div class="form-group">
<label>Year</label>
#Html.DropDownListFor(model => model.YEAR_ABBR, ViewBag.YearList as MultiSelectList, "--select--", new { #class = "form-control", #id = "ddlYear", multiple = "multiple" })
</div>
</form>
</div>
<div class="modal-footer">
Cancel
<input type="reset" value="GetRep" class="btn btn-success" id="btnSubmit" />
</div> </div>
</div> </div> </div>
<div dir="rtl" align="center" style="overflow:auto" class="tablecontainer">
<div id="rsperror"></div>
<table id="list" cellpadding="0" cellspacing="0"></table>
<div id="pager" style="text-align:center;"></div>
</div>
Now my script is something like this:
<script type="text/javascript">
$(document).ready(function () {
bindData();
$("#btnSubmit").click(function () {
$('#list').trigger('reloadGrid'); })
});
var bindData = function () {
$('#list').jqGrid({
url: '#Url.Action("Get_RepContracts","Home")',
postData: { YEAR_ABBR: function () { return $('#YEAR_ABBR').val(); } },
datatype: 'json',
jsonReader: {
root: "Rows",
page: "Page",
},
mtype: 'GET',
//columns names
colNames: ['Vahed_Descript' ],
colModel: [
{ name: 'Vahed_Descript', index: 'Vahed_Descript', align: 'right', width: 200, sorttype: "number", }
],
pager: $('#pager'),
rowNum: 800,
rowList: [ 800 ,1000],
sortname: 'Vahed_Descript',
hidegrid: false,
direction: "rtl",
gridview: true,
rownumbers: true,
footerrow: true,
userDataOnFooter: true,
loadComplete: function () {
calculateTotal();
$("tr.jqgrow:odd").css("background", "#E0E0E0");
},
loadError: function (xhr, st, err) {
jQuery("#rsperror").html("Type: " + st + "; Response: " + xhr.status + " " + xhr.statusText);
} , loadonce: true
}) ;
And here the button code ( My modal form works well. when I click the filter button, the filter options in my modal form appear, and then I select the year from year dropdownlist in modal and then i click the report button, after that the below code fires and I can see the selected year's data in action "Get_RepContracts" but it does not bind to my jqgrid):
Thanks in Advance...
UPDATE : Now My code is like below :
$(document).ready(function () {
bindData();
$("#btnSubmit").click(function () {
var myPostData = $('#list').jqGrid("getGridParam", "postData");
$('#list').trigger('reloadGrid');
$("#myModal").modal("hide");
}) });
var bindData = function () {
$('#list').jqGrid({
url: '#Url.Action("Get_RepContracts","Home")',
postData: {
YEAR_ABBR : function () { return $("#YEAR_ABBR").val();},
} ,
datatype: 'json',
jsonReader: { ........
It seems to me that you have small problem with the usage of correct id of select element. Your HTML code contains #id = "ddlYear" parameter of #Html.DropDownListFor:
#Html.DropDownListFor(
model => model.YEAR_ABBR,
ViewBag.YearList as MultiSelectList,
"--select--",
new {
#class = "form-control",
#id = "ddlYear",
multiple = "multiple"
}
)
but you still use
postData: {
YEAR_ABBR: function () { return $("#YEAR_ABBR").val(); }
}
To solve the problem you should just modify the code to
postData: {
YEAR_ABBR: function () { return $("#ddlYear").val(); }
}

How to create Multi-Level Treeview in ASP.NET MVC

I have implemented a code to create Tree View and also save it into database.
Controller
public ActionResult IndexMda()
{
using (BackendEntities context = new BackendEntities())
{
var plist = context.MDA.Where(p => p.PARENT_MDA_ID == null).Select(a => new
{
a.MDA_ID,
a.MDA_NAME,
a.MDA_DESCRIPTION,
a.ORGANIZATION_TYPE
}).ToList();
ViewBag.plist = plist;
}
GetHierarchy();
return View();
}
public JsonResult GetHierarchy()
{
List<MDA2> hdList;
List<MdaViewModel> records;
using (BackendEntities context = new BackendEntities())
{
hdList = context.MDA.ToList();
records = hdList.Where(l => l.PARENT_MDA_ID == null)
.Select(l => new MdaViewModel
{
MDA_ID = l.MDA_ID,
text = l.MDA_NAME,
MDA_DESCRIPTION = l.MDA_DESCRIPTION,
ORGANIZATION_TYPE = l.ORGANIZATION_TYPE,
PARENT_MDA_ID = l.PARENT_MDA_ID,
children = GetChildren(hdList, l.MDA_ID)
}).ToList();
}
return this.Json(records, JsonRequestBehavior.AllowGet);
// return View();
}
private List<MdaViewModel> GetChildren(List<MDA2> hdList, long PARENT_MDA_ID)
{
return hdList.Where(l => l.PARENT_MDA_ID == PARENT_MDA_ID)
.Select(l => new MdaViewModel
{
MDA_ID = l.MDA_ID,
text = l.MDA_NAME,
MDA_DESCRIPTION = l.MDA_DESCRIPTION,
ORGANIZATION_TYPE = l.ORGANIZATION_TYPE,
PARENT_MDA_ID = l.PARENT_MDA_ID,
children = GetChildren(hdList, l.MDA_ID)
}).ToList();
}
[HttpPost]
public JsonResult ChangeNodePosition(long MDA_ID, long PARENT_MDA_ID)
{
using (BackendEntities context = new BackendEntities())
{
var Hd = context.MDA.First(l => l.MDA_ID == MDA_ID);
Hd.PARENT_MDA_ID = PARENT_MDA_ID;
context.SaveChanges();
}
return this.Json(true, JsonRequestBehavior.AllowGet);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddNewNode(AddNode model)
{
try
{
if (ModelState.IsValid)
{
using (BackendEntities db = new BackendEntities())
{
MDA2 hierarchyDetail = new MDA2()
{
MDA_NAME = model.NodeName,
PARENT_MDA_ID = model.ParentName,
MDA_DESCRIPTION = model.NodeDescription,
ORGANIZATION_TYPE = model.NodeOrganizationType
};
db.MDA.Add(hierarchyDetail);
db.SaveChanges();
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
throw ex;
}
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
The partial view is where the Tree View is created
Partial View
#model BPP.CCSP.Admin.Web.ViewModels.AddNode
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Add Node</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm("AddNewNode", "Mda", FormMethod.Post, new { #id = "formaddNode", #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-12">
<div class="col-md-6 row">
<div class="input-group">
<input type="text" class="form-control" value="Perent Node" readonly="readonly">
<span class="input-group-addon">
#Html.RadioButtonFor(model => model.NodeTypeRbtn, "Pn", new { #class = "btn btn-primary rbtnnodetype" })
</span>
</div>
</div>
<div class="col-md-6">
<div class="input-group ">
<input type="text" class="form-control" value="Child Node" readonly="readonly">
<span class="input-group-addon">
#Html.RadioButtonFor(model => model.NodeTypeRbtn, "Cn", new { #class = "rbtnnodetype" })
</span>
</div>
</div>
<br />
#Html.ValidationMessageFor(m => m.NodeTypeRbtn, "", new { #class = "alert-error" })
</div>
<div class="clearfix">
</div>
<div class="col-md-12">
<div class="petenddiv hidden">
#Html.Label("Select Parent")
#Html.DropDownList("ParentName", new SelectList(ViewBag.plist, "MDA_ID", "MDA_NAME"), "--select--", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.ParentName, "", new { #class = "alert-error" })
</div>
</div>
<div class="clearfix">
</div>
<div class="col-md-12">
<div>
#Html.Label("MDA Name")
#Html.TextBoxFor(model => model.NodeName, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.NodeName, "", new { #class = "alert-error" })
</div>
</div>
<div class="col-md-12">
<div>
#Html.Label("Description")
#Html.TextBoxFor(model => model.NodeDescription, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.NodeDescription, "", new { #class = "alert-error" })
</div>
</div>
<div class="col-md-12">
<div>
#Html.Label("Organization Type")
#Html.DropDownListFor(model => model.NodeOrganizationType, new List<SelectListItem>
{
new SelectListItem{Text = "Agency", Value = "Agency"},
new SelectListItem{Text = "Commission", Value = "Commission"},
new SelectListItem{Text = "Department", Value = "Department"},
new SelectListItem{Text = "Ministry", Value = "Ministry"}
}, "Select Error Type", new { #style = "border-radius:3px;", #type = "text", #class = "form-control", #placeholder = "Enter Organization Type", #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.NodeDescription, "", new { #class = "alert-error" })
</div>
</div>
<div class="clearfix">
</div>
<br />
<br />
<div class="col-md-12">
<div>
<div class="pull-left">
<input type="submit" id="savenode" value="S A V E" class="btn btn-primary" />
</div>
<div class="pull-right">
<input type="button" id="closePopOver" value="C L O S E" class="btn btn-primary" />
</div>
</div>
</div>
<div class="clearfix">
</div>
}
</div>
</div>
View
<div class="col-md-12" style="margin:100px auto;">
<div class="modal fade in" id="modalAddNode" role="dialog" aria-hidden="true">
#Html.Partial("_AddNode")
</div>
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">Ministries, Departments and Agencies -: [ Add MDA and its Members ]</div>
<div class="panel-body">
<div id="tree"></div>
<div class="clearfix">
</div>
<br />
<div>
<button id="btnDeleteNode" data-toggle="modal" class='btn btn-danger'> Delete Node <span class="glyphicon glyphicon-trash"></span> </button>
<button id="btnpopoverAddNode" data-toggle="modal" class='btn btn-warning'> Add Node <span class="glyphicon glyphicon-plus"></span> </button>
</div>
</div>
</div>
</div>
Scipts
#section Scripts {
#System.Web.Optimization.Scripts.Render("~/bundles/jqueryval")
<script src="#Url.Content("~/Scripts/conditional-validation.js")" type="text/javascript"></script>
<script src="~/Scripts/Gijgo/gijgo.js"></script>
<link href="http://code.gijgo.com/1.3.0/css/gijgo.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
//'Hierarchy/GetHierarchy'
$(document).ready(function () {
var Usertree = "";
var tree = "";
$.ajax({
type: 'get',
dataType: 'json',
cache: false,
url: '/Mda/GetHierarchy',
success: function (records, textStatus, jqXHR) {
tree = $('#tree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: true,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
Usertree = $('#Usertree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: false,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
tree.on('nodeDrop', function (e, MDA_ID, PARENT_MDA_ID) {
currentNode = MDA_ID ? tree.getDataById(MDA_ID) : {};
console.log("current Node = " + currentNode);
parentNode = PerentId ? tree.getDataById(PARENT_MDA_ID) : {};
console.log("parent Node = " + parentNode);
if (currentNode.PARENT_MDA_ID === null && parentNode.PARENT_MDA_ID === null) {
alert("Parent node is not droppable..!!");
return false;
}
// console.log(parent.HierarchyLevel);
var params = { MDA_ID: MDA_ID, PARENT_MDA_ID: PARENT_MDA_ID };
$.ajax({
type: "POST",
url: "/Mda/ChangeNodePosition",
data: params,
dataType: "json",
success: function (data) {
$.ajax({
type: "Get",
url: "/Mda/GetHierarchy",
dataType: "json",
success: function (records) {
Usertree.destroy();
Usertree = $('#Usertree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: false,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
}
});
}
});
});
$('#btnGetValue').click(function (e) {
var result = Usertree.getCheckedNodes();
if (result == "") { alert("Please Select Node..!!") }
else {
alert("Selected Node id is= " + result.join());
}
});
//delete node
$('#btnDeleteNode').click(function (e) {
e.preventDefault();
var result = tree.getCheckedNodes();
if (result != "") {
$.ajax({
type: "POST",
url: "/Mda/DeleteNode",
data: { values: result.toString() },
dataType: "json",
success: function (data) {
alert("Deleted successfully ");
window.location.reload();
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
},
});
}
else {
alert("Please select Node to delete..!!");
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
// show model popup to add new node in Tree
$('#btnpopoverAddNode').click(function (e) {
e.preventDefault();
$("#modalAddNode").modal("show");
});
//Save data from PopUp
$(document).on("click", "#savenode", function (event) {
event.preventDefault();
$.validator.unobtrusive.parse($('#formaddNode'));
$('#formaddNode').validate();
if ($('#formaddNode').valid()) {
var formdata = $('#formaddNode').serialize();
// alert(formdata);
$.ajax({
type: "POST",
url: "/Mda/AddNewNode",
dataType: "json",
data: formdata,
success: function (response) {
// $("#modalAddNode").modal("hide");
window.location.reload();
},
error: function (response) {
alert('Exception found');
// $("#modalAddNode").modal("hide");
window.location.reload();
},
complete: function () {
// $('.ajax-loader').css("visibility", "hidden");
}
});
}
});
//Close PopUp
$(document).on("click", "#closePopup", function (e) {
e.preventDefault();
$("#modalAddNode").modal("hide");
});
$('.rbtnnodetype').click(function (e) {
if ($(this).val() == "Pn") {
$('.petenddiv').attr("class", "petenddiv hidden");
$("#ParentName").val("");
}
else {
$('.petenddiv').attr("class", "petenddiv");
}
});
});
</script>
}
As shown above, what I have created can only do one level node. I want want to create multi-level.Whereby, a child will be a parent to other children.
Please how do I achieve this.
You can see some ASP.NET examples about this at https://github.com/atatanasov/gijgo-asp-net-examples/tree/master/Gijgo.Asp.NET.Examples
Please use our examples in order to achieve that.

How to pass selected files in Kendo Upload as parameter in ajax request

After much of struggle im posing this question. Im using a Kendo Upload on a page. Am able to post the selected files on the asyn mode with whe the page has Html.BeginForm. But I'm not able to send file details as HttpPostedFileBase when I use ajax request to send data to the controller.
Following is my html
<form class="form-horizontal" role="form">
<div class="form-group">
#Html.Label("Complaint Name", new { #class = "col-sm-3 control-label" })
<div class="col-sm-4">
#Html.TextBoxFor(
m => m.ComplaintName,
new
{
#TabIndex = "1",
#class = "form-control input-sm",
disabled = true
})
</div>
</div>
<div class="form-group">
#Html.Label("Complaint Details", new { #class = "col-sm-3 control-label" })
<div class="col-sm-4">
#Html.TextBoxFor(
m => m.ComplaintDetails,
new
{
#TabIndex = "2",
#class = "form-control input-sm",
disabled = true
})
</div>
</div>
<div class="form-group">
#Html.Label("Choose files to upload", new { #class = "col-sm-3 control-label" })
<div class="col-sm-9 nopaddingforTextArea">
<input name="files" id="files" type="file" />
</div>
</div>
<div class="form-group">
<div>
<input id="btnSubmit" class="btn btn-primary pull-right" type="button" />
</div>
</div>
</form>
Following is my action
public ActionResult SaveComplaintDetails(string complaintName, string complaintDetails, IEnumerable<HttpPostedFileBase> files)
{
}
Following is my js
$("#files").kendoUpload({
async: {
saveUrl: '#Url.Action("EsuperfundCommentsBind", ClientInboxConstants.NewQuery)',
autoUpload: false
},
multiple: true
});
$("#btnSubmit").click(function () {
//Ajax call from the server side
$.ajax({
//The Url action is for the Method FilterTable and the Controller PensionApplicationList
url: '#Url.Action("SaveComplaintDetails", "Complaints")',
//The text from the drop down and the corresponding flag are passed.
//Flag represents the Index of the value in the dropdown
data: {
complaintName: document.getElementById("ComplaintName").value,
complaintDetails: document.getElementById("ComplaintDetails").value,
files: //What to pass here??
},
contentType: "application/json; charset=utf-8",
//Json data
datatype: 'json',
//Specify if the method is GET or POST
type: 'GET',
//Error function gets called if there is an error in the ajax request
error: function () {
},
//Gets called on success of the Ajax Call
success: function (data) {
}
});
});
My question is how to pass the selected files in Kendo Upload in ajax as a parameter?
Any help in this aspect would be really appreciated.
If your view is based on a model and you have generated the controls inside <form> tags, then you can serialize the model to FormData using:
<script>
var formdata = new FormData($('form').get(0));
</script>
This will also include any files generated with: <input type="file" name="myImage" .../> and post it back using:
<script>
$.ajax({
url: '#Url.Action("YourActionName", "YourControllerName")',
type: 'POST',
data: formdata,
processData: false,
contentType: false,
});
</script>
and in your controller:
[HttpPost]
public ActionResult YourActionName(YourModelType model)
{
}
or (if your model does not include a property for HttpPostedFileBase)
[HttpPost]
public ActionResult YourActionName(YourModelType model,
HttpPostedFileBase myImage)
{
}
If you want to add additional information that is not in the form, then you can append it using
<script>
formdata.append('someProperty', 'SomeValue');
</script>
**Example Usage :**
View :
#using (Html.BeginForm("Create", "Issue", FormMethod.Post,
new { id = "frmCreate", enctype = "multipart/form-data" }))
{
#Html.LabelFor(m => m.FileAttachments, new { #class = "editor-label" })
#(Html.Kendo().Upload()
.HtmlAttributes(new { #class = "editor-field" })
.Name("files")
)
}
<script>
$(function () {
$('form').submit(function (event) {
event.preventDefault();
var formdata = new FormData($('#frmCreate').get(0));
$.ajax({
type: "POST",
url: '#Url.Action("Create", "Issue")',
data: formdata,
dataType: "json",
processData: false,
contentType: false,
success: function (response) {
//code omitted for brevity
}
});
});
});
</script>
*Controller :*
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] Model viewModel, IEnumerable<HttpPostedFileBase> files)
{
//code omitted for brevity
return Json(new { success = false, message = "Max. file size 10MB" }, JsonRequestBehavior.AllowGet);
}
<script>
$(function () {
$('form').submit(function (event) {
event.preventDefault();
var formdata = new FormData($('#createDetail').get(0));
$.ajax(
{
type: 'POST',
url: '#Url.Action("Detail_Create", "Product")',
data: formdata,
processData: false,
success: function (result) {
if (result.success == false) {
$("#divErr").html(result.responseText);
} else {
parent.$('#CreateWindowDetail').data('kendoWindow').close();
}
},
error: function (xhr, ajaxOptions, thrownError) {
$("#divErr").html(xhr.responseText);
}
});
});
});
#using (Html.BeginForm("Detail_Create", "Product", FormMethod.Post, new { id = "createDetail", enctype="multipart/form-data"}))
{
<div id="divErr" class="validation-summary-errors"></div>
<fieldset>
<ol>
<li>
#Html.LabelFor(m => m.Price)
#(Html.Kendo().NumericTextBoxFor(m => m.Price).Name("Price").Format("{0:0}")
.HtmlAttributes(new { style = "width:100%" })
)
</li>
<li>
#Html.LabelFor(m => m.Description)
#Html.TextBoxFor(model => model.Description, new { #class = "k-textbox", id = "Description", style = "width:100%;" })
</li>
<li>
#Html.LabelFor(m => m.Group)
#(Html.Kendo().ComboBox()
.Name("Group")
.Placeholder("Введите группу детали")
.DataTextField("Name")
.DataValueField("Id")
.HtmlAttributes(new { style = "width:100%;" })
.Filter("contains")
.MinLength(1)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Group_Read_ComboBox", "Product");
})
.ServerFiltering(true);
})
)
</li>
<li>
#Html.LabelFor(m => m.Image)
#(Html.Kendo().Upload()
.Name("files")
)
</li>
</ol>
</fieldset>
<button type="submit" id="get" class="k-button">Добавить</button>
}
[HttpPost]
public ActionResult Detail_Create(DetailModel model, IEnumerable<HttpPostedFileBase> files)
{
string error = string.Empty;
if (ModelState.IsValid)
{
.....
}
IEnumerable<System.Web.Mvc.ModelError> modelerrors = ModelState.SelectMany(r => r.Value.Errors);
foreach (var modelerror in modelerrors)
{
error += "• " + modelerror.ErrorMessage + "<br>";
}
return Json(new { success = false, responseText = error }, JsonRequestBehavior.AllowGet);
}
after pressing the button, the controller null comes to how to fix. 2 days already sitting, and the time comes to an end

Automatically update viewModel after save to db

What I want to achieve is once the data got saved into database, when it goes back to client, it will automatically update the observable array. But somehow I couldn't make it happen.
This is my Server side code:
[HttpGet]
public JsonResult GetTasks()
{
var tasks = context.ToDoTasks.ToList();
return Json(tasks.Select(c => new TaskViewModel(c)).ToList(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult AddTask(string text, string date)
{
var nTask = new ToDoTask()
{
Text = text,
Date = DateTime.ParseExact(date, "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture),
IsDone = false,
Order = 1,
};
context.ToDoTasks.Add(nTask);
context.SaveChanges();
return Json(new TaskViewModel(nTask), JsonRequestBehavior.AllowGet);
}
This is my cshtml file code:
<form>
<div class="controls controls-row" style="margin-top:40px;">
<input class="span7" type="text" placeholder="Task to do" style="margin-right:4px;" id="oText">
<div id="task-date" class="input-append date">
<input data-format="MM/dd/yyyy" type="text" placeholder="MM/dd/yyyy" name="taskDate" id="oDate" />
<span class="add-on">
<i data-time-icon="icon-time" data-date-icon="icon-calendar">
</i>
</span>
</div>
<button class="btn" type="submit" style="margin-top:-10px;" data-bind="click: save">+</button>
</div>
<div class="controls">
<label class="checkbox">
<input type="checkbox"> Mark all as complete
</label>
</div>
<div id="task-section" style="margin-top:20px;">
<ul data-bind="foreach: Tasks">
<!-- ko if: IsDone -->
<li>
<span><input type="checkbox" style="margin:-5px 5px 0px 0px;" data-bind="checked: IsDone" /></span>
<del><span data-bind="text: Text"></span></del>
<del><span class="task-date" data-bind="text: Date"></span></del>
</li>
<!-- /ko -->
<!-- ko ifnot: IsDone -->
<li>
<span><input type="checkbox" style="margin:-5px 5px 0px 0px;" data-bind="checked: IsDone" /></span>
<span data-bind="text: Text"></span>
<span class="task-date" data-bind="text: Date"></span>
</li>
<!-- /ko -->
</ul>
</div>
<div class="clearfix" style="margin-top:30px;">
<span class="pull-left" style="font-weight:bold;"><span data-bind="text: oItemLeft"></span> item left</span>
<span class="pull-right badge" style="cursor:pointer;" data-bind="click: remove">Clear # completed item</span>
</div>
</form>
And finally my JS:
var ViewModel = function (data) {
var self = this;
self.Tasks = ko.mapping.fromJS(data, {}, self.Tasks);
self.oItemLeft = ko.computed(function () {
var i = 0;
data.forEach(function (entry) {
if (!entry.IsDone) i++;
});
return i;
});
self.save = function () {
$.ajax({
url: "Home/AddTask",
type: "POST",
data: { text: $('#oText').val(), date: $('#oDate').val() },
success: function (response) {
ko.mapping.fromJS(response, ViewModel);
}
});
};
self.remove = function () {
alert('delete');
}
}
$(function () {
$.getJSON("/Home/GetTasks/", null, function (data) {
ko.applyBindings(new ViewModel(data));
});
// for datepicker
$('#task-date').datetimepicker({
language: 'pt-BR',
pickTime: false
});
});
self.save = function () {
$.ajax({
url: "Home/AddTask",
type: "POST",
data: { text: $('#oText').val(), date: $('#oDate').val() },
success: function (response) {
var task = ko.mapping.fromJS(response);
self.Tasks.push(task);
}
});
};
Also for oItemLeft you should be referring to self.Tasks instead of data:
self.oItemLeft = ko.computed(function () {
var i = 0;
self.Tasks().forEach(function (entry) {
if (!entry.IsDone) i++;
});
return i;
});

Knockout checkbox binding, with autoupdate

I am trying to when a person changes the state of previously bound checkbox, I want to update the server with the new value.
So here is what I have:
JSCRIPT
function JobViewModel() {
var self = this;
var baseUri = '/Api/Pedidos/';
self.TotalItems = ko.observable(#Model.TotalItems);
self.AbreviaNome = ko.observable(#Model.AbreviaNome.ToString().ToLower());
self.AbreviaFantasia = ko.observable(#Model.AbreviaFantasia.ToString().ToLower());
self.update = function () {
alert('Boom');
$.ajax({
type: "PUT",
url: baseUri,
data: self.Job,
datatype: "json",
contenttype: "application/json"
})
.done(function (data) {
//handleSuccessFunctionHERE(data);
alert('Magic');
})
.error(function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
alert("fail");
});
};
}
function JobDetailsViewModel() {
var self = this;
var baseUri = '/Api/Pedidos/';
self.Job = new JobViewModel();
}
HTML
<label class="btn btn-primary" data-bind="css: {active:Job.AbreviaNome }">
<input type="checkbox" data-bind="checked: AbreviaNome , onchange: Job.update" name="type" id="AbreviaNome "> Nome</input>
</label>
This never triggers the update function. I also have tried :
<label class="btn btn-primary" data-bind="css: {active:Job.AbreviaNome }">
<input type="checkbox" data-bind="checked: AbreviaNome , click: Job.update" name="type" id="AbreviaNome "> Nome</input>
</label>
And this within the JobViewModel:
this.AbreviaNome.subscribe(function (newValue) {
alert('test');
}, this);
Any ideas?
You should use subscribe for this and not the onchange handler. You mentioned you tried it, but you subscribed to AbreviaNome instead of AbreviaLogradouro.
Solved the problem, below is the binding:
<label class="btn btn-primary " data-bind="css: {active:Job.AbreviaNome}">
<input type="checkbox" data-bind="checked: Job.AbreviaNome, event: {change: Job.update}" name="type" id="AbreviaNome">Nome/Razão</input>
</label>
Not sure this was the best way but it works.

Resources