Hi,
I have a sample ASP.NET 5 (MVC) web app from Microsoft working in VS2015:
http://docs.asp.net/en/latest/tutorials/your-first-aspnet-application.html
I am in attempt to popluate the Telerik Grid with the Model that I have generated above, however having no luck.
Snip from the app:
BooksController:
// GET: Books
public
IActionResult Index()
{
var applicationDbContext = _context.Book;
return
View(applicationDbContext.ToList());
}
@(Html.Kendo().Grid(Model)
.Name(
"datagrid"
)
.Columns(columns =>
{
columns.Bound(b=>b.Title);
})
.DataSource(dataSource => dataSource
.Ajax()
)
)
When I debug, Grid does not appear on the page. However, I can see the actual data written in the html source of the page:
HTML:
<
div
id
=
"datagrid"
name
=
"datagrid"
></
div
><
script
>jQuery(function(){jQuery("#datagrid").kendoGrid({"columns":[{"title":"Title","field":"Title",
:
"data":{"Data":[{"BookID":2,"AuthorID":null,"Genre":"Gothic parody333","Price":12.95,"Title":"Northanger Abbey","Year":1817,"Author":null},{"BookID":3,"AuthorID":2,"Genre":"Bildungsroman","Price":15.00,"Title":"David Copperfield","Year":1850,"Author":null},{"BookID":4,"AuthorID":3,"Genre":"Picaresque","Price":8.95,"Title":"Don Quixote","Year":1617,"Author":null}],"Total":3}}});});</
script
>
Would help if you could point out what I may have missed, thanks!
We are using the multiselect control with values pre-selection and ToDataSourceResult instance as describe in documentation.
Unfortunately, when we post our model and its ModelState is invalid, we return to the view and the control fails to display the pre-selection and the search also stop working.
Here is some sample snippet.
Model
public
class
CreateModel
{
[Required]
public
string
Name {
get
;
set
; }
public
List<
int
> ProductIds {
get
;
set
; }
public
List<Product> InitialProducts {
get
;
set
; }
}
public
class
Product
{
public
int
ProductId {
get
;
set
; }
public
string
ProductName {
get
;
set
; }
}
Controller
public
class
HomeController : Controller
{
[HttpGet]
public
ActionResult Create()
{
var initialProduct = GetProductList().First();
var model =
new
CreateModel
{
InitialProducts =
new
List<Product>(
new
[] { initialProduct }),
ProductIds =
new
List<
int
>(
new
[] { initialProduct.ProductId })
};
return
View(model);
}
[HttpPost]
public
ActionResult Create(CreateModel model)
{
if
(ModelState.IsValid)
return
RedirectToAction(
"Success"
);
model.InitialProducts = GetProductList().Where(p => model.ProductIds.Contains(p.ProductId)).ToList();
return
View(model);
}
[HttpGet]
public
ActionResult Success()
{
return
View();
}
private
static
IEnumerable<Product> GetProductList()
{
return
new
[]
{
new
Product { ProductId = 1, ProductName =
"Chai"
},
new
Product { ProductId = 2, ProductName =
"Chang"
},
new
Product { ProductId = 3, ProductName =
"Book"
},
new
Product { ProductId = 4, ProductName =
"Fork"
},
new
Product { ProductId = 5, ProductName =
"Knife"
},
new
Product { ProductId = 6, ProductName =
"Spoon"
},
new
Product { ProductId = 7, ProductName =
"Dish"
},
new
Product { ProductId = 8, ProductName =
"Glass"
},
new
Product { ProductId = 9, ProductName =
"Cup"
}
};
}
[HttpPost]
public
JsonResult GetDataSourceProducts([DataSourceRequest] DataSourceRequest request)
{
var products = GetProductList();
if
(request.Filters !=
null
&& request.Filters.Count > 0)
{
var filter = (FilterDescriptor)request.Filters[0];
products = products.Where(p => p.ProductName.ToLower().Contains((
string
)filter.Value)).AsEnumerable();
}
return
Json(products.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
}
View
@using (Html.BeginForm("Create", "Home"))
{
<
div
>
@Html.Kendo().TextBoxFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
</
div
>
<
div
>
@(Html.Kendo().MultiSelectFor(m => m.ProductIds)
.DataTextField("ProductName")
.DataValueField("ProductId")
.Placeholder("Select products...")
.AutoBind(false)
.DataSource(source => source
.Custom()
.ServerFiltering(true)
.Type("aspnetmvc-ajax")
.Transport(transport => transport.Read(read => read.Action("GetDataSourceProducts", "Home")))
.Schema(schema => schema.Data("Data").Total("Total"))
)
.Filter(FilterType.Contains)
.Value(Model.InitialProducts)
)
</
div
>
<
div
>
<
button
id
=
"Save"
type
=
"submit"
>Save</
button
>
</
div
>
}
Is there any kind of work around for this?
My Model looks Like this:
public class ForecastChartViewModel
{
public int ID { get; set; }
public String PeriodName { get; set; }
public String EstimateDesc { get; set; }
public Decimal EstimateValue { get; set; }
public String ChartColor { get; set; }
public Boolean IsBenchmark { get; set; }
}
I want the periodName to be the values across the X-Axis and each EstimateDesc to be stack on top of each other for that period if IsBenchmark is false, if IsBenchmark is true I'd like to use a line instead of a stack. EstimateValue is the charted Value. I want to be able to set the color for the series to the value of the ChartColor as well.
@(Html.Kendo().Chart<ManpowerForecast.Web.ViewModels.ForecastChartViewModel>()
.Name("chart")
.Legend(legend => legend
.Visible(true)
)
.DataSource(ds => ds
.Read(read => read.Action("ReadManpowerReportForecast", "Manpower"))
.Group(group => group.Add(model => model.EstimateDesc))
.Sort(sort => sort.Add(model => model.PeriodName))
)
.SeriesDefaults(seriesDefaults =>
seriesDefaults.Bar().Stack(true)
)
.Series(series =>
{
series
.Column(model => model.EstimateValue)
.Name("#= group.value #")
.Visible(true);
})
.CategoryAxis(axis => axis
.Categories(model => model.PeriodName)
.MajorGridLines(lines => lines.Visible(false))
.Line(line => line.Visible(false))
)
.ValueAxis(axis => axis.Numeric()
.Max(60)
.MajorGridLines(lines => lines.Visible(false))
.Visible(false)
)
)
In my Controller "ReadManpowerReportForecast" I'm just throwing in some junk data for right now to make sure I can get this chart to function before I go through the complexity of forcing my data into the model in this format. so I could change my model if need be. The code to load the viewmodel looks liket this:
IList<ForecastChartViewModel> vCharts = new List<ForecastChartViewModel>();
ForecastChartViewModel vChart = new ForecastChartViewModel()
{
PeriodName = "Period1",
EstimateDesc = "Project1",
EstimateValue = 20,
IsBenchmark = false,
ChartColor = "#cc00cc"
};
vCharts.Add(vChart);
vChart = new ForecastChartViewModel()
{
PeriodName = "Period1",
EstimateDesc = "Project2",
EstimateValue = 20,
IsBenchmark = false,
ChartColor = "#aa0033"
};
vCharts.Add(vChart);
vChart = new ForecastChartViewModel()
{
PeriodName = "Period1",
EstimateDesc = "Project3",
EstimateValue = 10,
IsBenchmark = true,
ChartColor = "#110011"
};
vCharts.Add(vChart);
vChart = new ForecastChartViewModel()
{
PeriodName = "Period2",
EstimateDesc = "Project1",
EstimateValue = 30,
IsBenchmark = false,
ChartColor = "#cc00cc"
};
vCharts.Add(vChart);
vChart = new ForecastChartViewModel()
{
PeriodName = "Period2",
EstimateDesc = "Project2",
EstimateValue = 12,
IsBenchmark = false,
ChartColor = "#aa0033"
};
vCharts.Add(vChart);
vChart = new ForecastChartViewModel()
{
PeriodName = "Period2",
EstimateDesc = "Project3",
EstimateValue = 5,
IsBenchmark = true,
ChartColor = "#110011"
};
vCharts.Add(vChart);
For example, if I have a change event as below
function sliderChange(e)
{
var msg = "View is changed to " + e.value;
$("#e.ID").html(msg);
}
How can I get slider ID then I can change some control related to this ID?
Thanks
I have two grids, A and B, in one page. After modifying data on A grid, I like to trigger changes in B grid and save it to the server. Is there method I can call through JavaScript to save grid B?
thanks
I've been working on change the class added to a table row of the grid based on the value of a specific cell. For some reason however my code doesn't actually seem to do anything. There are no errors it just doesn't apply a class to the row cell and I don't know why. Can someone do a sanity check for me and make sure I have the code correctly structured please.
The Grid
@(Html.Kendo().Grid<
Spoton_Areas_Test.ViewModels.VesselsViewModel
>()
.Name("Grid")
.Columns(columns => {
columns.Bound(c => c.fixture_work)
.Title("Work");
columns.Bound(c => c.vessel_status)
.Title("Status");
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Events(e=>e.DataBound("OnDataBound"))
.DataSource(dataSource => dataSource
.Ajax()
.Sort(sort =>
{
sort.Add(
company => company.owner_company).Ascending();
})
.PageSize(40)
.Model(model =>
{
model.Id(p => p.vessel_idx);
})
.Read(read => read.Action("vessels_Read", "Home"))
.Update(update => update.Action("vessels_Update", "Home"))
))
My Javascript
function
onDataBound(e) {
var
kendoGrid = $(
"#Grid"
).data(
"kendoGrid"
);
var
rows = e.sender.element.find(
"tbody tr"
);
for
(
var
i = 0; i < rows.length; i++) {
var
row = rows[i];
var
status = kendoGrid.dataItem(row).vessel_status;
if
(status =
"PPT"
) {
$(row.cells[3]).addClass(
"customRed"
);
}
}
}
I have a grouped Grid in batch mode. My aggregates aren't refreshing as edits are made to the aggregated data until after a .saveChanges is performed. I want the aggregate to update as soon as the focus leaves a cell that is aggregated.
My Columns look like this:
columns.Bound(c => c.Period1)
.HeaderTemplate("<a>" + @title1 + "<br>" + @title2 + "</a>")
//.ClientGroupHeaderTemplate("#= sum #")
.ClientGroupFooterTemplate("#= sum #")
.ClientFooterTemplate("#= sum #")
.Filterable(false)
.Width(100);
My Datasource is configured as such:
.DataSource(dataSource => dataSource
.Ajax()
.AutoSync(false)
.Aggregates(aggregates =>
{
if (Model.Count() > 0) { aggregates.Add(p => p.Period1).Sum(); }
//more aggregate properties here
})
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Group(groups => groups.Add(p => p.ProjectType))
.Model(model =>
{
model.Id(prop => prop.ID);
//other model properties here
})
.Create(create => create.Action("CreateManpowerProjectEstimates", "Manpower"))
.Read(read => read.Action("ReadManpowerProjectEstimates", "Manpower"))
.Update(edit => edit.Action("UpdateManpowerProjectEstimates", "Manpower"))
.Destroy(delete => delete.Action("DestroyManpowerProjectEstimates", "Manpower"))
.PageSize(20)
)
I am attempting to post to an action in the controller from a custom button in the Grid component. At first the Grid would render the form outside of the column, this was fixed by {}.Render() which appears to generate the form in the correct location.
My problem is that the items being passed to the form are always null, regardles:
I'll simply my example:
@{Html.Kendo().Grid(Model)
.Name(
"IterationGrid"
)
.Sortable()
.Columns(columns =>
{
columns.Tempate(@<text>
using
(Html.BeginForm(
"RemindEmployee"
,
"Evaluations"
, FormMethod.Post))
{
Html.Hidden(
"employeeID"
, item.Employee.EmployeeID);
Html.Hidden(
"reviewID"
, item.ReviewId);
Html.Hidden(
"fullname"
, item.Employee.Fullname);
<input type=
"submit"
name=
"Remind"
value=
"Remind"
class
=
"btn btn-primary btn-k-grid"
/>
}@</text>).Title(
"Action"
); }).Render(); }
As I mentioned this appears to work fine, and the Controller has:
[HttpPost]
public
ActionResult RemindEmployee(
int
? employeeID,
int
? reviewID,
string
fullname) { }
Though the parameters are always passed as null. What's the best way to handle this example here?
Note: I've already used some javascript $.post() to do the same thing, but I would like to know the proper way to get the above to work with hidden forms for my own benefit.
Hi,
It’s posible not close grid popup if I have added in modelstate an error on créate or update method of controller.
public ActionResult DirectInCreate([DataSourceRequest]DataSourceRequest request, DirectInViewModel service)
{
if (ModelState.IsValid)
{
if (service.OrigenID == 0)
{
string errorMessage = string.Format("El camp Productor es obligatori.");
ModelState.AddModelError("", errorMessage);
}
Else
function onError(e, gridName) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
var grid = $("#" + gridName).data("kendoGrid");
grid.one("dataBinding", function (e) {
e.preventDefault();
})
alert(message);
grid.cancelChanges();
}
}
Thanks in advance.
Xavier de la Rubia.