MVCContrib Grid Razor problem, Column.Action do not render - razor

Code below works great with aspx view engine, i am trying to convert it to razor as below. Problem is first column do not show up.
I convert first column into link using action method. With razor it(first column) is not getting rendered in page at all. Rest of grid is fine.
What could be the problem?
#{Html.Grid(Model.Orders).Attributes(style => "width: 100%;").Columns(
column => {
column.For(x => x.OrderNumber).Action(p => {
#:<td>
Html.ActionLink(
p.OrderNumber.ToString(),
"orderdetail",
"OrderUpdate",
new { id = p.OrderNumber, backUrl = Url.Action("OrderHistory", new { controller = "DataController", id = ViewData["id"] }) },
new { });
#:</td>
}).HeaderAttributes(style => "text-align:left");
column.For(x => x.OrderTimeV2).HeaderAttributes(style => "text-align:left");
column.For(x => x.Status).HeaderAttributes(style => "text-align:left");
column.For(x => x.Type).HeaderAttributes(style => "text-align:left");
}).RowStart((p, row) => { }).Render();}

I have moved away from using mvccontrib grid as it doesn't make much sense in grid we have.
Anyway problem was code in the question does not return html but puts code directly into response stream. And code for columns rendered using razor which put's code into stream whenever called. so it ends up putting columns into stream before grid is rendered.
It was resolved by not using razor code in action called by grid.

Ok I got it working for me with the following
#Html.Grid(Model.Result).Columns(column => {
column.For(u => u.Name).Named("Name");
column.For(u => u.Code).Named("Code");
column.For(u => Html.ActionLink("Edit", "Edit", new { id = u.Id })).Named("Edit");

You can do a custom column to get what you want:
#Html.Grid(Model).Columns(column => {
column.Custom(
#<div>
<em>Hello there</em>
<strong>#item.Name</strong>
</div>
).Named("Custom Column");
})
From: MvcContrib Grid Custom Columns (Razor)
I did this when porting some .aspx pages to Razor.

Related

Kendo MVC Grid Filtering - Filters that consider multiple fields

I have a MVC Kendo grid where one column is a client template that actually uses multiple fields. By default the built in filtering is only applied to the field the column is bound to. How do I override that so it considers both fields. Ie, when I search for "Contains" "De" a column that displays "Detroit, MI" should return.
Here's what I have so far:
MVC View
#(Html.Kendo().Grid<ViewModel>()
.DataSource(dataSource => dataSource
.Custom()
.Transport(t =>
{
t.Read(r => r.Action("StatusGridRead", "DeviceStatus"));
})
.Schema(schema => schema
.Data("Result.Data")
.Total("Result.Total")
.Errors("Result.Errors")
.Model(m =>
{
m.Id(f => f.Id);
m.Field(f => f.StateOrProvince);
m.Field(f => f.City);
...
})
)
)
.Columns(columns =>
{
columns.Bound(c => c.StateOrProvince).Title("City & State").ClientTemplate("#=City#, #=StateOrProvince#");
...
})
.Events(e=>
{
e.Filter("statusGridFilter");
})
.Sortable()
.Filterable(f =>
{
f.Extra(false);
f.Operators(o => o.ForString(s =>
{
s.Clear();
s.Contains("Contains");
s.IsEqualTo("Is Equal To");
s.StartsWith("Starts With");
s.EndsWith("Ends With");
s.DoesNotContain("Does Not Contain");
s.IsNotEqualTo("Is Not Equal To");
}));
})
)
Javascript
function statusGridFilter(e) {
if (e.field == "StateOrProvince") {
//What do I do here?
}
}
I understand if I made a column for city and one for state that would resolve this issue, however I actually have a similar scenario (client template with many string fields displayed) where that won't work and am just picking this as the easiest example. Other than making 1 column for 1 field, I'm open to any other ideas that may solve filtering for this scenario.

Kendo Grid select over multiple pages

I have created a kendo grid using Asp.Net MVC wrappers. I have included a checkbox for selecting multiple rows made the wiring and everything works ok. However, I have issues, when I change page, or do a filtering as the selecting rows/checkbox disappear.
What is the solution for this problem?
You need to use .PersistSelection(true) to ensure rows remain selected when changing pages:
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()
.Name("rowSelection")
.Columns(columns => {
columns.Bound(o => o.ShipCountry).Width(300);
columns.Bound(p => p.Freight).Width(300);
columns.Bound(p => p.OrderDate).Format("{0:dd/MM/yyyy}");
})
.Pageable(pageable => pageable.ButtonCount(5))
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple))
.PersistSelection(true)
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(m=>m.Id("OrderID"))
.PageSize(6)
.Read(read => read.Action("Orders_Read", "Grid"))
)
Also ensure you have an id column declared in the DataSource, like .Model(m=>m.Id("OrderID")) in the example, otherwise it will fail.
Full details here.
I had issues with the jQuery grid.select() however:
var grid = $('#rowSelection').data('kendoGrid');
var rows = grid.select();
This only seemed to return rows selected on the currently displayed page rather than all the rows selected across all the pages.

