This is a migrated thread and some comments may be shown as answers.

Bind grid in editor template

5 Answers 628 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Joe
Top achievements
Rank 1
Joe asked on 16 Jul 2012, 04:31 PM
I am using an editor template to edit an entity that is represented by a view model. I have a grid in the editor template that in order to bind needs to have the primary key of the model passed to it in order to bind the images. How do I accomplish this?? Here is what I am currently doing which is NOT working:

From the grid .DataSource property:
.Read( read => read.Action( "BindImages", "CatalogAdministration" ).Data( "bind_images" ) )

"bind_images" javascript function:
function bind_images() {
 
    var grid = $("#GridInventoryItems").data("kendoGrid");
 
    grid.select().each(function () {
 
        var dataItem = grid.dataItem($(this));
 
        key = dataItem.InventoryItemId;
 
    });
 
    return {
        inventoryItemId: key 
    };
}

"BindImages" method in the controller:
public JsonResult BindImages( int? InventoryItemId )
{
    JsonResult result = null;
 
    if( InventoryItemId.HasValue )
    {
        result = Json( _GetImageViewModelRecords( InventoryItemId ) );
    }
 
    return result;
}

What is happening is that in the javascript function, the "Key" is always the previously edited record (because I don't know how to get the ID of the record beign currently edities, it looks like I am just grabbing the key of the selected row which is always going to be 1 behind). SO my first issue is how do I get the key of the row being edited?

Secondly, even when a valid ID is passed to the controller method and data is returned, it is never loaded into the grid. What am I doing wrong?

Instead of the .Data and passing a javascript function can't I just add to the route values using the .Route property? If so, how?

Any help is appreciated. Thanks!!

5 Answers, 1 is accepted

Sort by
0
Joe
Top achievements
Rank 1
answered on 16 Jul 2012, 05:32 PM

Still not able to get this working. So let me try to explain a little better. My outer grid represents records from a view model. The view model represents an inventory item. The inventory item view model has a property called "Images" which is a list of ImageViewModels. When the master grid is being edited, I want the edit form to represent the images with a grid that can be easily added to or have items removed from. Ideally, the grid would just bind itself to the list of images in the model without having to go back and query for the data, but I can't seem to get that to work.

Here is my grid:

@(Html.Kendo().Grid( Model.Images )
    .Name( "GridImages" )
    .DataSource( dataSource => dataSource
        .Ajax()
        .Model( model => model.Id( i => i.ImageId ) )
        .Destroy( destroy => destroy.Action( "ImageDelete", "CatalogAdministration" ) )
        .Create( create => create.Action( "ImageCreate", "CatalogAdministration" ) )
    )
    .BindTo( Model.Images )
    .AutoBind( false )
    .Columns( columns =>
    {
        columns.Bound( image => image.ImageId ).Width( 100 )
            .ClientTemplate( "<img width='100' height='110' alt='#= ImageId #' src='"
                + Url.Content( "~/Content/Images/Product Images/" )
                    + "#= FileName #' />" ).Title( "Image" );
        columns.Bound( image => image.FileName );
        columns.Command( commands =>
            commands.Destroy() );
 
    } )
    .PrefixUrlParameters( false )
    .Scrollable( scrolling => scrolling.Enabled( true ) )
    .Sortable( sorting => sorting.Enabled( true ) )
    .Pageable( paging => paging.Enabled( false ) )
    .Filterable( filtering => filtering.Enabled( false ) )
    .Groupable( grouping => grouping.Enabled( false ) )
    .Resizable( resizing => resizing.Columns( true ) )
    .Events( events =>
        events
            .Remove( "onImageDelete" )
    )
    .HtmlAttributes( new
    {
        style = "width:500px"
    } )
)

I am not specifying the "read" property in the data source because I was hoping to just be able to bind it to the image list that is already in the model using the "BindTo", but when I do this nothign is ever loaded. If I specify a "Read" property then I have to go back to the controller and query the database again which works fine for existing records but does not work for new records (it will end up getting the image list from whatever row was previously selected). How is the "BindTo" supposed to work?

I have also tried this:

.Read( read => read.Action( "BindImages", "CatalogAdministration" ).Data( "setRouteValues('" + Model.InventoryItemId + "')" ) )

which would be perfect except the model is always empty. Of course. So how can I pass the ID to the javascript function or whether or not it is a new record vs. an existing record?

Thanks!

0
Joe
Top achievements
Rank 1
answered on 17 Jul 2012, 02:58 PM
FYI the way I was able to get this to work correctly using the standard Telerik MVC grid was to subscribe to the "DataBinding" event of the Images grid and set the route value there, however there is no longer a databinding event, just a DataBound event which fires too late. Why are events that were available in the Telerik grid not available any more? This is making converting the app a huge pain.
0
Joe
Top achievements
Rank 1
answered on 17 Jul 2012, 04:13 PM
Yet another way that doesn't work but should:

On my EditorTemplate:

@Html.HiddenFor( i => i.InvItemId )

And on the Images Grid Read Property:
.Read( read => read.Action( "BindImages", "CatalogAdministration" ).Data( "setRouteValues" ) )

And in the "setRouteValues":
function setRouteValues() {
 
    alert($("#InvItemId").val);
 
    return {
        InventoryItemId: key
    };
}

The alert is just alerting a massive function, not the value of the hidden field. If I could refernce the hidden field value here, I might be able to make it work, but no dice.

UPDATE: I was able to reference the field with document.getElementById BUT it is always 0 because grid in the editor template calls the "setRouteValues" method BEFORE the other data is even loaded on the form. What kind of sense does that make? This hidden field should be loaded before the grid fires off its read method. This is getting very old. It shouldn't be this hard to port functionality from the MVC grids.

I could also accomplish what I need by being able to determine if a grid is in edit or add mode from the setRouteValues javascript function but I have scoured all the properties of the grid at that stage and see no indication of the mode.

What is really irritating is that I shouldn't even have to be doing this. The records ARE in the model already, why do I need to hookup to the "Read" datasource property and make another trip to the server when I already have the records in the underlying model? I just want to bind the grid to records that already exist in the model. There has to be a way...
0
Joe
Top achievements
Rank 1
answered on 17 Jul 2012, 07:02 PM
Finally got this working but it seems like a hack to me.

Updated my javascript setRouteValues function to this:
function setRouteValues(e) {
    key = 0;
    setInventoryItemId();
    return {
        InventoryItemId: key
    };
}
function setInventoryItemId(e) {
 
    var grid = $("#GridInventoryItems").data("kendoGrid");
 
    grid.select().each(function () {
        var dataItem = grid.dataItem($(this));
        key = dataItem.InvItemId;
    });
}

This way it sets the ID to the actual record being edited when the edit button is clicked and sets the id (and leaves it set) to 0 for a new item. I still think I should just be able to bind right to the items in the model rather than go back to the server again and have to go through all of this.








0
Steve
Top achievements
Rank 1
answered on 29 Jul 2018, 07:08 PM

I used Alex's answer here to solve a similar issue. https://www.telerik.com/forums/pass-grid-view-model-data-to-editor-template

 

Tags
Grid
Asked by
Joe
Top achievements
Rank 1
Answers by
Joe
Top achievements
Rank 1
Steve
Top achievements
Rank 1
Share this question
or