PDF in MVC using Kendo Grid - asp.net-mvc

I am using Kendo grid. In that grid first column is hyperlink column. If I click on each hyperlink, then the selected text of the hyperlink should be passed to the controller action. That hyperlink text is actually a pdf file name. So if a file name is is clicked on the grid ,then the same file should be opened in a tag is same page itself. Both the grid and tag to view PDf are in same page. How to do this?
Kendo grid: // This grid will be in Home.cshtml and also I splitted this into two . one will have this grid floating left and other will floating right with as follows
<object data=#url.action("GetPdf")></object>
#(Html.Kendo().Grid<Cutomers.Model.CustomerDataModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.FileName).ClientTemplate( "/#= FileName #" );
columns.Bound(c => c.CreatedDate).Width(70);
columns.Bound(c => c.CreatedBy).Width(70);
})
.HtmlAttributes(new { style = "height: 350px;" })
.Scrollable()
.Groupable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(1))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Customers_Read", "Home"))
)
)
My controller:
public FileStreamResult GetPDF()
{
FileStream fs = new FileStream("D:/pdfSample.pdf", FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
}

*************************Grid***************************
#(Html.Kendo().Grid<SearchEmailHistoryGridModel>()
.Name("EmailSearchGrid")
.Columns(columns =>
{
columns.Bound(p => p.ExtractId).Visible(false);
columns.Bound(p => p.FileName).Title("File Name");
columns.Bound(p => p.TemplateName).Title("Template");
columns.Bound(p => p.CentreName).Title("Centre");
columns.Bound(p => p.LeaseId).Title("Lease ID");
columns.Bound(p => p.Unit).Title("Unit").Width("80px");
columns.Bound(p => p.Occupant).Title("Occupant");
columns.Bound(p => p.ContactName).Title("Contact");
columns.Bound(p => p.Attachment).Title("Attachment").ClientTemplate("# if(data.Attachment!=null) {# <div style='cursor: hand;'><a class='gridLink' href='\\#' id='slpitLink' title='Download #:Attachment#' onclick=\"DownloadFile(#:ExtractId#,'#:FileName#','#:Attachment#'); return false;\">View</a></div> #}#");
columns.Bound(p => p.EmailAddress).Title("Email").Width("150px");
columns.Bound(p => p.EmailSent).Title("Email Sent").Visible(false);
columns.Bound(p => p.FirstSentDate).Title("Date Sent").Width("85px");
columns.Bound(p => p.SentBy).Title("Sent By").Width("85px");
columns.Bound(p => p.Delivered).Title("Delivered").Width("85px");
columns.Bound(p => p.Read).Title("Read").Width("70px");
columns.Bound(p => p.Exception).Title("Error").ClientTemplate("# if(data.Exception=='Yes') {# <a style='color:\\#94BB27; text-decoration:none; cursor:help' title='#:data.ExceptionDescription#'>Yes</a> #} else {# <label>No</label> #}#").Width("60px");
columns.Command(command =>
{
command.Custom("Resend").Click("ResendEmail").HtmlAttributes(new { title = "Resend Email" });
command.Custom("Forward").Click("SendForwardEmail").HtmlAttributes(new { title = "Forward Email" });
}).Title("Action");
})
.Events(e => e.DataBound("onEmailSearchDataBound"))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.PageSizes(new int[] { 5, 10, 20,50 })
.ButtonCount(5)
)
.Filterable()
.Scrollable()
.HtmlAttributes(new { style = "height:650px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(c => c.ExtractId);
})
.Read(read => read.Action("ReadEmailHistory", "EmailManagement").Data("GetSearchFilterData"))
)
)
*******************************Script***********************************
//Download File
function DownloadFile(extractId,folder,fileNameParam) {
$.post('#Url.Action("DownloadFile", "Correspondence")', { extractId: extractId, folder: folder, fileName: fileNameParam })
.done(function (data) {
if (data.url == null) {
showMessage(data);
}
else {
$("body").append("<iframe src='" + data.url + "' style='display: none;'></iframe>");
}
});
}
**********************************Controller****************************
//Download File
[HttpPost]
[FilterSessionExpire]
public ActionResult DownloadFile(int extractId,string folder, string fileName)
{
var filePath = Path.Combine(ConfigurationManager.AppSettings["EcorsSplitFilePath"],folder, fileName); //in folder level
if (System.IO.File.Exists(filePath))
{
//return file link
return Json(new { url = Url.Action("DownloadFileActual", "Correspondence", new { folder = folder, fileName = fileName }) }, JsonRequestBehavior.AllowGet);
}
//else return error
return Json("File:" + fileName + " Not found.", JsonRequestBehavior.AllowGet);
}
//Actual Download File
public ActionResult DownloadFileActual(string folder, string fileName)
{
const string contentType = "application/pdf";
var filePath = Path.Combine(ConfigurationManager.AppSettings["EcorsSplitFilePath"], folder, fileName); //in folder level
return File(filePath, contentType, fileName);
}

