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

How to access DataKeys from JavaScript?

13 Answers 427 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
dstj
Top achievements
Rank 1
dstj asked on 06 Jul 2010, 11:28 PM
Hi,

I need to access the grid's DataKey from Javascript, but it is NOT displayed as a column. Is there standard, preferred way to do this? or it the solution presented by another user in this thread the only viable workaround ?

Here is my grid. Note that the ID property is not displayed...

   <% Html.Telerik().Grid<Account>(Model) 
         .Name("Grid") 
         .Columns(columns => 
         { 
            columns.Bound(x => x.Name); 
            columns.Bound(x => x.Email); 
            columns.Bound(x => x.Balance).Format("{0:C}"); 
         }) 
         .Filterable(filtering => filtering.Enabled(true)) 
         .DataKeys(dataKeys => dataKeys.Add(x => x.Id)) 
         .Render(); 
   %> 

Thanks,

Dominic.

13 Answers, 1 is accepted

Sort by
0
Sam Critchley
Top achievements
Rank 1
answered on 07 Jul 2010, 05:49 AM
This code assumes only one data key.

function rowSelected(e){  
    var grid = $(e.row).parents('.t-grid').data('tGrid');  
    var data = grid.data[$(grid.$tbody[0].rows).index(e.row)];  
  
    var id;  
    for (x in grid.dataKeys)  
        id = data[x];  
      
document.location.href = grid.ajax.updateUrl + '/' + id;  
}  

0
dstj
Top achievements
Rank 1
answered on 07 Jul 2010, 04:30 PM
Hi Sam,

Thanks for your reply. I tried your code, but grid.data and grid.dataKeys are undefined. Can you tell me how your grid is declared? Maybe that's the reason why those client-side properties are not set.

Thanks,

Dominic.
0
Sam Critchley
Top achievements
Rank 1
answered on 08 Jul 2010, 12:26 AM
Hi Dominic,

grid comes from that first line of code. Perhaps I should explain how this function is to be used. You should use it for the rowselected grid client event. So in you grid declaration include: .ClientEvents(p=>p.OnRowSelected("rowSelected"))

That said you can get access to grid at any time like so:

var grid = $('.t-grid').data('grid');

or

$('.t-grid').each(function(i, item){
var grid = $(item).data('grid');
});

Oh there's one another important thing. Maybe its the cause of your problem. You need to declare the grid editable otherwise the dataKeys and probably the data property are never created.

So add this to ur grid declaration:

.Editable(p=>p.Enabled(true))

0
dstj
Top achievements
Rank 1
answered on 08 Jul 2010, 10:50 PM
Hi again Sam,

Still, grid.data and grid.dataKeys are both undefined... don't know what I'm doing doing different from you...

Here is how my grid is declared :

<% Html.Telerik().Grid<Account>(Model)
      .Name("Grid")
      .Columns(columns =>
      {
         columns.Bound(x => x.AccountNumber);
         columns.Bound(x => x.Name);
         columns.Template(x =>{ %>
            <%= x.BillingCoordinates.GetFullName() %>
         <% }).Title("Contact");
         columns.Bound(x => x.BillingCoordinates.Email);
         columns.Bound(x => x.Balance.CurrentBalance).Format("{0:C}");
         columns.Bound(x => x.Balance.PendingBalance).Format("{0:C}");
      })
      .Scrollable(scrolling => scrolling.Enabled(false))
      .Pageable(paging => paging.Enabled(false).PageSize(50))
      .Sortable(sorting => sorting.Enabled(true))
      .Filterable(filtering => filtering.Enabled(true))
      .Groupable(grouping => grouping.Enabled(false))
      .ClientEvents(events => events.OnRowSelected("onRowSelected"))
      .DataKeys(dataKeys => dataKeys.Add(x => x.Id))
      .Editable(p => p.Enabled(true))
      .Selectable()
      .Footer(true)
      .Render();
%>

