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

Advanced row-level operations with KendoUI

28 Answers 1054 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Mono
Top achievements
Rank 1
Mono asked on 30 Nov 2011, 09:37 PM
Hello,

I'm very interested in using Kendo UI for my upcoming project. However, i have two needs that need to be met. I would like to figure out how to integrate them into my test project. For my test project, I'm just altering the index.html in the examples/web/grid directory. Within this grid, I need to support:

  1. Double-Clicking on a row. When someone double-clicks on a row, I want to just show an an alert window that says "Hello", just to see it working.
  2. Context-Menu on a row. When someone right-clicks on a row, I need to show a popup menu. I know this won't work in touch-based environments. But we're building a desktop solution and context-menu is a requirement, not an option :(.
Is it possible to do these? If so, how do you do it on the example grid?

Thank you!

28 Answers, 1 is accepted

Sort by
0
Accepted
Atanas Korchev
Telerik team
answered on 01 Dec 2011, 02:16 PM
Hello Mono,

 You can easily use the built-in "dblclick" and "contextmenu" DOM events. I have created a quick demo to show you how to do this:


Regards,
Atanas Korchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Jay
Top achievements
Rank 2
answered on 07 Feb 2012, 10:29 PM
For those of you who are looking to use a context menu with KendoUI (as I was).  I have created a small jQuery based context menu that uses the KendoUI stylesheet.  So, the context menu you get will fit right in with the rest of KendoUI.

Enjoy!

http://jsfiddle.net/jkappel/wVHmR/

PS - Kendo Team, please build an official context control into KendoUI.
        Feel free to use my code if any of it is useful to you.
0
Boone
Top achievements
Rank 2
answered on 16 Feb 2012, 06:25 PM
Jay, this looks great. Although, I need to know how to attach it to each grid row like your first question and unfortunately Atlanas's response to JSFIDDLE is throwing a 404 error.

Here is my grid:

$("#grid").kendoGrid({
                scrollable: false,
                sortable: true,
                pageable: true,
                selectable: "row",
                sortable: {
                    mode: "multiple",
                    allowUnsort: true
                },
                columns: [
                            //Fields here
                        ],
                dataSource: {
                    schema: {
                        data: "d.LoadSearchingResults",
                        total: function (data) {
                            return data.d.TotalResults;
                        }
                    },
                    pageSize: 200,
                    transport: {
                        read: {
                            url: "ServiceURL",
                            contentType: "application/json; charset=utf-8",
                            type: "POST"
                        },
                        parameterMap: function (options) {
                            var object = {};
                            object.pageIndex = options.page;
                            object.size = options.pageSize;
                            object.orderBy = options.sort;
                            return JSON.stringify({ options: object, criteria: searchCriteria });
                        }
                    }
                }
            });

Any help would be greatly appreciated. Thanks
0
Jay
Top achievements
Rank 2
answered on 16 Feb 2012, 11:32 PM
Ah, yes.  Basically what you need to do is use a jQuery selector for the trigger property that will get hold of each row you want.  One thing to keep in mind with the Kendo Gird though, is that if you are using remote data, the data will not be available when you instantiate your grid.  So, you have to attach to the dataBound event and do your work there.  For example:

 $("#grid").kendoGrid({
     dataBound
: function(e) {
         my.contextMenu({
trigger: '#grid td',
        leftButton: false,
        rightButton: true,
        menu: '#testMenu',
        callback: ctxCallback
    });

     
}
 
});

I updated my jsFiddle example to include a grid as well.  Hope this helps!
http://jsfiddle.net/jkappel/wVHmR/ 

PS - in my example, I attached it to the TD elements, but you can use any element you like such as TR or whatever.
0
Boone
Top achievements
Rank 2
answered on 17 Feb 2012, 12:32 AM
Perfect, although I would like the menu to come out where the mouse was clicked (I should be able to handle that part). One more question thought, how would I get that rows ID populated into that value.

So when I right click, the menu comes up. If I click on the first item I would like to call another webservice and pass in the id of the row that brought up the context menu.
0
Jay
Top achievements
Rank 2
answered on 17 Feb 2012, 05:58 PM
OK, so the callback from the item click passes the menu Item that was clicked, as well as the trigger that opened the menu.  So, by interrogating the trigger object, you should be able to get the data you need.  For example if the trigger object is a table row, then you might want to interrogate that row for the ID or the data value within the first TD.

It might look something like this:

function ctxCallback (menuItem, trigger) {
    var id = trigger.find('td:first').attr('id');
    alert('User clicked Context Menu Item "'+ menuItem.text().trim() +'" for the id: ' +id);
0
Mike
Top achievements
Rank 1
answered on 26 Mar 2012, 11:38 AM

Hello,
I'm interested to see the example for the double-click on the grid.
The connection to the example indicates that the page does not exist.
Can I have the correct link?
Thank you.



http://jsfiddle.net/korchev/UVaKQ/44/ -> not page found
0
Jay
Top achievements
Rank 2
answered on 26 Mar 2012, 04:53 PM
I don't know what happened to Atanas jsFiddle page, but if all you need is an example of how to respond to double clicking a row, this should help:

    $('#myGrid tr').dblclick(function({
        alert($(this).find('td:first').text());
    }); 

when you double click a row, you will get an alert with the text data from the first TD element on the row.
0
Mike
Top achievements
Rank 1
answered on 26 Mar 2012, 06:29 PM
Thanks.
0
Ikue
Top achievements
Rank 1
answered on 20 Aug 2012, 03:15 AM
Hi 

My client wants to have right click menu for filtering.
I could mange to create right click menu and filter a datasource.(Thanks for nice work  http://jsfiddle.net/jkappel/wVHmR/ 
)
However the context menu doesn't appear after I filter it.
Do I need to recreate a menu?
0
Jay
Top achievements
Rank 2
answered on 20 Aug 2012, 03:20 PM
Ikue,

     I have not played with the filtering myself, so I can't say for certain.  What I imagine is happening is that the data source removes all rows from the grid, filters the dataset, then re-inserts the filtered results.  Therefore, the objects in the grid are completley new.  The context menu attaches functions to events on the objects in the list.  Therefore, it would need to be run again since the new objects would not have the functions attached to their events.

What you might want to do is to take the code that creates the context menu and place it in it's own procedure.  Then call that function from the grid dataBound event, and also after whatever code you have in place to filter the list.

If you need more specific help, feel free to upload a sample of what you are trying to do and I would be happy to look at it for you. 
0
Ikue
Top achievements
Rank 1
answered on 23 Aug 2012, 04:19 AM
Hi Jay

I repeated some lines of your function after filtering. It worked.
Thank you!
0
Andrew
Top achievements
Rank 1
answered on 11 Sep 2012, 02:15 PM
Hi Jay Thanks for the awesome demo, just one thing, i am unable to get hold of the UID or the Entire Row data in the ctxCallback for some reason

trigger.attr(

 

'id') is undefined? any ideas

 

0
Jay
Top achievements
Rank 2
answered on 11 Sep 2012, 03:15 PM
What are you passing in for the trigger value when you create the context menu?
0
Andrew
Top achievements
Rank 1
answered on 12 Sep 2012, 06:18 AM

trigger: '#DriverLog td'

the full function binds after the databound event so each row is bound to the menu, I even thought of trying to add another value to parse

dataItem: this.dataItem($(this.currentTarget).closest('tr'))

 

 

but this failed dismally.

also i have been doing this the MVC way, this is how i bound your code, but getting no where with accessing row data.

 

@{

 

Html.Kendo().Grid<

 

DriverLogDTO>()
.Name("DriverLog")
.Columns(columns =>
{
columns.Bound(o => o.LogDate).Format("{0:yyyy-MM-dd}")
columns.Bound(o => o.LogItemID).Visible(
false);
}).DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(o => o.LogItemID))

 

.Read(read =>
read.Action(
"GetDriverLog", "TripCapture", new { AssetID = ViewData["AssetID"], DriverID = ViewData["DriverID"], Startdate = DateTime.Parse(ViewData["StartDate"].ToString()), EndDate = DateTime.Parse(ViewData["EndDate"].ToString()) })))
.Events(e => e.DataBound(
"function() { my.contextMenu({ trigger: '#DriverLog td', leftButton: false, rightButton: true, menu: '#testMenu', callback: ctxCallback }); LineItems_Databound(); }"))

 

.Render();}

 

 

0
Jay
Top achievements
Rank 2
answered on 12 Sep 2012, 03:18 PM
Alright, so you are binding the menu to the TD element which is fine.  But you want to read attributes from the row which contains the TD.  So, in your callback function, trigger will be a jQuery object referencing the TD element the user clicked.  Therefore, you should be able to get an attribute such as the id from the row containing the TD element via either of the methods below:

    trigger.parent().attr('id');  
or
    trigger.closest('tr').attr('id');

let me know if this still doesn't help and I will put together a sample for you.
0
Stefan
Top achievements
Rank 2
answered on 13 Sep 2012, 01:33 PM
Hi & thank you for the good tutorial script.
I am new with using Kendo, so i cant get this working as i want with my grid.

I want that when i right click on a <tr> in my grid i want to display the Menu. I want to begin by getting the id of that row as a value.
I also want an alert when i double left click on a row in my grid.

<div id="Grid">
@(Html.Kendo().Grid(Model)
    .Name("GridField")
    .Columns(columns =>
    {
        columns.Bound(item => item.SalonID);
        columns.Bound(item => item.Avtnr);
        columns.Bound(item => item.SalonName);
        columns.Bound(item => item.Street);
        columns.Bound(item => item.ZipCode);
        columns.Bound(item => item.City);
        columns.Bound(item => item.Telephone);
        columns.Bound(item => item.SalonEmail);
        columns.Bound(item => item.Description);
        columns.Bound(item => item.ContactPerson);
    })
    .ColumnMenu()
    .Groupable()
    .Pageable()
    .Sortable()
    .Resizable(resize => resize.Columns(true))
    .Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action("Read", "Search"))
        .ServerOperation(false)
        .PageSize(15)
    )
        .Events(events => events.Change("ctxCallback"))
    )