Related

Kendo grid delete button passing the details of the row

I have a kendo grid in which I want to form delete button to pass the details of the row to the controller (as I am using mvc). Then I will use these details to delete the row from the database.
I searched in kendo website and I found the part for the delete or destroy call but I don't know how to pass these details of the row to the controller.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("Grid")
.Columns(columns => {
columns.Bound(p => p.ProductName);
columns.Bound(p => p.UnitPrice).Width(140);
columns.Bound(p => p.UnitsInStock).Width(140);
columns.Bound(p => p.Discontinued).Width(100);
columns.Command(command => command.Destroy()).Width(110);
})
.ToolBar(toolbar => {
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ProductID))
.Create("Editing_Create", "Grid")
.Read("Editing_Read", "Grid")
.Update("Editing_Update", "Grid")
.Destroy("Editing_Destroy", "Grid")
)
)
My grid:
<div id="grid">
#(Html.Kendo().Grid<dynamic>()
.Name("BrowseGrid")
.Columns(columns =>
{
foreach (System.Data.DataColumn c in Model.Grid.Columns)
{
columns.Bound(c.ColumnName).EditorTemplateName("String");
}
columns.Command(command =>
{
command.Destroy();
command.Custom("").Text("editteam").HtmlAttributes(new { id = "editteam", onClick = "editRow()" });
});
})
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model =>
{
//Define the model
foreach (System.Data.DataColumn column in Model.Grid.Columns)
{
model.Field(column.ColumnName, column.DataType);
model.Id("Id");
}
})
.Read(read =>
read.Action("BrowseGrid", "Configuration")
)
.Destroy( update => update.Action("Delete", "Configuration"))
//Data("{nodeID:"+#Model.nodeID+"}"
)
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new int[] { 10, 100, 1000, 10000, 100000, 1000000 })
.ButtonCount(10)
)
)
Please change to:
.Destroy(update => update.Action("Process_Destroy", "controller name"))
and in controller,
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Process_Destroy([DataSourceRequest] DataSourceRequest request, ProductViewModel product)
{
if (product != null)
{
//write your code for delete action;
}
return Json(ModelState.ToDataSourceResult());
}
This will work.
I am assuming you only need the id of the row to delete it, but I think you can send the full model of the selected row. I am sending both.
Like this:
.Destroy(d => d.Action("controllerMethod", "controllerName").Data("jsFunction"))
And in javascript:
function jsFunction() {
var grid = $("#BrowseGrid").data("kendoGrid");
var id = grid.dataItem(grid.select()).Id;
return {
id: id
};
}
Your controller method should receive the parameter:
public ActionResult controllerMethod(string id)

Customizing Grid of Kendo UI