Javascript:
function onRowSelected(e) {
   //var grid = $('#Grid').data('tGrid');
   //var id = e.row.cells[0].innerHTML;
   var grid = $(e.row).parents('.t-grid').data('tGrid');
   var data = grid.data[$(grid.$tbody[0].rows).index(e.row)];
   var id;
   for (x in grid.dataKeys) {
     id = data[x];
   }
 
   window.location = "/Accounts/View/" + id;
}

Thanks for your help on this,

Dominic.
0
Sam Critchley
Top achievements
Rank 1
answered on 09 Jul 2010, 12:41 AM
Hmm... heres a bit of code from one of my pages that has datakeys working. I am using rowBound but I used to use rowBound. 

function rowBound(e) {
    $(e.row).find('.deletelink').click(function (ev) {
        ev.stopPropagation();
        ev.stopImmediatePropagation();
        ev.preventDefault();
         
        var grid = $(this).parents('.t-grid').data('tGrid');
        grid.deleteRow($(this).closest('tr'));
         
        return false;
    });
 
    $(e.row).click(function (ev) {
        var grid = $(this).parents('.t-grid').data('tGrid');
        var data = grid.data[$(grid.$tbody[0].rows).index(this)];
 
        var id;
        for (x in grid.dataKeys)
            id = data[x];
 
        document.location.href = grid.ajax.updateUrl + '/' + id;
    });
 
    if (typeof rowBoundExtras != 'undefined')
        rowBoundExtras();
}


    <%= Html.Telerik().Grid<DocumentListModel>()
            .Name("Grid")
            .DataKeys(p=>p.Add(x=>x.DocumentId))
            .Columns(columns =>
                {
                    columns.Bound(o => o.FileReference.MIMEType)
                        .ClientTemplate(@"<img src=""/documenticon/<#= FileReference.MIMEType.replace(/\//g, '_') #>.png"" alt=""<#= FileReference.MIMEType #>"" />")
                        .Sortable(false).Title(" ").Width(32);
                    columns.Bound(o => o.Title).ClientTemplate(@"<h4><#= Title #></h4><div class=""metainfo"">Uploaded by <#= CreatedBy #></a>").Title("Document");
                    columns.Bound(o => o.Category).ClientTemplate(@"<#= Category #><br/><div class=""metainfo"">Last updated <#= prettyDate(UpdatedOn) #></div><div class=""actionlinks""><a href=""#"" class=""deletelink"">delete</a><a href=""/filereference/servefile/<#= FileReference.FileReferenceId #>"">download</a>(<#= parseInt(FileReference.Size / 1024) #>kB)</div>").Title(" ").Width(260);
                })
            .DataBinding(db =>
                {
                    db.Ajax().Select("ListGrid", "Document");
                    db.Ajax().Delete("Delete", "Document");
                    db.Ajax().Update("Edit", "Document");
                }
            )
            .Editable(p=>p.Enabled(true))
            .ClientEvents(p=>p.OnRowDataBound("rowBound"))
            .Selectable(p => p.Enabled(User.IsInRole(Intranet.Core.Permissions.CanEditUnit)))
            .Sortable(p=>p.OrderBy(x=>x.Add(z=>z.UpdatedOn).Descending()))
            .Pageable()
            .EnableCustomBinding(true)
%> 
0
Steven
Top achievements
Rank 1
answered on 16 Jul 2010, 10:50 PM
The solution linked to at the top of this post did not work for me and after following the suggestions in this post, grid.data and grid.datakeys are null for me too so this is how I hacked my way around the problem in the javascript function called when a row is clicked:

function OnRowSelected(e) {
   
  // Find out which column contains Id values
  var grid = $(e.row).parents('.t-grid').data('tGrid');
  var indexOfIdColumn = -1;
  var counter = 0;
  for (var i = 0; i < grid.columns.length; i++) {
      var col = grid.columns[i];
      if (col.member = "Id") {
          indexOfIdColumn = counter;  // This is the column you are looking for. Move along.
          break;
      }
      counter++;
  }
   
  if (indexOfIdColumn < 0) {
      alert("I can't take you to the page you want because I couldn't find the ID column in the grid. This is a javascript error - please report a bug.");
  }
  else {
      // Grouping shifts the columns over so take this into account
      indexOfIdColumn = indexOfIdColumn + grid.groups.length;
 
      var row = e.row;
      document.location.href('/Account/Details/' + row.cells[indexOfIdColumn].innerHTML);
  }
}

Is it a hack? Yes. Is it brittle? Yes. Am I still tearing my hair out trying to fix this bug? No.
0
Alexandre Jobin
Top achievements
Rank 1
answered on 31 Aug 2010, 07:27 PM
its because your in 'server' mode. If you are in Ajax mode, you will have access to grid.data and grid.dataKeys

well, i think its the problem since that im in the same situation and this is the conclusion of my research!
i hope someday we will be able to have access to the data property wherever we are in Ajax or Server mode.
0
Atanas Korchev
Telerik team
answered on 01 Sep 2010, 06:59 AM
Hello Alexandre Jobin,

Indeed currently the grid does not serialize the data source during server binding. I think this makes sense in the default case. Perhaps we can introduce a setting to force data source serialization even during server binding. Still I am not sure users will know it exists and use it.

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
0
Alexandre Jobin
Top achievements
Rank 1
answered on 01 Sep 2010, 02:02 PM
for my needs, it would be great to have access to grid.data and grid.datakeys in Server mode. In my applications, i dont always need to be in Ajax mode but i still need to talk to the selected row and do something with the Id that represent the row.

Because we don't have access to the grid.data, i need to hide a column with the Id of the row and read that column but in Ajax mode, i don't have to do it. So theres two way to do the same thing depending if you are in Server mode or Ajax mode.

In my opinion, it would be great to be able to use the same javascript to read data independently of the mode you choose!

alex



0
Alexandre Jobin
Top achievements
Rank 1
answered on 22 Sep 2010, 07:22 PM
hi!

just wanted to know if this feature is scheduled for a future release.

thanks

alex
0
Yves Tremblay
Top achievements
Rank 1
answered on 01 Dec 2010, 06:52 PM
Here how I did it. This is a hack and I don't like it, but I haven't found a better way.

            var grid = $(e.row).parents('.t-grid').data('tGrid');
            var index = e.row.rowIndex;

            // Remove grouping rows
            var node = e.row.previousSibling;
            while (node != null) {
                if (node.className.indexOf('t-grouping-row') >= 0) {
                    index--;
                }
                node = node.previousSibling;
            }

            var data = grid.data[index];
0
Dean
Top achievements
Rank 1
answered on 26 May 2011, 05:11 PM
I am using  2011 version of the grid.

Eventually I worked out :

function onRowSelected(e) {  
var grid = $(e.row).parents('.t-grid').data('tGrid');   
var data = grid.data[$(grid.$tbody[0].rows).index(e.row)];  

field1 = data.Field1;  
field2 = data.Field2;  

etc;  
}  

This gives properly named variables for all the fields in the original data, not just the displayed columns.

I did not need the Editable() on.

The rowindex seems to change depending on if the grid has .Groupable() or .Scrollable()

0
Kevin
Top achievements
Rank 1
answered on 22 Sep 2011, 07:32 PM
OK, but I have a hierarchical grid with three levels.  I am editing a row on the third level and I want to get the primary key of it's immediate parent (second level).

Anyone?

Steve
Tags
Grid
Asked by
dstj
Top achievements
Rank 1
Answers by
Sam Critchley
Top achievements
Rank 1
dstj
Top achievements
Rank 1
Steven
Top achievements
Rank 1
Alexandre Jobin
Top achievements
Rank 1
Atanas Korchev
Telerik team
Yves Tremblay
Top achievements
Rank 1
Dean
Top achievements
Rank 1
Kevin
Top achievements
Rank 1
Share this question
or