</div>

Here is the rest of the code:
http://jsfiddle.net/Qz9MM/
0
Jay
Top achievements
Rank 2
answered on 24 Sep 2012, 04:11 PM
Stefan,

Sorry for the delayed response, I have been on vacation.  The jsFiddle sample you posted does not contain a data grid, so I am not sure exactly how to help with that.  However, from the looks of the code that you pasted above, I think the issue you are running into is that when the grid is first instantiated, it has no rows in it.  Then the data source performs an asynchronous fetch.  Once the data has been received, the data source notifies the grid, and the grid generates the data rows.  Therefore, you must instantiate the context menu after the grid has generated it's data rows.  Look up within this thread at my February 16, 2012 post for assistance with this.

Also, I have updated my jsFiddle example to include showing how to get a Row ID when using the TD as the trigger since so many people have been asking about it.  I hope this helps.

http://jsfiddle.net/jkappel/wVHmR/ 
0
steven
Top achievements
Rank 1
answered on 22 Oct 2012, 02:22 AM
Jay,

First, thanks for contributing your context menu to the site, Its greatly appreciated to a newbie like myself trying to learn kendoui.

I have a grid, bound to remote data, and I have the context menu activating.

I'm using this for a CRUD interface and was wondering, without displaying the "ID" field as the first column, is there any other way to have it recognize an "ID" to pass to script?