By default grid of Kendo shows values of columns but I'd like to customize it. For example I want to show an icon for each value of one column.
I have a column in my grid that shows the status of activation or inactivation.Instead of showing "true" or "false", I want to show an icon that is proper for it.
I've used ".Template()" in grid but my code in ".Template" did not fire!
How can I solve this problem?
<div style="width: 100%;">
#(Html.Kendo().Grid<Jahan.Blog.Model.Article>()
.Name("ArticleAdmin").Navigatable()
.Resizable(c => c.Columns(true))
.HtmlAttributes(new { #class = "cursorLink", #style = "width: 1000px;height:auto;overflow: scroll;" })
.Columns(columns =>
{
columns.Bound(p => p.UserId).Width(100);
columns.Bound(p => p.Title).Width(200);
//columns.Bound(p => p.Summary).Width(140);
//columns.Bound(p => p.Description).Width(100);
columns.Bound(p => p.LikeCounter).Width(100);
columns.Bound(p => p.RateCounter).Width(100);
// Please attention to this
columns.Bound(p => p.IsActive).Template(p => #Html.ShowIcon(p.IsActive)).Width(80);
columns.Bound(p => p.IsActiveNewComment).Width(170);
columns.Bound(p => p.CreatedDate).Width(160).Format("{0:G}");
columns.Bound(p => p.ModifiedDate).Width(160).Format("{0:G}");
columns.Command(command => command.Destroy()).Width(170);
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.Id))
.Create("Editing_Create", "ArticleAdmin")
.Read("Editing_Read", "ArticleAdmin")
.Update("Editing_Update", "ArticleAdmin")
.Destroy("Editing_Destroy", "ArticleAdmin")
))
</div>
Please attention to this part of my code:
columns.Bound(p => p.IsActive).Template(p => #Html.ShowIcon(p.IsActive)).Width(80);
and
public static MvcHtmlString ShowIcon(this HtmlHelper html, bool isActive, string text = "", string activeCssClass = "glyphicon glyphicon-ok", string inactiveCssClass = "glyphicon glyphicon-remove")
{
StringBuilder result = new StringBuilder();
TagBuilder span = new TagBuilder("span");
span.SetInnerText(text);
if (isActive)
{
span.AddCssClass(activeCssClass);
}
else
{
span.AddCssClass(inactiveCssClass);
}
result.Append(span);
return MvcHtmlString.Create(result.ToString());
}
You can do this with a ClientTemplate as follows:
columns.Bound(p => p.IsActive)
.ClientTemplate("<img src='/Content/#= IsActive ? 'tick.png' : 'cross.png' #''>");
The above simply checks the IsActive property and displays a tick or cross image.
columns.Bound(p => p.IsActive).ClientTemplate("#= showIcon(IsActive) #").Width(80);
JavaScript function:
function showIcon(isActive) {
var result = "";
if (isActive == true) {
result = "<img src='/Content/tick.png'/>";
} else {
result = "<img src='/Content/cross.png'/>";
}
return result;
}
for more information click How do I use a JavaScript function in a column client template?

How to only update a row in Telerik MVC grid without refreshing the grid data?

From the samples and documentation, it looks like if I want to update one row (or do a batch update) in a Telerik grid, I also need to refresh the data in the entire grid.
Is there a way to just update that one row on the client and not return all the grid data every time I want to do an update? It seems extremely wasteful to keep returning that much data every time.
Even if I do a batch update, why do I need to return all the new data?
Generally a database has many users, and your user interface may be accessed by multiple people. If the grid is going to update, then it will include any other changes that may have happened to the data since the grid originally loaded.
The grid allows you to limit the number of records that are shown at a time via the paging option. On our project we are loading the grid with AJAX, and using IQueryable's in the controller. When we call ToDataSourceResult(request) on the IQueryable, it only retrieves the data that is needed, and does not load the full table from the database.
On the Razor View:
#(Html.Kendo().Grid<WebApp.ViewModels.AccountViewModel>()
.Name("Accounts")
.Columns(columns =>
{
columns.Bound(c => c.AccountNumber);
columns.Bound(c => c.Name);
columns.Bound(c => c.Address1);
columns.Bound(c => c.Address2);
columns.Bound(c => c.City);
columns.Bound(c => c.State);
columns.Bound(c => c.Zip);
columns.Bound(c => c.PrimaryContact).Title("Contact");
})
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains("Contains")
.DoesNotContain("Doesn't Contain")
)
)
)
.Groupable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new int[] { 5, 10, 20, 50, 100, 500 })
.ButtonCount(5)
)
.DataSource(dataSource => dataSource
.Ajax()
.Sort(sort => sort.Add("Name").Ascending())
.PageSize(20)
.Read(read => read.Action("Account_Read", "Account"))
)
)
Then in the controller:
public ActionResult Account_Read([DataSourceRequest] DataSourceRequest request)
{
var jsonlist = GetAccounts()
.Select(sa => new AccountViewModel
{
ID = sa.ID,
AccountNumber = sa.AccountNumber,
Name = sa.Name,
Address1 = sa.Address1,
Address2 = sa.Address2,
City = sa.City,
State = sa.State,
Zip = sa.Zip,
PrimaryContact = sa.User.FirstName + " " + sa.User.LastName
}
).ToDataSourceResult(request);
return Json(jsonlist);
}
UPDATE
We have an inline edit form on one of our Kendo grids. It took us a bit to get it how we watned. In the Razor View:
#(Html.Kendo().Grid<DataViewModel>()
.Name("Data")
.Columns(columns =>
{
columns.Bound(c => c.FieldName)
.EditorTemplateName("DataFieldName")
.Title("Item Name")
.Width(200);
columns.Bound(c => c.TextValue)
.Title("Text");
columns.Command(command => { command.Edit(); command.Destroy(); })
.Title("Actions")
.Width(172);
})
.Filterable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new int[] { 5, 10, 20, 50, 100 })
.ButtonCount(5)
)
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Sort(sort => sort.Add("CreatedDate").Descending())
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(pd => pd.ID);
model.Field(pd => pd.CreatedDate).Editable(false);
model.Field(pd => pd.ValuesID).DefaultValue(Model.Values.ID);
})
.Read(read => read.Action("Data_Read", "History", new { ValuesID = Model.Values.ID }))
.Create(update => update.Action("Data_Create", "History"))
.Update(update => update.Action("Data_Update", "History"))
.Destroy(update => update.Action("Data_Destroy", "History"))
)
)
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
</script>
In order to use the Kendo date time picker for the date option, we had to create a custom editor template. We created a new folder under Views >> Shared >> EditorTemplates. The file name is DataFieldName.cshtml:
#model WebApp.ViewModels.DataViewModel
#using WebApp.ViewModels
#(Html.Kendo().ComboBox()
.Name("FieldName")
.Placeholder("Select/Create Item Name")
.DataTextField("Name")
.DataValueField("Name")
.Filter(FilterType.Contains)
.DataSource(source => source
.Read(read => read.Action("GetFieldNames", "History"))
)
)
Then the controller has all of the action results for the AJAX calls:
[HttpPost]
public ActionResult Data_Create(DataViewModel DataIn)
{
var Data = new Data();
Data.ValuesID = DataIn.ValuesID;
Data.FieldName = DataIn.FieldName;
Data.TextValue = DataIn.TextValue;
if (DataIn.TimeValue != null) Data.TimeValue = DataIn.TimeValue;
if (ModelState.IsValid)
{
db.Datas.Add(Data);
db.SaveChanges();
}
return RedirectToAction("EditValue", new
{
ValueID = DataIn.ValuesID,
tankID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).TankID
});
}
[HttpPost]
public ActionResult Data_Update(DataViewModel DataIn)
{
var Data = db.Datas.Find(DataIn.ID);
Data.FieldName = DataIn.FieldName;
Data.TextValue = DataIn.TextValue;
if (DataIn.TimeValue != null) Data.TimeValue = DataIn.TimeValue;
if (ModelState.IsValid)
{
db.Entry(Data).State = EntityState.Modified;
db.SaveChanges();
}
return RedirectToAction("EditValue", new
{
ValueID = DataIn.ValuesID,
tkID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).tkID
});
}
[HttpPost]
public ActionResult Data_Destroy(DataViewModel DataIn)
{
var Data = db.Datas.Find(DataIn.ID);
db.Datas.Remove(Data);
db.SaveChanges();
return RedirectToAction("EditValue", new
{
ValueID = DataIn.ValuesID,
tkID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).tkID
});
}
public ActionResult GetFieldNames()
{
var jsonList = db.Datas
.Select(pd => new
{
Name = pd.FieldName
})
.Distinct()
.OrderBy(pd => pd.Name)
.ToList();
return Json(jsonList, JsonRequestBehavior.AllowGet);
}

