40 Answers, 1 is accepted
The select command works only in server bound mode current. In order to make it work in ajax binding you have to create a column which contains the action link and use the client-template to supply data to the action method. Here is a codesnippet:
columns.Add(c => c.CustomerID).ClientTemplate("<a href='/Controller/Action?id=<#= CustomerID #>'>Select</a>");
Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
The funcionality I search is the same as .Toolbar(actions => actions.Custom().Action("Action","Controller") to place custom actions at the top of the grid, but instead, for each row... anyway I guess for your response that nothing like that is supported at this moment.
Is there any way I could inherit or implement interfaces to any of your classes to create it? can you give me some guidelines? And, will you support this feature in a future release?
For now, I have found a semi-solution for selecting a row clicking on any part of it... as follows:
The grid is declared something like this:
| <%= |
| Html.Telerik().Grid<myClass>() |
| .Name("xxxxx") |
| .... |
| .ClientEvents(events => |
| events.OnRowSelected("rowSelected") |
| .OnRowDataBound("rowDataBound") |
| .Selectable() |
| .... |
| %> |
Then I define this 2 functions in javascript:
| function rowDataBound(e) { |
| e.row.rowid = e.dataItem.Id; |
| } |
| function rowSelected(e) { |
| document.location.href = "/controller/action/" + e.row.rowid; |
| } |
This works, but I think it's not the best way to do something as trivial as selecting a row in a grid, and additionally, if you put any kind of button in that grid, when you click the button, it also executes my javascript so it rends the buttons useless..
Thank you in advance.
We will implement custom commands for the commands column but I cannot commit with a deadline - it is not yet decided when we are going to do this. We would also enhance the select command to work with ajax binding scenarios too.
In your case I recommend you use jQuery and subscribe to the select buttons click event:
<% Html.Telerik().ScriptRegistrar().OnDocumentReady(() => {
%>
$('.t-grid-select').live('click', function (e) {
e.preventDefault();
location.href = "/controller/action?id=" + $(e.target).closest('tr')[0].rowid;
});
<% }); %>
Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
We are having the same issues as mentioned above and would really like the possibility to add custom column commands (on top of Edit and Delete) to redirect to custom ActionResult methods in the controller. Is this still not possible or has this functionality been released recently?
Kind regards
Victor Ström
Yes, this is still not possible. As a workaround you can use a template column and add the required buttons there.
Regards,Atanas Korchev
the Telerik team
Using razor and looking at some examples from you and some external we have managed to get half-way. Unfortunately the Ajax binding is not working as it should, could you give us any pointers on how to include the Id in the client-side link?
.Columns(columns =>
{
columns.Bound(r => r.Name);
columns.Bound(r => r.Type);
columns.Template(@<a href="/RightsAdministration/Roles/Permission/@item.Id">Test</a>)
.ClientTemplate(@"<a href='/RightsAdministration/Roles/Permission/' + Id>Test</a>")
.Title("Test");
columns.Command(commands => {
commands.Edit();
commands.Delete();
});
})
/Victor
Try this:
.ClientTemplate("<a href='/RightsAdministration/Roles/Permission/<#= ID #>'>Test</a>")
Regards,Atanas Korchev
the Telerik team
/Victor
As far as I can tell, there are still only row-based commands for Select, Edit and Delete.
Yes, we can use .ClientTemplate and whatever other work-arounds, but for consistency and readability of code, why can't we have a custom command to go with the other commands?!?
I think of a .ClientTemplate for display!!! possibly even for display of a link to another page at some other website elsewhere, but not for triggering an interactive action command (like select, edit, delete) on the data of the current website where you're trying to do data processing of some kind.
So if you want to promote readability and comprehensibility of code, in my opinion, we do need a custom command that works like the current select/edit/delete row-based commands. And all of these row commands should have an easily configurable way to specify the image source file for the image buttontype used for the command button, as well as the method that is triggered by clicking on the command button.
Ideally, it would be something like the GridButtonColumn or Grid*CommandColumn(s) in the grid from RadControls for ASP.net AJAX. In fact, it will be great if/when the MVC grid has more of the features available in the RadControls grid....
This suggestion makes perfect sense and I logged it for public tracking. You can vote for it here. I also updated your Telerik points.
Regards,Atanas Korchev
the Telerik team
http://www.telerik.com/community/forums/aspnet-mvc/grid/inconsistency-in-ajax-binding-for-update-delete.aspx
All of these row-based commands whether select/insert/update/delete or custom should have a consistent and convenient interface that is easy to understand and use. If you are a developer using the Telerik MVC extensions, please vote up this feature request at
http://www.telerik.com/support/pits.aspx#/public/aspnet-mvc/5485
However, any help from Telerik with current workarounds would be appreciated because I continue to have difficulties with these row-based commands.
I am attempting to use the approach with ClientTemplate(), and an <a> tag like this:
.ClientTemplate(
"<a href='~/AdminResreps/ValidateNexusResource/<#= ResourceIidKey #>' class='t-button'>Validate</a>"
);
Note that I am using class='t-button' so that the appearance is the same as the other Telerik buttons. But I cannot get the right href. What should I get when I use the "~"? What should I get when I use the "#"? And I do know what they usually mean, but they don't seem to work that way here in the Telerik grid. For example, this version:
.ClientTemplate(
"<a href='../ValidateNexusResource/<#= ResourceIidKey #> class='t-button' >Validate</a>");
displays the correct URL with host and correct path in the browser status bar, but when clicked on then goes to the wrong URL without the host
So how do I get the correct href value for an MVC route that should normally go to a default route like this:
routes.MapRoute(
"PdsDefault", "{controller}/{action}/{id}"
,
Thanks. And again most of these confusions and difficulties would be solved by having a row-based custom command that can be used in the Telerik grid in a manner consistent with the current row-based edit/delete commands.
You can use the right href easily:
"<a href='" + Url.Content("~/AdminResreps/ValidateNexusResource/") + "<#= ResourceIidKey #>' class='t-button'>Validate</a>"Atanas Korchev
the Telerik team
I've now tried that approach and a variety of other approaches. Here's the final solution that I've decided to use. In the View, the relevant code for the custom command column:
col.Bound(row => row.ResourceIidKey).Title("").Sortable(false).Filterable(false)
.EditorTemplateName("ResourceIidKey")
.ClientTemplate("<a class='t-button' onclick='OnValidateResourceButtonClick(<#= ResourceIidKey#>)'>Validate</a>");
Note that there is an <a> tag and class attribute 't-button' assuring that the command column button appears the same as the other default Telerik command buttons. In the template file ResourceIidKey.cshtml for the EditorTemplate:
@Html.Display("")
which prevents the command column button from being displayed when in edit mode and without needing any extra JavaScript events. I have not tested whether a completely empty template file works but using @Html.Display("") with an empty string certainly does work, and it is "clean" in the sense that the column data for the ResourceIidKey is NOT written and then subsequently hidden via JavaScript.
And for the <a> tag onclick in the ClientTemplate, I am using the .post JQuery function like this:
function OnValidateResourceButtonClick(id) {
$.post("/AdminResreps/ValidateNexusResource/" + id, null,
function () { $("#NexusResources").data("tGrid").rebind(); }, "json");
}
So now that I am satisfied with this solution for a custom command, it raises the question of how to modify and customize the default commands for insert/update. For the examples in the Telerik documentation where the entire list of rows and the entire View is rebuilt, that seems unnecessary when really only a single row has been updated. So how to modify the default insert/update commands to return and rebind only a single row instead of the entire view? Is the best approach to modify them in Javascript after selecting them via class attributes? The command elements do not appear to be generated with id attributes so it's not possible to select them with ids.....
Indeed the command buttons don't have an id. The reasons is that ids must be globally unique and the grid is not using any id generation scheme to guarantee that.
You cannot change the default behavior of the edit, delete and insert commands. What you can do is implement entirely custom commands which do the same - in a way similar to what you have done so far. Unfortunately we don't have an example showing how to implement grid editing with custom column commands. Still you can use the following grid JavaScript methods (currently undocumented):
grid.editRow(tr) -> will switch a row (DOM element) to edit mode
grid.cancelRow(tr) -> will switch a row back to display mode
grid.addRow() -> will insert a new empty row at the top
There is the
grid.saveRow(tr) method but you should not use it as it will rebind the grid which you are trying to avoid.
Atanas Korchev
the Telerik team
I followed your instruction however, the link/button/ect only show up when I refresh page using ajax, or switch to a new page
The very first time it just doesn't work and show all the Id (bounded field) instead of the desired button
I'm using MVC3 with Razor syntax and this is my code
.Columns(columns => { columns.Bound(c => c.Id).Width(100); columns.Bound(c => c.Content).Width(200); columns.Bound(c => c.Description); columns.Bound(c => c.ReportedDate).Format("{0:dd/MM/yyyy}").Width(120); columns.Bound(c => c.Id) .ClientTemplate(string.Format("<a class='t-button' href='javascript:approve(<#= Id #>)'>Validate</a>")) .Title("Approve"); columns.Command(c => c.Delete()); })And this is my reference in _Layout page
@(Html.Telerik().StyleSheetRegistrar() .DefaultGroup(group => group.Add("telerik.common.css") .Add("telerik.windows7.css") .Combined(true) .Compress(true))) @(Html.Telerik().ScriptRegistrar() .DefaultGroup(group => group .Compress(true)) )That's because the examples are using the client-side template. Your grid is most probably bound server side initially. You need server side templates in this case.
Regards,Atanas Korchev
the Telerik team
Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!
So if the row-based custom command is triggered from a row on page 5 of 10 pages, then it gets executed correctly, but the paging mechanism does not work properly and just goes back to page 1 which is NOT good for the user who expects the AJAX server request to return to the same page 5 of 10 from which the request was triggered, and not page 1.
So could you please expand the demo at
http://demos.telerik.com/aspnet-mvc/grid/hierarchyajax
to clearly and explicitly explain the design pattern to use for a row-based custom command that will work in a manner similar to the regular insert/update/delete row-based commands while preserving an AJAX request-response that returns to the same page from which it was triggered?
And for everybody else, please continue to vote up the feature request at
http://www.telerik.com/support/pits.aspx#/public/aspnet-mvc/5485
for better row-based custom command support. Thanks!!!
Also, when can we expect to see more systematic and complete documentation with examples of the Telerik jQuery client-side API for the Telerik MVC Grid???
Custom commands have been scheduled for the Q3 2011 release. We will update PITS shortly. I am sorry for the confusion created.
In order to preserve the current grid state (paging, sorting, filtering, grouping) it must be sent with every request to the action method which feeds the grid with data. The edit commands currently support this out of the box. Implementing the same in a custom command now is possible too but will require some code. A similar implementation can be seen here. The code which updates the grid state is this:
function onDataBound() { var grid = $(this).data('tGrid'); // Get the export link as jQuery object var $exportLink = $('#export'); // Get its 'href' attribute - the URL where it would navigate to var href = $exportLink.attr('href'); // Update the 'page' parameter with the grid's current page href = href.replace(/page=([^&]*)/, 'page=' + grid.currentPage); // Update the 'orderBy' parameter with the grids' current sort state href = href.replace(/orderBy=([^&]*)/, 'orderBy=' + (grid.orderBy || '~')); // Update the 'filter' parameter with the grids' current filtering state href = href.replace(/filter=(.*)/, 'filter=' + (grid.filterBy || '~')); // Update the 'href' attribute $exportLink.attr('href', href); }As for documentation please do let us know how to improve the existing one. Tell us why you don't find it systematic and what you think is missing.Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
As mentioned in previous post earlier this week, and as described in detail in the solution I posted on April 19 in this same thread, I am looking for a design pattern that is appropriate for row-based custom command that will appear in every row just like the Insert/Edit/Delete buttons appear in every row.
And that is why I asked Telerik to extend the demo for the AJAX binding for Master-Detail hierarchy at
http://demos.telerik.com/aspnet-mvc/grid/hierarchyajax
to include a design pattern for a row-based custom command. Wouldn't it be better to store a single copy of the necessary paging data perhaps in a session variable, and then access that? Or must it be repeated for each and every row? In any event, a working demo would be appreciated.
And as far as the existing documentation is concerned, it does have a list of client-side events, but where is the list of all the client-side object and variable names (for example, 'tGrid' for the grid itself) that the developer needs to know to effectively use the client-side events and the Telerik jQuery JavaScript file that has been minified. I looked for a non-minified version (appropriately formatted and documented) but could not find it in my copy of Telerik MVC. Is there a non-minified, formatted and documented version of the JavaScript file for the Telerik MVC grid?
The grid needs to pass to the server side (the action method) the current page, filter, sort and grouping info.
For server bound grid custom commands will render the grid info as part of the url (as the edit command currently does). For ajax bound grids the command will automatically include that info as the grid has it stored.
Which scenario are you interested in right now - ajax or server binding? Could you provide a small running project where you have a custom command which is losing the grid paging? We will check it out and assist with the implementation.
Storing the current page, sort, filter and grouping info in the session is a possible workaround but will not be a clean solution. Lots of people disable session state.
As for documentation you are asking for a list of all client-side object and variable names. I am not sure what you mean by that. We do not support private method or variable access. There are a few public methods which are not documented and we will do so shortly.
The complete source is available in the Source folder of your Telerik Extensions for ASP.NET MVC distribution.
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
However, in every post in this thread, I have always stated that I am talking about the client-side AJAX scenario including the previous posts and the April 19 post in this thread where I explicitly provide the client-side code that I am using for the solution.
As far as client-side JavaScript object names, I am talking about any names expected and used by the Telerik client-side JavaScripts like "tGrid" for objects like the grid itself. Certainly, any of the names for any of the objects that we need to know in order to use the jQuery JavaScript files from Telerik that control use of the Telerik MVC grid for AJAX calls from client side with client-side events. If we have to know the name of the object in order to access it in the client-side event, then that is something that should be documented.... or how else are we supposed to use the client-side events???
And as far as demo that would be most useful for me (and I assume other Telerik customers), I will continue to repeat my request for an extended version of the current demo for the AJAX binding for Master-Detail hierarchy at
http://demos.telerik.com/aspnet-mvc/grid/hierarchyajax
to also include a design pattern for a row-based custom command. There are many reasons why I continue to repeat my request for an extension of this current existing demo to include a design pattern for a row-based custom command... not the least of which is that it makes absolutely clear that we are talking about the clientside AJAX scenario, in a realistic environment of a master detail grid where each row should have insert/edit/delete buttons, as well as a row-based custom command, and be compatible with paging so that the AJAX request-response cycle returns the grid back to the same page from which the row-based custom command was triggered.
Getting the client-side object is documented here. Every single component contains such a section in its Client API and Events help topic. Also in every client-side event we include a short code example showing how to get the instance of the component e.g.:
Handling the OnLoad event<script type="text/javascript"> function Grid_onLoad(e) { //`this` is the DOM element of the grid var grid = $(this).data('tGrid'); //event handling code }I think that we have duly documented how to get the client-side object inside and outside of event handlers. If this is not sufficient please let me know what is missing. As for the example I do not understand this "include a design pattern for a row-based custom command". Please let me know what the custom command should do in this case and I will prepare an example right away. Otherwise I can only prepare a custom command which will rebind the grid.
Regards,
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
So how about a row-based custom command that demonstrates a "hello world from row = id key" and display it in a status message in the toolbar at the top of the grid.
And as far as documentation, it is clear to me that there are very different expectations and attitudes about the nature and quality of documentation.
I am an older generation software engineer who began programming in the 1970's. Back then and at least for several decades up through the 1990's, no software company could expect any reputation of quality if it failed to produce systematic high quality documentation for its software function libraries used for development. Systematic always meant comprehensive and catalogued both alphabetically and topically.
The greatest cause of loss of time in today's world of software results from the absence of the high quality documentation that used to be required in the industry. Much of the younger generation does not even know what the older generation used to be able to benefit from. Now it's more or less what I call "documentation by forum question and answer and search through forums" rather than a simple quick and easy lookup in an alphabetical listing or topical listing... Another cause of difficulties is that now documentation always seems to lag several quarters behind the release of the actual software.
And one of the great benefits of an improvement in the quality of documentation would be LESS TIME spent by Telerik answering the same questions again and again in the forums.
A demo which displays "hello world from row = id key" does not need to go to the server and rebind the grid. The current data key can be easily retrieved using the dataItem method. Then JavaScript can be used to update the toolbar of the grid. I don't think the grid state needs to be maintained in this case as the grid is not refreshed. Could you please describe a scenario in which you need to make a request to the server and pass the grid state to the action method? The best thing I can think of is to just return the grid state back as JSON which does not make much sense.
As for documentation it is still not clear what your point is. Please specify a concrete topic or content which is lacking. Tell us which part is not comprehensive and what level of comprehensiveness you expect.
Regards,
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
I am convinced that no matter what I write that you'll find something wrong with it, and therefore a reason not to create the requested demo... as if you cannot yourself imagine a scenario that demonstrates the requested functionality... even if it is a "mock" or "dummy" scenario... as if there are no simple validation or status checks on an individual row that do in fact necessitate an AJAX server request analogous to the insert/edit/delete AJAX server requests on each row.
Same with documentation... I'm sure that you'll find something wrong with what I've said... so I'll just have to generate the list myself and then I'll post it here as a demonstration of what has not been documented
Ok, I will create a dummy example which will send the current page and sorting order for the grid etc. Will attach it to this thread.
As for documentation - you said that the whole documentation style is not what you expected and that's what I asked you to elaborate on. I totally agree with you that there are some things missing from the public API which we will address shortly.
Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Please find attached the sample project. It is based on the ajax hierarchy example. There is a custom command in both the child and ajax grid. It passes the current page, key and sort order to an action method and alerts the result (which is the same in JSON format).
Best regards,Atanas Korchev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
I want to follow up with a short description of what the custom commands would look like. Your feedback will be appreciated!
Here is a code snippet showing what we currently plan to support:
Html.Telerik().Grid<Customer>() .Columns(columns => { // Declare a custom command columns.Command(commands =>commands.Custom() // Set its text .Text("Show Details") // Option name .Name("detail") // Specify button appearance (if needed) .ButtonType(GridButtonType.ImageAndText) // Specify the path to the image (if any) .ImageUrl("~/Content/icon.png") // All data keys of the grid will be passed to that action .Action("Details", "Home") // Add route values for ajax binding scenarios using client template expressions .Action("Details", "Home", new { id = "<#= CustomerID #> }) // Pass additional route values for server binding scenarios. Note that "action" and "controller" are required. // The reason is that an instance of the model should be provided .Action(c = > { action="Details", controller="Home", id = c.ID }) // Whether to POST or GET (default). If POST is used a <form> will be created under the hood .Method(GridHttpVerb.Post) // Whether to send the grid state to the action method - current page, sort expression etc. Default to true. .SendState(false)
) })In addition the grid will support a new client-side event called "OnCommand" which will be raised when the user clicks on a custom command. The event arguments will provide the command name, dataItem and other data which may be useful.
What do you think? Are those options sufficient?
Looking forward to your feedback,
Atanas Korchev
the Telerik team
1) Using the MVC framework controller and actions, a developer can choose to return JSON data with model types that range from data for the full grid, to data for a single row in the grid, to data for a simple text display of a status message. Will the Telerik clientside OnCommand event support in a convenient way this full range of model types returned as data and be clearly documented for the developer?
2) Will there be ancillary support features for the MVC grid that assist any implementation of a custom command? For example, a convenient way to return both the row data returned for updating the specific row record that triggered the custom command and also a status message for display in the toolbar at the top of the grid? What about enabling an option for the grid that can be switched on/off that would automatically generate ids for each row in the grid (<tr> tags with row record ids) that could be used in conjunction with the custom command?
The question that I would be asking when testing a beta would be: Does the Telerik implementation of a row-based custom command make it more convenient for me and eliminate some of the extra client side JavaScript that I have to write myself to run a custom command for a particular row record, update the data for only that row record (and not the entire page of row records!), and also display a status message in the toolbar at the top of the grid. Or put more simply, will it enable me to eliminate all the client side JavaScript that I am writing myself now to do all of this each time I want to implement a row-based custom command?!?
Up to your questions:
- Custom commands will render as a link (for GET request) or button (for post request). Both way the custom button will navigate server side instead of making ajax. Perhaps you need a different custom button functionality which will make ajax requests and then raise another event (OnCommandComplete for example) and pass the result. Then you can update the current row (via custom JavaScript code) or rebind the grid (again via custom code). Will that suffice in your case? I don't think we can implement entirely codeless custom commands as there are quite many possible outcomes of a custom command. The OnCommand event will be raised before the request is made (server or client side).
- This would be supported if we decide to implement the AjaxCustomCommand. You would return whatever JSON you need and perform additional logic in the completion event. As for row ID generation - why is this required? Right now there is a JavaScript method which allows the developer to get the data item to which a certain table row is bound to. This is the dataItem JavaScript method. Could you use it instead?
Perhaps we will be most helpful if we see your current implementation and see how we can make this easier via custom commands. Sharing any code would help!
Atanas Korchev
the Telerik team
Very exciting news that this finally will be implemented. I agree that the server-side scenario would be the most common, but agree with Carl that a client-side option would be very helpful.
Some general syntax comments:
- ImageUrl - nice to have the option, but to me a css class way to specify the icon is almost necessary
- Action method options - I'm not sure I understand fully:
Action("Details","Home")//fine, normal behaviourAction("Details","Home",new{Area="MyArea", CustomArg="CustomVal"})//should be an option, but probably that is the case?Action(c => {action ="Details", ...})//quite strange semi-lambda syntax to me, probably nice to have, but I would much prefer something like:Action<ControllerType> ((contr, item) => contr.ActionName(item.FirstArg, item.SecondArg,"CustomArg"))//but maybe that is not possible?Action("Details","Home",new{id ="<#= CustomerID #>"})// I really dont like this syntax and never have - is there no way to get around this and make it strongly typed? maybe here the semi-lambda syntax could be used? I mean generally now and not just for custom row commands... Something like:Action(item =>newJsFunction("CustomJsFunction",true})// (SendGridState = true) orAction(item =>newJsFunction("CustomJsFunction", item.GridState, item.Arg1, item.Arg2,"customArg", ..., ..., ...}) - Text: Good - is there any possibility you could add this to Insert, Edit and Delete buttons as well?? Pretty please?
In general, I can see a three main ways one will want to use this:
- Direct to a custom edit page (server-side behaviour, no-fuss)
- Custom ajax behaviour (send custom arguments, return updated row data or full grid. Could be for example "mark as finished", "mark order as payed", etc
- Custom js behaviour (send custom arguments (including grid/grid state to a custom js function)
Optimally I would like to be able to specify a js-enabled behaviour (2 or 3) and a server-side fallback (1) with a "mode" switch or similair, quite similair to how edit/delete/insert can be set up right now.
Kind regards
Victor Ström
Up to your questions:
- ImageHtmlAttributes would be exposed instead of ImageUrl because it is more generic
- The "strange" semi lambda syntax is needed in order to pass the actual data item (of type T) so strongly type route generation is enabled e.g. Your suggestion to use the controller method is a really great idea! I hope we can implement that. The <#= #> client-side expression would remain if you want to use custom commands and route values for ajax bound grids. There is no clean way to translate arbitrary server code to a client-side template.
- Custom text for all commands has been requested before and makes a lot of sense. Unfortunately I am not sure if we can implement that for the next release. I can only say that we will do our best.
- Server fallbacks should be possible for ajax enabled commands. The API is not yet finalized though.
Thanks for the great feedback!
Regards,
Atanas Korchev
the Telerik team
Just one clarification, I'm probably missing something basic but anyway... Why is it not possible to avoid the <#= ... #> syntax? My initial suggestion was probably not correct, but it should be doable using expression trees and using them to extract "item => item.FirstArg" into the required "<#= FirstArg #>", but I realize it would be quite an undertaking to actually write an expression parser.
/Victor
Extracting a single property is doable. However what if the expression is arbitrary code? Something like c => if (c.Active) return c.FirstName.ToLowerCase() else return c.LastName.ToLowerString(). There is no way to convert code like this to runnable JavaScript code which can be interpreted by the browser.
This is the main reason we have been using client templates which use JavaScript instead of C# or VB.NET.
Atanas Korchev
the Telerik team
Well... Since currently such code cannot be reused anyway (it has to be written in javascript as a client expression) I fail to see the great use of it in general (it can easily be written in the receiving js function instead). Also - since the grid component in the current state gives different results in columns using server-side or ajax binding (simple enums would be one example) meaning you have to create specific properties in the view models to overcome these issues, I cannot see why this should be the any different. Given the choice of a strongly typed way of passing arguments vs the possibility to declare js logic inline when passing arguments to a custom function I would choose the first every time.
Still, I do understand that it probably is a lot of work to implement, but stating that the reason is that you can only use "raw" viewmodel properties seems a bit wrong to me.
However, as long as you provide a way to pass the data of the clicked row (on top of the usual grid event object of course) along with some custom (fixed) arguments to a custom js function i think there wont be any big problems.
/Victor
I couldn't understand your last comment. The reason of using <#= #> inside the route values is to bind them during ajax binding. As I said before we simply cannot use a C# expression to generate JavaScript out of it.
The simple use case is "Show Details" custom command which opens a new page and shows more details for the current record. If the grid is bound client-side you can use client-side template expressions to embed various properties of the data item in the route e.g. /Home/Details/<#= CustomerID #> will become /Home/Details/1.
Atanas Korchev
the Telerik team
I see your point about this being a practical way; I still argue that it should be possible (although not necessarily easy) to create a unified syntax for both server and client site request in most cases.
Slightly modified from earlier:Action<ControllerType> ((contr, item) => contr.ViewDetails(item.Id))could be code to go to /ControllerName/ViewDetails/item.Id. Given the possibility to parse expressions it should be possible to generate the url server-side with replacement tokens to use in javascript. We have ourselves done this using custom code (similair to var beforeReplace = @(Url.Action("ActionName", "Controller", new {Id=default(Guid)}))) - but maybe a generic solution is not that easy.
Anyway I look forward to start using the custom command columns soon!
/Victor
Just a quick follow up about the following idea:
Action<HomeController>((controller, o) => controller.Index(o.OrderID, "foo", "bar"))
We tried yesterday to implement this and had partial success. Unfortunately we discovered that this approach will not work in all cases. For example when binding to dynamic or DataTable. Having in mind this and the complexity of parsing the C# expression we decided to pursue a different approach for specifying route values. An approach similar to the way DataKeys are specified:
commands.Custom() // add constant route values here .Action("Index", "Home", new { constantRouteValue = "foo" }) .RouteValues(values => { values.Add(o => o.OrderID).RouteKey("orderId"); // send the OrderID property as "orderId" route key values.Add("CustomerID"); // send the CustomerID property as CustomerID });Also have in mind that by default the grid data key fields will be send as route values so there may not be a need to add route values at all. In addition you don't need to use client-side template expressions - we will do the translation as we do for the data keys.
Regards, Atanas Korchev
the Telerik team
Sounds promising! Maybe you could adjust the naming of "RouteValues" to reflect that only "row properties" should be specified there to avoid confusion with the "constant routevalues"?
In general, although not as elegant, I think the solution is certainly good enough. A bit sad that the action method cannot be strongly typed as it can throughout the rest of the grid component, but nice with a flexible solution never the less.
/Victor
commands.Custom() // add constant route values here .Action("Index", "Home", new { constantRouteValue = "foo" }) .RouteValues(values => { values.Add(o => o.OrderID).RouteKey("orderId"); // send the OrderID property as "orderId" route key values.Remove("ID"); // remove the ID property from the routevalues });