Such as a product table:
productid, productname and product price.  I dont want to show productid. can i still right click on an option, choose an "edit" option and have the script take me to product.cfm?productid=(productid variable)

thanks
steve

0
Jay
Top achievements
Rank 2
answered on 22 Oct 2012, 03:41 PM
Steven,

I'm glad that my work on the context menu is useful to you.  In your situation, I would recommend that you use the KendoUI Row Templates to render your grid rows.  These allow you to have whatever HTML you want rendered for each row.  You can then assign your product id to a hidden div or as an attribute on some other item.  For example:

<div class="myCustomRow">
    <div id="productId" style="display:none">${ productId }</div>
    <div class="column1">$ { productName }</div>
    <div class="column2">$ { price} </div>
    etc...
</div>

You could then attach the context menu to the "myCustomRow" class.  When the callback event fires, the trigger would be that div.  you could find your product_id via: trigger.find('#productId').html();

0
Kerry
Top achievements
Rank 1
answered on 22 Oct 2012, 08:17 PM
Hi Jay!  Since you seem to still be responding to this thread, I'd like to ask your advice on a problem I'm having.  I have a page with 2 context menus (per your code) that work fine until I throw a splitter on the page.  Any ideas on how to fix?  Here's a fiddle, top context works, bottom does not.

http://jsfiddle.net/hKAB8/6/ 


Thanks for any help!!!

Kerry
0
Jay
Top achievements
Rank 2
answered on 24 Oct 2012, 03:17 PM
Kerry,

Sorry for taking a bit to get back to you, but I have been looking into the issue you are experiencing.  Unfortunately, I have not been able to determine what the cause of it is.  I suspect that the instantiation of the splitter control re-creates the elements within the split containers, but my testing was not able to verify this.

I also tried creating the context menus after the instantiation of the splitter, and even set a 1000ms timeout callback for their creation.  Nothing helped.  At this point, I don't know what to say.  Maybe someone from Kendo UI can help?
0
Kerry
Top achievements
Rank 1
answered on 24 Oct 2012, 03:32 PM
Thanks Jay!  I know you're under no obligation here.  I did ask Kendo and they updated my jsfiddle (http://jsfiddle.net/hKAB8/7/).  It looks like it's a positional thing.  Adding the splitter must reset the vertical position in that panel maybe.  It's still appearing way too far south but I'll continue to tweak it.
0
Jay
Top achievements
Rank 2
answered on 24 Oct 2012, 06:13 PM
Well, that's quite interesting.  At least now you can just "fiddle" (pun intended) with the positioning of the menu to resolve the issue. :)