Asp.Net MVC KendoUI grid

#(Html.Kendo().Grid<RTM.WEB.MVC.ViewModels.SortingViewModel.ProductViewModel>()
.Name("ProductsGrid").HtmlAttributes("height:430")
.Columns(columns =>
{
columns.Bound(p => p.IsSelected).Width(50).Title("");
columns.Bound(p => p.ProductName);
columns.Bound(p => p.Price).Format("{0:C}");
columns.Bound(p => p.GroupName);
// columns.Bound(p => p.MeasurementId);
// columns.Bound(p => p.BarcodeValue);
columns.Command(comand =>
{
comand.Custom("Edit").Click("ViewEdit");
comand.Destroy();
}).Title("Commands").Width(180);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
//.Events(events=>events.Sync("addGroupData"))
.ServerOperation(true)
.Batch(true)
.Events(events =>
{
events.Error("errorHandler");
events.Sync("addDataToResponce");
})
.Model(model =>
{
model.Id(p => p.ProductId);
model.Field(p => p.ProductId).Editable(false);
})
// .Aggregates(aggregates =>
//{
// //aggregates.Add(p => p.ProductId);
// //aggregates.Add(p => p.ProductName);
// aggregates.Add(p => p.Price).Sum();
//})
.Group(groups => groups.Add(p => p.GroupName))
.Create(create => create.Action("Products_Create", "Sorting"))
.Read(read => read.Action("Products_Read", "Sorting"))
.Update(update => update.Action("Products_Update", "Sorting"))
.Destroy(destroy => destroy.Action("Products_Destroy", "Sorting"))
)
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div >
<a class="k-button" onclick="AddProduct()">Add New Product</a>
#item.SaveButton()
<a class="k-button" onclick="NewGroup()">NewGroup</a>
<a class="k-button" onclick="UnGroup()">UnGroup</a>
<label>Show products by warehouse:</label>
#(Html.Kendo().DropDownList()
.Name("warehouses")
.OptionLabel("All")
.DataTextField("Name")
.DataValueField("WarehouseId")
.AutoBind(false)
// .Events(e => e.Change("warehousesChange"))
.DataSource(ds =>
{
ds.Read("Products_Warehouses", "Sorting");
})
)
</div>
</text>);
})
.Events(events =>
{
events.DataBound("dataBound");
})
.Pageable(page => page.PageSizes(true).Numeric(false).Refresh(true).Input(true))
//.Navigatable()
.Selectable()
.ColumnMenu()
.Filterable()
.Sortable()
.Scrollable()
.Editable(editable => editable.Mode(GridEditMode.InCell).DisplayDeleteConfirmation(false))
)
public JsonResult Products_Read([DataSourceRequest]DataSourceRequest request)
{
int allcount=0;
List<ProductModel> products= DataManager.ProductRepository.GetAllProducts(request.Page, request.PageSize,ref allcount);
List<ProductViewModel> productViewModels=new List<ProductViewModel>();
foreach (var product in products)
{
productViewModels.Add(ConvertProductViewModel(product));
}
if (request.Sorts.Count != 0)
{
string member = request.Sorts.First().Member;
string sorttype = request.Sorts.First().SortDirection.ToString();
switch (member)
{
case "IsSelected":
if (sorttype == "Ascending")
{
productViewModels = productViewModels.OrderBy(p => p.IsSelected).ToList();
}
if (sorttype == "Descending")
{
productViewModels = productViewModels.OrderByDescending(p => p.IsSelected).ToList();
}
break;
case "ProductName":
if (sorttype == "Ascending")
{
productViewModels = productViewModels.OrderBy(p => p.ProductName).ToList();
}
if (sorttype == "Descending")
{
productViewModels = productViewModels.OrderByDescending(p => p.ProductName).ToList();
}
break;
case "Price":
if (sorttype == "Ascending")
{
productViewModels = productViewModels.OrderBy(p => p.Price).ToList();
}
if (sorttype == "Descending")
{
productViewModels = productViewModels.OrderByDescending(p => p.Price).ToList();
}
break;
}
}
var result = new DataSourceResult()
{
Data = productViewModels,
Total = allcount,
AggregateResults = null,
Errors = null,
};
return Json(result, JsonRequestBehavior.AllowGet);
}
This is my code.When i return data from action server paging doesn't work.
I want do server paging kendo ui group grid, but response data type undefined.I need working example for group grid.It works in basic grid but don't work for group grid.
You should just need to update the controller method. As the sorting you are doing seems quite basic, you can use the supplied Kendo method ToDataSourceResult(DataSourceRequest request).
Add the following to your using section in the Controller:
using Kendo.Mvc.Extensions;
Then simply return:
return Json(productViewModels
.ToDataSourceResult(request, JsonRequestBehavior.AllowGet));
This should take care of any filtering, sorting, grouping, and paging for you.
You might also want to take a look at AutoMapper to more easily map objects from Product to ProductViewModel.