How can I ensure Kendo Grid passes a numeric value with the correct separator to ASP.NET MVC?

I have a simple grid that uses a custom popup editor template. In the template, I'd like to use a Numeric Textbox.
Due to localization, the application keeps trying to use a comma to separate decimals in the numeric values. When these values are passed to the ASP.NET MVC back-end, the value is lost and null is passed. How can I ensure the posted value has a period separator?
I have tried setting the underlying field values to 2.5 instead of 2,5 in the grid's Save event, as well as tried to overwrite the e.model.WeightKg to 2.5. The value is still passed with a comma separator, as shown by inspecting the form data in the request.
My grid:
#(Html.Kendo().Grid<PackageViewModel>()
.Name("PackageGrid")
.Columns(columns => {
columns.Bound(o => o.PackageCode);
columns.Bound(o => o.WeightKg);
columns.Command(o => o.Edit());
})
.DataSource(d => d
.WebApi()
.Model(m => m.Id(o => o.PackageCode))
.Read(c => c.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Packages" })))
.Create(c => c.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Packages" })))
.Destroy(c => c.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Packages" id = "{0}" })))
.Update(c => c.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Packages" id = "{0}" })))
.PageSize(20)
)
.Editable(e => e.Mode(GridEditMode.PopUp).TemplateName("Package"))
.Selectable()
.Deferred()
)
The numeric textbox in the template:
#Html.Kendo().NumericTextBoxFor(m => m.WeightKg).Decimals(8)
And finally, the unparsed form data, followed by the parsed form data:
sort=&group=&filter=&PackageCode=DOOS-B&WeightKg=2%2C5
sort:
group:
filter:
PackageCode:DOOS-B
WeightKg:2,5

Setting Content for Bound Kendo UI MVC TabStrip using Razor

Having trouble setting the tab content for a databound tabstrip. I found an example of how to to it using webforms syntax, but can't successfully convert this to razor:
Here is webforms syntax from here:
.BindTo(Model,
(item, navigationData) =>
{
item.Text = navigationData.Text;
item.ImageUrl = navigationData.ImageUrl;
item.Content = () =>
{%>
Some random content I want to appear
<% };
})
Here is how I am trying to do it in Razor:
#(Html.Kendo().TabStrip()
.Name("OrderDetailsTabs")
.BindTo(Model, (item, model) =>
{
item.Text = "Part: " + model.WOHdr.OrderDetailId; // tab text
item.Content = () =>
{
(#<text>
Test #(model.WOHdr.Id)
</text>);
};
Which produces the error:
A local variable named 'item' cannot be declared in this scope because it would give a different meaning to 'item', which is already used in a 'parent or current' scope to denote something else
You have to use .InlineTemplate...not .Content
tab.Template.InlineTemplate =
#<text>
#(Html.EditorFor(model => tabModel, "WorkOrder", tabModel))
</text>;

zend framework 2, return the rendered contents of a view inside a JSON Model

I am trying to create a JsonModel with an item in the variables 'html' containing the current rendered view. I would like to add this code to an event:
rather than this method: How to render ZF2 view within JSON response? which is in the controller, I would like to automate the process by moving it to an Event
I have the strategy in my module.config.php:
'strategies' => array(
'ViewJsonStrategy',
)
I have set up a setEventManager in the controller:
$events->attach(MvcEvent::EVENT_RENDER, function ($e) use ($controller) {
$controller->setRenderFormat($e);
}, -20);
Is this the best event to attach it to? would the RENDER_EVENT be better?
Now I would like to change the render of the page based on !$this->getRequest()->isXmlHttpRequest(), (commented out for debug)
public function setRenderFormat($e)
{
//if(!$this->getRequest()->isXmlHttpRequest())
//{
$controller = $e->getTarget();
$controllerClass = get_class($controller);
//Get routing info
$controllerArr = explode('\\', $controllerClass);
$currentRoute = array(
'module' => strtolower($controllerArr[0]),
'controller' => strtolower(str_replace("Controller", "", $controllerArr[2])),
'action' => strtolower($controller->getEvent()->getRouteMatch()->getParam('action'))
);
$view_template = implode('/',$currentRoute);
$viewmodel = new \Zend\View\Model\ViewModel();
$viewmodel->setTemplate($view_template);
$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($viewmodel, $viewmodel);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
//}
}
Strangely, (or not) this code works and produces the $jsonModel, however is doesn't overwite the normal HTML view with the json, but the same code (without the event) in a controller method, overwrites perfectly.
p.s Is there a better method to do the whole concept?
p.p.s how can I obtain the current View Template from within the controller, without resorting to 8 lines of code?
Thanks in advance!
Aborgrove
you are returning the view model from an event I thinks this doesn't have any effect in current viewmanager view model, fetch the current viewmodel from viewmanager and call setTerminal(true). or replace the created jsonmodel using the viewmanager