I have a pretty basic MultiSelect, but the filter textbox (so you can type) does not even render.
#(Html.Kendo().MultiSelectFor(x => x.ParentAction.CustomFields)
.Placeholder("Search...")
.BindTo(Model.ParentAction.CustomFields)
.DataTextField("Name")
.DataValueField("CustomFieldId")
.Filter(FilterType.Contains)
.HtmlAttributes(new { #class = "form-control"})
.Height(325))
I also have a working DropDownList that uses server filtering:
#(Html.Kendo().DropDownListFor(x => x.ParentAction.CampaignId)
.OptionLabel("Select an existing campaign")
.DataSource(s =>
{
s.Custom()
.Type("aspnetmvc-ajax")
.ServerFiltering(true)
.Transport(t => t.Read(r =>
{
r.Action("GetCampaignsByActionType", "Campaign");
})
);
})
.DataTextField("Name")
.DataValueField("CampaignId")
.Enable(false)
.AutoBind(false)
.Filter(FilterType.Contains)
.CascadeFrom("ParentAction_CampaignType")
.Height(325)
.HtmlAttributes(new { #class = "form-control", style = "border:none;" })
.Deferred(!Request.IsAjaxRequest()))
That I converted to a multiselect which still does not render a textbox that I can type in:
#(Html.Kendo().MultiSelectFor(x => x.ParentAction.CampaignId)
//.OptionLabel("Select an existing campaign")
.DataSource(s =>
{
s.Custom()
.Type("aspnetmvc-ajax")
.ServerFiltering(true)
.Transport(t => t.Read(r =>
{
r.Action("GetCampaignsByActionType", "Campaign");
})
);
})
.DataTextField("Name")
.DataValueField("CampaignId")
.Enable(false)
.AutoBind(false)
.Filter(FilterType.Contains)
//.CascadeFrom("ParentAction_CampaignType")
.Height(325)
.HtmlAttributes(new { #class = "form-control", style = "border:none;" })
.Deferred(!Request.IsAjaxRequest()))
I cannot seem to find anything on this specific behavior when searching the web. So what am I doing incorrectly?
Related
Inside the editor template of one of my Grids, A, I have another grid, B. I want to set read and update actions of this Grid based on the current Id in the A.
I've tried using Razor code inside the editor template like this:
// details grid: B
.Read("action", "controller", new { #Model.Id })
But Id was always null, probably because Razor is server-side.
So I've tried to set the Grid inside the main page, in the Edit event of the main Grid.
function EditHandler(e) {
if (e.model.isNew())
return;
var detailGrid = e.container.find("#details").data('kendoGrid');
detailGrid.dataSource.options.transport.read.url = "#Url.Action("", "")".concat('/', e.model.Id);
detailGrid.dataSource.options.transport.update.url = "#Url.Action("", "")".concat("/", e.model.Name);
}
This doesn't work neither. The definition of the Grid in the editor template will overwrite these properties.
This is the main Grid:
#(Html.Kendo().Grid<A>()
.Name("A")
.Columns(columns =>
{
columns.Bound(x => x.Id).Hidden();
columns.Bound(x => x.Name).HtmlAttributes(new { #style = "text-align: left" });
....
columns.Command(command =>
{
command.Edit(); command.Destroy();
});
})
.....
.Selectable()
.Navigatable()
.DataSource(ds => ds
.Ajax()
.Model(model =>
{
model.Id(x => x.Name);
})
.Read("", "")
.Update("", "")
.Destroy("", "")
.Create("", "")
)
.Events(e => e.Edit("EditHandler").Save("SaveHandler"))
)
Inside the editor template of this class, a.cshtml, I have another Grid that I want its Edit and Read Actions include the Id of the Grid A.
#(Html.Kendo().Grid<B>()
.Name("B")
.Columns(columns =>
{
columns.Bound(.....
})
.....
.Editable(edit => edit.Mode(GridEditMode.InCell))
.Selectable()
.Navigatable()
.DataSource(ds => ds
.Ajax()
.PageSize(5)
.Model(model =>
{
model.Id(x => x.Id);
})
.Read("", "")
.Update("", "")
).ToClientTemplate()
)
UPDATE
function EditHandler(e) {
if (e.model.isNew())
return;
var detailGrid = e.container.find("#details").data('kendoGrid');
detailGrid.dataSource.read({ Id: e.model.Id });
detailGrid.dataSource.update({ Name: e.model.Name });
}
As Dion noted, it needs 2 changes:
In the child Grid, B, set the auto bind to false: .AutoBind(false)
Set the ID with read method, not manually as I've been trying.
To overcome this case, I will trigger Grid-B's read manually inside Grid-A's edit event. Follow this setup:
Grid-B Config:
.AutoBind(false)
.DataSource(ds => ds.Ajax()
.Read("action", "controller")
.Update(url => url.Action("update", "controller").Data(paramData)))
Modify Grid-A edit function:
function EditHandler(e) {
var gridB = $("#gridB").getKendoGrid(),
model = e.model;
gridB.dataSource.read({Id: model.Id});
}
// get Id for update
function paramData() {
return { Id : $("#Id").val(); };
}
Hope this help.
Note: Unlike read, update will be triggered after popup shown then Id field will be already have its value. Therefor you can use Url.Action(...).Data() for this case.
By default it looks like Telerik Grid for MVC3 submits only the rows marked as "dirty" to my controller. I need to be able to submit all rows on a Telerik Grid to my controller. In other words I think I need to mark all rows as changed so the grid will send all rows to my controller.
I am using Ajax data binding as in:
.DataBinding(dataBinding => dataBinding
.Ajax()
.Select("GetData", "ModuleAccess", new { roleId = #ViewBag.RoleId, appId = #ViewBag.AppId })
.Update("SaveBatchEditing", "ModuleAccess")
#(Html.Telerik().Grid<BarcodeListModel>()
.Name("orders-grid")
.ClientEvents(events => events.OnDataBinding("onDataBinding"))
.DataKeys(keys =>
{
keys.Add(x => x.Id);
})
.ToolBar(commands =>
{
commands.SubmitChanges();
})
.DataBinding(dataBinding =>
dataBinding.Ajax()
.Select("BulkEditSelect", "ProductVariant")
.Update("BulkEditSaveBarcode", "ProductVariant")
.Delete("DeleteBarcode", "ProductVariant")
)
.Columns(columns =>
{
columns.Bound(x => x.Id).ReadOnly();
columns.Bound(x => x.SKU);
columns.Bound(x => x.barcode);
//columns.Bound(x => x.Id)
// .Template(x => Html.ActionLink(T("Admin.Common.View").Text, "DeleteBarcode", new { id = x.Id }))
// .ClientTemplate("" + "Delete" + "")
// .Width(50)
// .Centered()
// .HeaderTemplate("DeleteBarcode")
// .Filterable(false)
// .Title("Delete");
columns.Command(commands => commands.Delete()).Width(180);
})
.Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both))
.DataBinding(dataBinding => dataBinding.Ajax().Select("BarcodeList", "ProductVariant", Model))
.Editable(editing => editing.Mode(GridEditMode.InCell))
.EnableCustomBinding(true)
)
use like this code
I found the answer:
function ModuleAccessGridHasChanges() {
var grid = $("#ModuleAccessGrid").data("tGrid");
if (grid != null) {
var additionalValues = grid.data;
if (!$.telerik.trigger(grid.element, 'submitChanges', { values: additionalValues })) {
grid.sendValues($.extend({}, additionalValues), 'updateUrl', 'submitChanges');
}
}
}
Fiddler shows all the data for the grid coming accross:
So I can make this work fine in newer browsers, but in IE9 when a date is clicked on the datepicker the cell turns back as unselected, empty and not dirty.
An example of my code is
MODEL
public string name { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}", NullDisplayText = "")]
[Display(Name = "Actual Start")]
public DateTime? ActualStartDate { get; set; }
public DateTime? ActualEndDate { get; set; }
GRID
Html.Kendo().Grid<MilestoneDto>()
.Name("editMilestoneList")
.Columns(columns =>
{
columns.Bound(m => m.Name).Title("Name");
columns.Bound(m => m.Status).EditorTemplateName("_milestoneStatus");
columns.Bound(m => m.PlannedStartDateStringValue);
columns.Bound(m => m.ProjectedStartDateStringValue);
columns.Bound(m => m.ActualStartDate).EditorTemplateName("GenericDatePicker");
columns.Bound(m => m.PlannedEndDateStringValue);
columns.Bound(m => m.ProjectedEndDateStringValue);
columns.Bound(m => m.ActualEndDateStringValue).EditorTemplateName("GenericDatePicker");
columns.Bound(m => m.CommentCount).ClientTemplate("#=CommentCount#</span>#}else{#<span class=\"fa fa-plus-circle\"></span>#}#").Title("Comments").Sortable(false).IncludeInMenu(false);
})
.HtmlAttributes(new { #class = "hidden results table-responsive" })
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("DataSource", "Milestone").Data("additionalParams"))
.Update(update => update.Action("BatchEdit", "Milestone"))
.Batch(true)
.Events(e => e.Sync("SyncGrid"))
.ServerOperation(false)
.Model(m => {
m.Id(mf => mf.Id);
m.Field(f => f.Name).Editable(false);
m.Field(f => f.Status).Editable(ViewBag.IsBaselined);
m.Field(f => f.PlannedStartDateStringValue).Editable(false);
m.Field(f => f.PlannedEndDateStringValue).Editable(false);
m.Field(f => f.CommentCount).Editable(false);
m.Field(f => f.ProjectedStartDateStringValue).Editable(false);
m.Field(f => f.ProjectedEndDateStringValue).Editable(false);
m.Field(f => f.ActualStartDate).Editable(ViewBag.IsBaselined);
m.Field(f => f.ActualEndDate).Editable(ViewBag.IsBaselined);
})
)
.Editable(editable => editable.Mode(GridEditMode.InCell))
.ColumnMenu()
.Filterable()
.Sortable();
}
EDITOR TEMPLATE
#model DateTime?
#Html.TextBoxFor(model => model, new { #class="k-textbox bootStrapDatePicker form- control" })
<script type="text/javascript">
$('.bootStrapDatePicker').datepicker({ startDate: '0', format: "m/d/yyyy", autoclose: true });
</script>
You have two (better) options that will automatically set up the DateTimePicker for you:
1) In the grid columns/models, use your ActualStartDate properties. Then you can use the .Format() method on your columns to format it how you'd like.
2) I don't know what the exact syntax is, but when you're defining the Model in the Grid, I I believe there is a DataType() or similar method to set it as a date time.
It's been a while but it turns out the problems was the version of jquery was incorrect.
I am using Ajax binding and so I am assuming that if I want the total to update after the user edits a change, I need the ClientFooterTemplate as opposed to just the FooterTemplate which works.
Here is my grid which works with FooterTemplate:
#{
GridEditMode mode = (GridEditMode)ViewData["mode"];
GridButtonType type = (GridButtonType)ViewData["type"];
GridInsertRowPosition insertRowPosition = (GridInsertRowPosition)ViewData["insertRowPosition"];
Html.Telerik().Grid<RedFile.Models.QuickQuoteItemView>("items")
.Name("QuoteItems")
.DataKeys(k => k.Add(o => o.Id))
.ToolBar(commands => commands.Insert().ButtonType(type).ImageHtmlAttributes(new { style = "margin-left:0" }))
.Columns(c =>
{
c.Bound(o => o.Id).ReadOnly().Hidden();
c.Bound(o => o.ItemID);
c.Bound(o => o.Description);
c.Bound(o => o.ItemQty);
c.Bound(o => o.ItemPrice).Format("{0:c}");
c.Bound(o => o.LineTotal)
.Width(100)
.Aggregate(ag => ag.Sum())
.FooterTemplate(result => (result.Sum == null ? "0.00" : result.Sum.Format("{0:c}")))
.Format("{0:c}");
c.Command(s =>
{
s.Edit();
s.Delete();
});
})
.Editable(editing => editing.Mode(mode).InsertRowPosition(insertRowPosition))
.DataBinding(b => b.Ajax()
.Select("GridSelect", "QuickQuote")
.Insert("GridInsert", "QuickQuote", new { qqid = Model.Id })
.Update("GridUpdate", "QuickQuote", new { qqid = Model.Id })
.Delete("GridDelete", "QuickQuote", new { qqid = Model.Id })
)
.Footer(true)
.Render();
}
If I change the footer template to something like this: (I have tried multiple variations with the same result)
.ClientFooterTemplate("<#= $.telerik.formatString('{0:c}', Sum) #>")
The total simply disappears.
All I want is a total that updates after the user changes something. Any idea what I'm doing wrong?
Thanks
columns.Bound(p => p.ItemPrice)
.FooterTemplate(
#<text>
Total:#string.Format("{0:c}", Model.ItemPrice)
</text>
)
.Width(100)
.Format("{0:c}");
Refer to Teleriks MVC grid Documentation
I am using Telerik MVC extension version 2012.1.419.340. I had a problem with Command Column in Grid. I will use the example code on Telerik website to explain my problem.
I have view like:
#model IEnumerable<Order>
#(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(o => o.OrderID).Width(100);
columns.Bound(o => o.ShipAddress);
columns.Command(commands => commands
.Custom("viewDetails")
.Text("View Details")
.DataRouteValues(route => route.Add(o => o.OrderID).RouteKey("orderID"))
.Ajax(true)
.Action("ViewDetails", "Grid"))
.HtmlAttributes(new { style = "text-align: center" })
.Width(150);
})
.ClientEvents(events => events.OnComplete("onComplete"))
.DataBinding(dataBinding => dataBinding.Ajax().Select("_CustomCommand", "Grid"))
.Pageable()
.Sortable()
.Filterable()
)
and my Order model like
public class Order{
public int OrderID {get;set;}
public string ShipAddress {get ; set; }
public bool CanEdit {get; set;}
}
I would like my Command Column to use different Action depending on CanEdit value. For example, if CanEdit is false, using action
columns.Command(commands => commands
.Custom("viewDetails")
.Text("View Details")
.DataRouteValues(route => route.Add(o => o.OrderID).RouteKey("orderID"))
.Ajax(true)
.Action("ViewDetails", "Grid"))
.HtmlAttributes(new { style = "text-align: center" })
if CanEdit is true, using action
columns.Command(commands => commands
.Custom("editDetails")
.Text("Edit Details")
.DataRouteValues(route => route.Add(o => o.OrderID).RouteKey("orderID"))
.Ajax(true)
.Action("EditDetails", "Grid"))
.HtmlAttributes(new { style = "text-align: center" })
Can you give me some idea how to implement it?
Thanks
Finally I solved this issue by using Template Column in the Grid. I found there is no way to change Text for command column on demand. Thanks