MVC Model Binding does not work on Kendo Grid

In an MVC project i have the following view where i use the Kendo Grid
<%: Html.Kendo().Grid<Milestone>()
.Name("MilestonesGrid")
.Columns(columns =>
{
columns.Bound(p => p.ContractMilestoneID).Hidden();
columns.Bound(p => p.MilestoneSN).Title("Κωδικός οροσήμου");
columns.Bound(p => p.EstimatedDate).Title("Εκτιμώμενη ημερομηνία");
columns.Bound(p => p.RealDate).Title("Πραγματική ημερομηνία");
columns.Bound(p => p.MilestoneDescription).Title("Περιγραφή");
columns.Bound(p => p.Payment).Title("Πληρωμή");
columns.Bound(p => p.PaymentRate).Title("Ποσοστό πληρωμής");
columns.Bound(p => p.IsCompleted).Title("Έχει ολοκληρωθεί");
columns.Command(command =>
{
command.Edit()
.Text("Επεξεργασία")
.CancelText("Ακύρωση")
.UpdateText("Αποθήκευση");
command.Destroy()
.Text("Διαγραφή");
});
})
.ToolBar(toolbar => toolbar.Create().Text("Προσθήκη νέου οροσήμου"))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Sortable()
.Pageable()
.Filterable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.Model(model => model.Id(o => o.ContractMilestoneID))
.Model(model => model.Field(o => o.MilestoneSN))
.Model(model => model.Field(o => o.EstimatedDate))
.Model(model => model.Field(o => o.RealDate))
.Model(model => model.Field(o => o.MilestoneDescription))
.Model(model => model.Field(o => o.Payment))
.Model(model => model.Field(o => o.PaymentRate))
.Model(model => model.Field(o => o.IsCompleted))
.Batch(true)
.Create(create => create.Action("CreateMilestone", "Milestones"))
.Read(read => read.Action("DetailsJson", "Milestones",
new { id = ViewBag.ID }))
.Update(update => update.Action("UpdateMilestone", "Milestones"))
.Destroy(delete => delete.Action("DeleteMilestone", "Milestones")))
%>
Also i have a controller where i want to save a new entry in the Kendo Grid.
[HttpPost]
public ActionResult CreateMilestone([DataSourceRequest] DataSourceRequest request,
Milestone milestone)
{
if (milestone != null && ModelState.IsValid)
{
using (TADCEntities database = new TADCEntities())
{
tblSymvaseisOrosima item = new tblSymvaseisOrosima
{
fldEstimatedDate = milestone.EstimatedDate,
fldIsCompleted = milestone.IsCompleted,
fldMilestoneDescription = milestone.MilestoneDescription,
fldMilestoneSN = milestone.MilestoneSN,
fldPayment = milestone.Payment,
fldPaymentRate = milestone.PaymentRate,
fldRealDate = milestone.RealDate,
fldStoixeioYpoergouID = milestone.ElementSubProjectID
};
database.tblSymvaseisOrosima.Add(item);
database.SaveChanges();
return Json(new[] { item }.ToDataSourceResult(request, ModelState));
}
}
return View();
// should also return json
}
The problem is that the Milestone type (the parameter in the controller) is always null even if i enter data when i create a new entry in the grid and press save. Any idea what to do in order to pass the entered data in the milestone parameter? Thank you in advance
As I saw in the Fiddler the parameters is posting with models prefix, thus you must access them like this:
public ActionResult CreateMilestone([DataSourceRequest] DataSourceRequest request,
[Bind(Prefix="models")] List<Milestone> milestons)
{
Milestone milestone = milestons[0];
.
.
.
}

Resources