This question is locked. New answers and comments are not allowed.
Hello,
In a nutshell, the CSS being generated is slighty wrong (I think) - it's only a small capital letter but I think it is preventing my custom command button image. Not sure how best to go about fixing it in the best way.
I have a mvc grid that generates an partial view based ajax form in a telerik window via ajax. One toolbar button allows me to open the create window and I am trying to do the same for edit everything is working fine...BUT my image is not appearing for my custom command button. See code below.
In a nutshell, the CSS being generated is slighty wrong (I think) - it's only a small capital letter but I think it is preventing my custom command button image. Not sure how best to go about fixing it in the best way.
I have a mvc grid that generates an partial view based ajax form in a telerik window via ajax. One toolbar button allows me to open the create window and I am trying to do the same for edit everything is working fine...BUT my image is not appearing for my custom command button. See code below.
.Columns(columns =>{columns.Command(commands => {commands.Custom("Edit").ButtonType(GridButtonType.Image).Ajax(true).ImageHtmlAttributes(new{ @class="t-icon t-edit"}).Text("Edit");commands.Delete().ButtonType(GridButtonType.Image);}).Width(100);columns.Bound(o => o.ApplicationID).Width(50);columns.Bound(o => o.ApplicationName).Width(200);columns.Bound(o => o.IsActive).Width(200);columns.Bound(o => o.IsAdminTool);columns.Bound(o => o.ApplicationID).ClientTemplate("<div id='Row_<#= ApplicationID #>'></div><script>$('#Row_<#= ApplicationID #>').html(GetLink('<#= ApplicationID #>'))</script>").Filterable(false).Title("").Width(100);})
This code produces...<aclass="t-button t-grid-Edit t-ajax t-button-icon"href="/config/applications/index/1"><spanclass="t-icon t-Edit"></span></a><aclass="t-button t-grid-delete t-button-icon"href="#"><spanclass="t-icon t-delete"></span></a>
(t-delete = correct)
(t-Edit = incorrect)
and I believe (please correct me if i'm being a twerp) it should be...<aclass="t-button t-grid-Edit t-ajax t-button-icon"href="/config/applications/index/1"><spanclass="t-icon t-edit"></span></a><aclass="t-button t-grid-delete t-button-icon"href="#"><spanclass="t-icon t-delete"></span></a>
I used IE developer tools to dynamically change the t-Edit and t-edit
and found the icon appears.
The code for t-delete is automatically generated and that works as expected.
Here is me hoping for a nice work around.
Oh and I'm using v2011.3.1306
Perhaps I'm confused too!!
Also, I can't seem to add additional class elements and the second class
automatically inserted by Telerik after t-icon seems to be modified
in relation to the name of the custom button part
i.e. commands.Custom("edit2") produces <span class="t-icon t-edit2" />.
BUT if i use the custom command name of edit then it goes to t-Edit.
All I want to do, is to use Tekerik icons i.e. edit in this case,
on a custom command button in a mvc grid.
Best wishes,
Dan.
More info:
1. using commands.custom("edit") results in an explosion.
2. using @class = "t-icon t-edit" (for ImageHtmlAttributes) does
absolutely nothing to the output of the span. Does this work or am I using it wrong?
In the meantime I've hacked a solution in JS but it's far from ideal...functionFixCustomCommandButton(gridID, commandName, iconName) {$("#"+ gridID +" .t-grid-"+ commandName +" .t-"+ commandName).attr("class","t-icon "+ iconName);}
Then call it from onDataBound client side event:functionGrid_onDataBound(e) {FixCustomCommandButton("Application","CustomEditCommand","t-edit");}
for your command button if ImageHtmlAttributes doesn't do anythingcommands.Custom("CustomEditCommand").ButtonType(GridButtonType.Image).Ajax(true).ImageHtmlAttributes(new{ @class="t-icon t-edit"}).Text("Edit");
9 Answers, 1 is accepted
0
Hi Dan,
I don't reproduce the described issue with the latest MVC extensions version. Using .Custom("Edit") leads to a t-edit CSS class being rendered to the button's inner <span> element.
An exception will be thrown if you don't have the .Action() for the custom command is not set.
Let me know if I am missing something.
All the best,
Dimo
the Telerik team
I don't reproduce the described issue with the latest MVC extensions version. Using .Custom("Edit") leads to a t-edit CSS class being rendered to the button's inner <span> element.
An exception will be thrown if you don't have the .Action() for the custom command is not set.
Let me know if I am missing something.
All the best,
Dimo
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Dan
Top achievements
Rank 1
answered on 13 Feb 2012, 08:52 PM
Hi Dimo,
I have attached two files, one is an image displaying my code, the result and the CSS using IE dev tool (where the code uses the latest version (2011.3.1306) from the content delivery network). The other is a VS1010 MVC project which results in the unexpected behaviour. There is only one page of real interest...~/Views/Home/Index.cshtml. You just need to run the project to see the result.
Also, omitting .Action does not result in an visibile exception for me (as I catch the request in Grid_onCommand, by which time I have everything I need to run my javascript and then simply e.preventDefault() the event - hopefully this method won't cause a problem with future releases).
Visual Studio tells me this is the latest version of Telerik MVC.
I have placed comments in the grid code to summarise the issues.
Since my initial post is a bit too detailed, let me summarise my main issues:
I have attached two files, one is an image displaying my code, the result and the CSS using IE dev tool (where the code uses the latest version (2011.3.1306) from the content delivery network). The other is a VS1010 MVC project which results in the unexpected behaviour. There is only one page of real interest...~/Views/Home/Index.cshtml. You just need to run the project to see the result.
Also, omitting .Action does not result in an visibile exception for me (as I catch the request in Grid_onCommand, by which time I have everything I need to run my javascript and then simply e.preventDefault() the event - hopefully this method won't cause a problem with future releases).
Visual Studio tells me this is the latest version of Telerik MVC.
I have placed comments in the grid code to summarise the issues.
Since my initial post is a bit too detailed, let me summarise my main issues:
- The icon is not visible on the custom button (I want the nice t-edit icon)
- ImageHtmlAttributes does not change the button image (span) class at all
- If using commands.Custom("edit") creates some sort of javascript error (lower case in an attempt to produce t-edit not t-Edit)
Please let me know if you need any more information.
Best wishes,
Dan.
0
Accepted
Hello Dan,
Thank you for the demo. We identified the cause ofthe problem and fixed it. Changes will take effect in the next internal build. I have updated your Telerik points.
In the meantime, you can make the edit icon appear by setting the required CSS class with Javascript, e.g. in the Grid's OnDataBound event.
On a side note, we do not recommend using a custom command, which has the same name as one of the Grid's native commands. This is because some event handlers and other scripts may get executed unexpectedly.
Regards,
Dimo
the Telerik team
Thank you for the demo. We identified the cause ofthe problem and fixed it. Changes will take effect in the next internal build. I have updated your Telerik points.
In the meantime, you can make the edit icon appear by setting the required CSS class with Javascript, e.g. in the Grid's OnDataBound event.
On a side note, we do not recommend using a custom command, which has the same name as one of the Grid's native commands. This is because some event handlers and other scripts may get executed unexpectedly.
Regards,
Dimo
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Dan
Top achievements
Rank 1
answered on 14 Feb 2012, 11:03 PM
Hi Dimo,
You are very welcome and thank you for the points.
I have a very different command name now and thank you for your recommendation.
I am using the custom command button (and toolbar button) to open up my own shared insert/edit interface (using a Telerik window to load a single partial view which contains an ajax form enabled with unobtrusive javascript validation). It all works impressively well and I am happy.
Thank you for your prompt support.
Best wishes,
Dan.
You are very welcome and thank you for the points.
I have a very different command name now and thank you for your recommendation.
I am using the custom command button (and toolbar button) to open up my own shared insert/edit interface (using a Telerik window to load a single partial view which contains an ajax form enabled with unobtrusive javascript validation). It all works impressively well and I am happy.
Thank you for your prompt support.
Best wishes,
Dan.
0
Phil
Top achievements
Rank 1
answered on 04 Apr 2012, 12:33 PM
Hi Dan,
Read your forum issue a few days ago. I had a custom image need on the grid. Now have custom images fully working on grid. Thought you might like to see my resolution:
http://www.telerik.com/community/forums/aspnet-mvc/grid/how-can-i-customise-button-images.aspx
It also sounds like you are building the same pattern as me.
Toolbar "Add" button launches Telerik Window which loads create view via ajax. On submit window hides and grid rebinds.
Edit button in grid row launches telerik window which loads edit view via ajax. On submit window hides and grid rebinds.
I would be keen to see your implementation in particular the ajax controller actions and what they return. Is it a small test project you could possibly post?
Best regards
Phil
Read your forum issue a few days ago. I had a custom image need on the grid. Now have custom images fully working on grid. Thought you might like to see my resolution:
http://www.telerik.com/community/forums/aspnet-mvc/grid/how-can-i-customise-button-images.aspx
It also sounds like you are building the same pattern as me.
Toolbar "Add" button launches Telerik Window which loads create view via ajax. On submit window hides and grid rebinds.
Edit button in grid row launches telerik window which loads edit view via ajax. On submit window hides and grid rebinds.
I would be keen to see your implementation in particular the ajax controller actions and what they return. Is it a small test project you could possibly post?
Best regards
Phil
0
Dan
Top achievements
Rank 1
answered on 04 Apr 2012, 08:46 PM
Hi Mr Phil,
Well I'll give you a whirlwind tour of a page which stores a list of applications (apps) I have installed onto a website for the client.
This is a basic CRUD scenario - there is a link in the grid that takes you through to application features.
I have one partial view for both the editing and inserting of the item row.
Edit button & create opens a telerik window, content loaded by the use of a view dynamically via jquery, form is updated/insert with the help of unobtrusive javascript.
Note: you need to make sure you have Model.Clear() before returning the same model to show a success message.
Note: this code does not yet limit access or have anti-forgery tokens.
Lets start with the easy bits first....
CONTROLLER (gets the data = calls service layer which performs EF based lookup - nothing fancy - returns a viewmodel. I use Castle Windsor to follow a IoC dependency injection pattern with service layer and repository layer).
Well I'll give you a whirlwind tour of a page which stores a list of applications (apps) I have installed onto a website for the client.
This is a basic CRUD scenario - there is a link in the grid that takes you through to application features.
I have one partial view for both the editing and inserting of the item row.
Edit button & create opens a telerik window, content loaded by the use of a view dynamically via jquery, form is updated/insert with the help of unobtrusive javascript.
Note: you need to make sure you have Model.Clear() before returning the same model to show a success message.
Note: this code does not yet limit access or have anti-forgery tokens.
Lets start with the easy bits first....
CONTROLLER (gets the data = calls service layer which performs EF based lookup - nothing fancy - returns a viewmodel. I use Castle Windsor to follow a IoC dependency injection pattern with service layer and repository layer).
[HttpPost, GridAction]public ActionResult _Select(){ return View(new GridModel(GetApplications()));}public List<Application> GetApplications(){ return applicationService.SelectApplications().ReturnValues["results"] as List<Application>;}VIEW
@using Telerik.Web.Mvc.UI;@{ViewBag.Title = "Applications"; } <script type="text/javascript" language="javascript"> // Open Window - create new applicationfunction OpenWindow_CreateNewApplication() {OpenWindow('Window', 'Loading content, please wait...');var url = '@(Url.Action("_application_create", new { Controller="Applications", Area = "Config"}))';var windowTitle = 'Create new application';LoadContentInWindow('Window', url, windowTitle);} // Open Window - edit applicationfunction OpenWindow_EditApplication(appID) {OpenWindow('Window', 'Loading content, please wait...');var url = '@(Url.Action("_application_edit", new { Controller="Applications", Area = "Config"}))';url += '?ApplicationID=' + appID;var windowTitle = 'Edit application';LoadContentInWindow('Window', url, windowTitle);} // Close Window - create new applicationfunction CloseWindow_CreateNewApplication() {CloseWindow();} // Close Window - edit applicationfunction CloseWindow_CreateEditApplication() {CloseWindow();} function Window_onClose() {RefreshGridData("Application");} // Build a hyperlink for Gridfunction GetLink(appID) {return "<a class='t-button' href='/config/applicationfeatures/index/" + appID + "'>Features</a>";} function GetButton(appID) { return "<button class='t-button t-button-icon' type='button' onclick='OpenWindow_EditApplication(" + appID + "); return false;'><span class='t-icon t-edit'></span></button>";} // Hack to fix command buttonsfunction Grid_onDataBound(e) {FixCustomCommandButton("Application", "CustomEditCommand", "t-edit");} function Grid_onCommand(e) { if (e.name == "CustomEditCommand") { // Get the data item var dataItem = e.dataItem; // Get the ApplicationIDvar AppID = dataItem.ApplicationID; // Open the window for this application IDOpenWindow_EditApplication(AppID); // This is requirede.preventDefault();}} </script> <h2>Applications</h2> @(Html.Telerik().Grid<Application>().Name("Application").DataKeys(keys => keys.Add(c => c.ApplicationID)).ClientEvents(clientEvents => {clientEvents.OnCommand("Grid_onCommand");clientEvents.OnDataBound("Grid_onDataBound");// clientEvents.OnError("Grid_onError");}).ToolBar(commands =>{commands.Custom().HtmlAttributes(new { @onclick = "OpenWindow_CreateNewApplication(); return false;" }).ImageHtmlAttributes(new { @class = "t-icon t-add" }).ButtonType(GridButtonType.ImageAndText).Text("Add new application");}).DataBinding(dataBinding => dataBinding.Ajax().Select("_Select", "Applications", new { Area = "Config" }).Insert("_Create", "Applications", new { Area = "Config" }).Update("_Edit", "Applications", new { Area = "Config" }).Delete("_Delete", "Applications", new { Area = "Config" })).Columns(columns =>{ // Custom edit buttoncolumns.Command(commands => {commands.Custom("CustomEditCommand").ButtonType(GridButtonType.Image).Ajax(true).Text("Edit");}).Width(50); //columns.Bound(o => o.ApplicationID).ClientTemplate("<div id='RowBT_<#= ApplicationID #>'></div><script>$('#RowBT_<#= ApplicationID #>').html(GetButton('<#= ApplicationID #>'))</script>").Filterable(false).Title("").Width(100);columns.Bound(o => o.ApplicationID).ClientTemplate("<div id='Row_<#= ApplicationID #>'></div><script>$('#Row_<#= ApplicationID #>').html(GetLink('<#= ApplicationID #>'))</script>").Filterable(false).Title("").Width(100);columns.Bound(o => o.ApplicationID).Width(50);columns.Bound(o => o.ApplicationName).Width(200);columns.Bound(o => o.ApplicationRoleName);columns.Bound(o => o.IsActive).Width(200);columns.Bound(o => o.IsAdminTool); columns.Command(commands =>{commands.Delete().ButtonType(GridButtonType.Image);}).Width(50);}).Editable(editing => editing.Mode(GridEditMode.PopUp).TemplateName("_application_edit").Window(config => config.Scrollable(true).Height(500).Width(700).Resizable(r => r.Enabled(true).MinHeight(500).MinWidth(700).MaxHeight(3000).MaxWidth(3000)))).Resizable(resizing => resizing.Columns(true)).Sortable().Filterable()) @Html.Partial("_pviewTelerikWindow")
and since I'm feeling a good mood - I'll give you some more code...
function OpenWindow(windowID, loadingMessage) { loadingMessage = (typeof loadingMessage == "undefined") ? ' Loading content, please wait...' : loadingMessage $("#" + windowID).data("tWindow").center().open(); $("#" + windowID).data("tWindow").title("Loading..."); $("#" + windowID).data("tWindow").content("<div style='padding: 10px;'><img src='/Content/Images/Misc/ajax.gif' alt='Loading...'></img> " + loadingMessage + "</div>");} // Load contentfunction LoadContentInWindow(windowID, url, windowTitle) { $("#" + windowID + " .t-content").load(url, function (response, status, xhr) { if (status == "error") { ReportJavascriptError(response, status, xhr); } else { $("#" + windowID).data("tWindow").title(windowTitle); } });} function ConfigEditPopup(e, windowTitle) { $(e.form) // Get the form .closest(".t-window").width(700).height(500) // Set standand width and height .css("marginLeft", 0) // Browser centres the popup (rather than column grid centre) .data("tWindow") // Get the data part of the window element .title(windowTitle) // Set the window title .center(); // Centre the window}
OOPPS almost forgot the credit view (credit = cr (create) and edit (edit) together -CRedit.
I thought this was clever at the time but I will maybe steer clear of financial apps for the time being! :)
@model MVC.Areas.Config.ViewModels.ApplicationCreditViewModel<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>@if (ViewBag.MessageBox != null){ @Html.Partial("_pviewEventInfoBox", (Information.MessageBox)ViewBag.MessageBox)}@if (Model != null){ string formID = "ds-ajax-form-application-create"; string applicationLoadingID = "ds-ajax-form-application-processing-create"; string message = @ViewBag.DatabaseUpdateMessage ?? ""; string postTo = @Model.ApplicationID == 0 ? "_application_create_insert" : "_application_edit_update"; string saveButtonText = @Model.ApplicationID == 0 ? "Add new application" : "Update application"; bool isInsert = @Model.ApplicationID == 0 ? true : false; <div id="@formID" > @using (Ajax.BeginForm(postTo, "Applications", new AjaxOptions { UpdateTargetId = @formID, InsertionMode = InsertionMode.Replace, LoadingElementId = @applicationLoadingID, LoadingElementDuration = 0 })) { if (@Model != null) { @Html.ValidationSummary(true) @Html.HiddenFor(model => model.ApplicationID) <div class="editor-label"> @Html.LabelFor(model => model.ApplicationName) </div> <div class="editor-field"> @Html.EditorFor(model => model.ApplicationName) @Html.ValidationMessageFor(model => model.ApplicationName) </div> <div class="editor-label"> @Html.LabelFor(model => model.ApplicationURL) </div> <div class="editor-field"> @Html.EditorFor(model => model.ApplicationURL) @Html.ValidationMessageFor(model => model.ApplicationURL) </div> <div class="editor-label"> @Html.LabelFor(model => model.ApplicationRoleName) </div> <div class="editor-field"> @Html.EditorFor(model => model.ApplicationRoleName) @Html.ValidationMessageFor(model => model.ApplicationRoleName) </div> <div class="editor-label"> @Html.LabelFor(model => model.IsActive) </div> <div class="editor-field"> @Html.EditorFor(model => model.IsActive) @Html.ValidationMessageFor(model => model.IsActive) </div> <div class="editor-label"> @Html.LabelFor(model => model.IsAdminTool) </div> <div class="editor-field"> @Html.EditorFor(model => model.IsAdminTool) @Html.ValidationMessageFor(model => model.IsAdminTool) </div> <p> <input class="t-button t-button-icontext " type="submit" value="@saveButtonText" /> <span id="@applicationLoadingID" style="display: none;"> <img src="@Url.Content("~/content/images/misc/ajax.gif")" alt="Loading...."/> </span> </p> <p> <button class="t-button t-button-icontext t-button-bare" type="button" onclick="CloseWindow(); return false;"> <span class="t-icon t-arrow-prev"></span>Cancel</button> </p> } } </div> }
Well there we go - bits and pieces missing. Let me know if you want/need them.
Wish I got telerik credits for this sharing of advanced techniques :D
Let me know if you have any specific questions Mr. Phil.
All the best,
Dan.
0
Dan
Top achievements
Rank 1
answered on 04 Apr 2012, 08:50 PM
Oh and this is my final code for fixing the edit button (but I don't tihnk it will be a problem once next release is out).
function Grid_onDataBound(e) {
FixCustomCommandButton("Application", "CustomEditCommand", "t-edit");
}
function FixCustomCommandButton(gridID, commandName, iconName) {
$("#" + gridID + " .t-grid-" + commandName + " .t-" + commandName).attr("class", "t-icon " + iconName);
}
0
Phil
Top achievements
Rank 1
answered on 04 Apr 2012, 09:23 PM
Blimey Dan, that's a thorough respose:-). Amusingly I think the bit i'm most interested in (controller actions to handle crud) is not there;-)
Will have a good read in the morning. Might have a look at castle. I'm using a service layer, wcf and repository layer but domain driven design rather than EF.
Thanks a lot. Owe you a beer.
Phil
Will have a good read in the morning. Might have a look at castle. I'm using a service layer, wcf and repository layer but domain driven design rather than EF.
Thanks a lot. Owe you a beer.
Phil
0
Jeremy
Top achievements
Rank 1
answered on 31 May 2012, 05:41 AM
Hi Dan,
Can you explain why the .TemplateName("_application_edit") option is needed on the grid also?
Thanks!
I see there's a custom command that opens the edit window and loads the content.
I also see that the grid is set to "Editable" with this line:
.Editable(editing => editing.Mode(GridEditMode.PopUp).TemplateName("_application_edit").Window(config => .......Can you explain why the .TemplateName("_application_edit") option is needed on the grid also?
Thanks!