You'll want to look in the menu.show() function.  The positioning starts with the following line:

var pos = $(this).offset();
0
Andrew
Top achievements
Rank 1
answered on 19 Jun 2013, 07:04 AM
Has anyone managed to get this to work with a grid that loads data dynamically as well as one that refreshes?
Or with multiple grids?

If i put the context menu once before the grid is loaded i get no menu at all. and if i put it after the grid load i end up with multiple alert messages.
So if the data was loaded 4 times and i have 2 grids, i will have 8 alert messages.
http://jsfiddle.net/zawisza/HwUDA/4/
0
Stefan Timm
Top achievements
Rank 2
answered on 02 Jul 2013, 07:49 AM

At first, thanks to Jay. I'm a MVC and Kendo beginner. The contextmenu is very usefull. Telerik send me an feedback, contextmenu on grid is not on their releaseplan. I think this is not the correct decision, because this is a basic usability thing in grids.

I spent a lot of time to implement the menu by Jay to my grid, and some failure come up. I want to describe theese things, so other developer save time by implementation.

@Jay, please can you optimize your code and send this to Telerik, they should publish this in their code-library, many thanks to you. I also wrote to Telerik, because I'm a Customer with a paid full license, and I expect this code in their code-library.

At first, when you implement the menu to the grid, have a look how you bind the grid to your data. When you use ajax binding, you have to use the method .ondatabound to bind the menu function to the row. Any other way is not working.

Ok, now the problems begin. The menu is bound to every cell in the grid, but when you switch on the virtual scrolling the grid will sometimes reload by the .ondatabound function. This is really a problem, because now the click event from the menuitem is bind a second time, or more. I'm searching and debugging to find this behaviour and I found the problem.
You have to append the following line to the code:

list.find('li').unbind("click");

before you bind the event again.

Now the click binding looks following:

var list = menu.find('ul').css({ 'list-style-type': 'none', padding: 0, margin: 0 });
            list.find('li').unbind("click");
            list.find('li').click(function () {
                menu.close();
                options.callback($(this), menu.data('trigger'));
            }).mouseenter(function () {
                $(this).addClass('k-state-hover');
            }).mouseleave(function () {
                $(this).removeClass('k-state-hover');
            }).mousedown(function () {
                $(this).addClass('k-state-selected');
            }).mouseup(function () {
                $(this).removeClass('k-state-selected');
            }).css({ margin: 0, cursor: 'pointer', padding: '3px 7px 3px 7px' });

The callback function is raised only one time.

Then, do not change the trigger -> td to tr, this is not working in the kendo grid. The menu appears always in the first cell, not on the selected cell.

Have Fun
Regards from Germany

@Jay, when you have a lot of time, or you are boring a little bit. You can try to implement the kendo.menu instead off ;-)

0
Michele
Top achievements
Rank 2
answered on 27 Aug 2013, 03:55 PM
Hello,
I'm looking at your solution for context menu.... just a question consider a case where I've a kendo grid with 3 column

ID | Description | Date
1   | User1           | 2013/08/22
2   | User2           | 2013/08/26
3   | User3           | 2013/08/24

How can I modify you code so when I right click on a row I got "Show UserX data" ?

I'm not able to access at the grid content when it opens the popup...I've tried with a function but I'm not js skilled...

In Silverlight it's really easy.......here I'm lost...

Thanks
Paolo
0
Stefan Timm
Top achievements
Rank 2
answered on 28 Aug 2013, 09:34 AM
Hi Paolo,

I think this is more complex. You can try to add a new option, then you fill the new parameter with the cell value when you call my.contextmenu while ondatabound. In the function my.contextmenu now you can replace the html text with the value of the new parameter.
regards Stefan Timm
Tags
Grid
Asked by
Mono
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Jay
Top achievements
Rank 2
Boone
Top achievements
Rank 2
Mike
Top achievements
Rank 1
Ikue
Top achievements
Rank 1
Andrew
Top achievements
Rank 1
Stefan
Top achievements
Rank 2
steven
Top achievements
Rank 1
Kerry
Top achievements
Rank 1
Andrew
Top achievements
Rank 1
Stefan Timm
Top achievements
Rank 2
Michele
Top achievements
Rank 2
Share this question
or