KendoUI Context Menu: too cool!


Today KendoUI announced its new release KendoUI Professional Q2 2014 and during the video presentation they have shown the new Widget ContextMenu.

Despite of attending the presentation I did want to play with it and learn more about this Widget. What is the best way for quickly getting familiar with Kendo UI Widgets? Yes, you are right, their Demo web site but there is no demo about this widget, is that possible? Sure they will fix it pretty soon.

KendoUI Context Menu

What is a Context Menu? According Wiki definition:

A context menu (also called contextual, shortcut, and popup or pop-up menu) is a menu in a graphical user interface (GUI) that appears upon user interaction, such as a right-click mouse operation.

What is a ContextMenu for Kendo UI?

For Kendo UI is an HTML unordered list (pre) that might happen to have more than one level (another unordered list).

Something like:

<ul id="context-menu">
    <li>Option 1
        <ul>
            <li>Option 1.1</li>
            <li>Option 1.2</li>
            <li>Option 1.3
              <ul>
                <li>Option 1.3.1</li>
                <li>Option 1.3.2</li>
                <li>Option 1.3.3</li>
                <li>Option 1.3.4</li>
              </ul>
          	</li>
        </ul>
    </li>
    <li>Option 2
        <ul>
            <li>Option 2.1</li>
            <li>Option 2.2</li>
            <li>Option 2.3</li>
        </ul>
    </li>
</ul>

And this looks like:

KendoUI Context Menu
KendoUI Context Menu

Defining a ContextMenu

In the previous paragraphs I have shown how to define the content of the Context Menu but we should say which are the target elements on which this Context Menu is activated. To do so, you define in the initialization the target elements using a jQuery Selector.

Example:

$("#context-menu").kendoContextMenu({
    target: "#area1,#area2"
});

Here I define that the context menu is going to be displayed if you right-click on an HTML element which id is “area1” or “area2”. Any other part of your HTML will not display it.

Defining a ContextMenu as DataSource

Despite I’ve shown how to initialize the content of the Context Menu using an HTML unordered list (ul) you can also use a DataSource or an array as follow:

var ds = [
    {
        text: "Europe"
    },
    {
        text : "Americas",
        items: [
            {
                text : "North America",
                items: [
                    { text: "Canada" },
                    { text: "United States" },
                    { text: "Mexico" }
                ]
            },
            { text: "Central America" },
            {
                text : "South America",
                items: [
                    { text: "Argentina" },
                    { text: "Brazil" },
                    { text: "Chile" }
                ]
            }
        ]
    },
    {
        text: "Asia"
    }
];
$("

“).kendoContextMenu({ dataSource: ds, target: “#area1” });

KendoUI Context Menu using a DataSource
KendoUI Context Menu using a DataSource

Where each option is an entry in the array and nested option are nested elements stored in an array called “items”.

Since this context menu is actually not defined in HTML I’ve used “$(‘

‘).kendoContextMenu({…});” for creating an HTML element that will contain the menu.

Additional options for the menu items

I’ve shown how to just display a text but you can actually decorate the text using any HTML by doing:

    { text: "United States", encoded: false },

Here I’ve decorated the text as bold (b) and I have set “encoded” to “false” indicating that “<” and “>” should actually not be displayed as a character but being part of the HTML tag.

The following image shows what happen if I define the content of the context menu as:

...
    items: [
        { text: "Canada", encoded: true },
        { text: "United States", encoded: false },
        { text: "Mexico" }
    ]
...
KendoUI Context Menu using HTML codes
KendoUI Context Menu using HTML codes

You can also define a CSS class:

.ob-red {
    background : red;
}
.ob-green {
    background : green;
}
...
    items: [
        { text: "Argentina", cssClass: "ob-red" },
        { text: "Brazil" },
        { text: "Chile", cssClass: "ob-green" }
    ]
...
KendoUI Context Menu using cssClass
KendoUI Context Menu using cssClass

Or you can also add images using “spriteCssClass” or “imageUrl”:

.ob-flag-argentina {
    background-image: url(/images/flags/argentina.png);
}
...
    items: [
        { text: "Argentina", spriteCssClass: "ob-flag-argentina"  },
        { text: "Brazil", imageUrl: "/images/flags/brazil.png" },
        { text: "Chile" }
    ]

That looks like:

KendoUI Context Menu with images
KendoUI Context Menu with images

Reusing KendoUI Menu

The new Context Menu widget actually is pretty similar to Kendo UI Menu, it accepts most of the Menu options and the DataSource are reusable as well. This is how the Menu looks like if I use previous DataSource for defining a Menu.

KendoUI Menu
KendoUI Menu
Advertisements

KendoUI Grid: custom sorting algorithms


There was a couple of times that I have had to sort columns in a KendoUI Grid but using my custom order. I mean, not using out-of-the-box ordering but doing something especial. Example: order ignoring accents, upper-lower case… but I couldn’t find how to do easily do it and end-up implementing server side filtering and sending the data sorted from the server. For what I was looking for, that was acceptable but this is not always desirable.

This week Atanas Korchev (@korchev) from Telerik, show us how to do it in Stack Overflow: easy and neat! Let me show you how.

KendoUI Grid: defining sortable columns

This is pretty easy, just define sortable: true in your Grid and it will work.

$("#grid").kendoGrid({
    dataSource: {
        data    : [
            { id: 1, name: "one" },
            { id: 2, name: "two" },
            { id: 3, name: "three" },
            { id: 4, name: "four" },
            { id: 5, name: "five" }
        ],
        pageSize: 10,
        schema  : {
            model: {
                fields: {
                    id  : { type: 'number' },
                    name: { type: 'string' }
                }
            }
        }
    },
    editable  : false,
    pageable  : false,
    sortable  : true,
    columns   : [
        { field: "id", title: "Number" },
        { field: "name", title: "Name" }
    ]
});

And you get:

Sortable Grid
Sortable Grid

and if you click on the column header it will sort the column numerically or alphabetically.

KendoUI Grid: Defining custom order

But, what about if you want to order the column by Name but you want that it should be considered as numbers…

If we look at KendoUI documentation about sortable we can define it at Grid level:

Sortable Grid option
Sortable Grid option

and at column level:

KendoUI Grid column sortable option
KendoUI Grid column sortable option

But despite the first says Can be set to a JavaScript object which represents the sorting configuration it does not provide any detail.

At least now, we have some details. Here is how to define a custom compare function.

KendoUI Grid: Custom compare function

Despite the documentation says that columns.sortable needs to be a Boolean it actually can be an object and one of the members of this object is a compare function that return -1 if first argument is less than seconde, 0 if both are the same or +1 if the second is greater that then first.

{
    field   : "name",
    width   : 200,
    title   : "Name",
    sortable: {
        compare: function (a, b) {
            return numbers[a.name] - numbers[b.name];
        }
    }
}

Now, for the sake of this example, what I do is defining an associative array for translating number names into numbers (this is only an example!).

var numbers = {
    "one"  : 1,
    "two"  : 2,
    "three": 3,
    "four" : 4,
    "five" : 5
};

Now, my grid definition is:

var grid = $("#grid").kendoGrid({
    dataSource: {
        data    : [
            { id: 1, name: "one" },
            { id: 2, name: "two" },
            { id: 3, name: "three" },
            { id: 4, name: "four" },
            { id: 5, name: "five" }
        ],
        pageSize: 10,
        schema  : {
            model: {
                fields: {
                    id  : { type: 'number' },
                    name: { type: 'string' }
                }
            }
        }
    },
    editable  : false,
    pageable  : false,
    sortable  : true,
    columns   : [
        { field: "id", title: "Number" },
        {
            field   : "name",
            title   : "Name",
            sortable: {
                compare: function (a, b) {
                    return numbers[a.name] - numbers[b.name];
                }
            }
        }
    ]
}).data("kendoGrid");

And when sorting what I get is:

KendoUI Grid custom sorted
KendoUI Grid custom sorted

KendoUI Grid: custom sorting strings

Have you ever tried sorting a column with string with mixed upper-lower case, accents…? Seems that KendoUI engineers have considered that we want alphabetical order (which is very useful) and not ASCII order.

Let’s consider that we have the following data in our DataSource

[
    { id: 1, name: "Johan" },
    { id: 2, name: "john" },
    { id: 3, name: "Jöhän" },
    { id: 4, name: "john" },
    { id: 5, name: "John" },
    { id: 6, name: "john" }
]

Where we see John in uppercase (record with id 5) and in lowercase (record with id 2, 4 and 6) or Johan with different punctuations.

If we define a Grid with this data and sort it by column name

var grid = $("#grid").kendoGrid({
    dataSource: {
        data    : [
            { id: 1, name: "Johan" },
            { id: 2, name: "john" },
            { id: 3, name: "Jöhään" },
            { id: 4, name: "john" },
            { id: 5, name: "John" },
            { id: 6, name: "john" }
        ],
        pageSize: 10,
        schema  : {
            model: {
                fields: {
                    id  : { type: 'number' },
                    name: { type: 'string' }
                }
            }
        }
    },
    editable  : false,
    pageable  : false,
    sortable  : true,
    columns   : [
        { field: "id", title: "Number" },
        { field: "name", title: "Name" }
    ]
}).data("kendoGrid");

What I get is:

Sorting name with default compare function
Sorting name with default compare function

That show that “Jöhään” is lower than “Johan” and “john” is always lower than “John” (odd?!)

Let’s define a sorting function using standard order. What I will do show side by side two grids with the same data.

My Grid definition is:

var grid1 = $("#grid1").kendoGrid({
    dataSource: {
        data    : [
            { id: 1, name: "Johan" },
            { id: 2, name: "john" },
            { id: 3, name: "Jöhään" },
            { id: 4, name: "john" },
            { id: 5, name: "John" },
            { id: 6, name: "john" }
        ],
        pageSize: 10,
        schema  : {
            model: {
                fields: {
                    id  : { type: 'number' },
                    name: { type: 'string' }
                }
            }
        }
    },
    editable  : false,
    pageable  : false,
    sortable  : true,
    columns   : [
        { field: "id", title: "Number" },
        { field: "name", title: "Name" }
    ]
}).data("kendoGrid");
var grid2 = $("#grid2").kendoGrid({
    dataSource: {
        data    : [
            { id: 1, name: "Johan" },
            { id: 2, name: "john" },
            { id: 3, name: "Jöhään" },
            { id: 4, name: "john" },
            { id: 5, name: "John" },
            { id: 6, name: "john" }
        ],
        pageSize: 10,
        schema  : {
            model: {
                fields: {
                    id  : { type: 'number' },
                    name: { type: 'string' }
                }
            }
        }
    },
    editable  : false,
    pageable  : false,
    sortable  : true,
    columns   : [
        { field: "id", title: "Number" },
        {
            field   : "name",
            title   : "Name",
            sortable: {
                compare: function (a, b) {
                    return a.name === b.name ? 0 : (a.name > b.name) ? 1 : -1;
                }
            }
        }
    ]
}).data("kendoGrid");

You can se that for the first Grid I do not define any “special” sortable option while for second, I defined a compare function that returns 0, 1 or -1.

compare: function (a, b) {
    return a.name2 === b.name2 ? 0 : (a.name2 > b.name2) ? 1 : -1;
}

Now, if I order incrementally by name both Grids, I get:

String column with custom compare function.
String column with custom compare function.

Where now uppercase come before lowercase and non accented character also before than same with accent or punctuation.

KendoUI MultiSelect in a Grid: Yes, we can!


In Spring 2013 (see Release Note) KendoUI introduced a new widget: MultiSelect. Similar to a Drop Down List but this time you see all selected options as some sort of buttons with an (x) for deleting it and a Drop Down List for adding new items.

Kendo UI MultiSelect widget
Kendo UI MultiSelect widget

But as well as it happens with dates or booleans, you do not have a Kendo UI out-of-the-box support of input fields of this type, in a Kendo UI Grid. If you want to use a MultiSelect, DatePicker, AutoComplete, CheckBox,… you need to write and editor function.

KendoUI: MultiSelect

Using MultiSelect widget for an input field is pretty simple, you just need to define an HTML select and invoke the kendoMultiSelect initialization with little more than a DataSource that is an array of valid options.

<select id="select"></select>
$("#select").kendoMultiSelect({
    dataSource: [
        "Africa",
        "Europe",
        "Asia",
        "North America",
        "South America",
        "Antarctica",
        "Australia"
    ]
});

And if we display what it stores, we can see that is is an array of strings.

KendoUI MultiSelect value
KendoUI MultiSelect value

 

KendoUI: MultiSelect, saving ids

But in the previous case the DataSource is just an array of strings but you might have both text: what you want to show; and value what you want to store. You configure which field is used for text in dataTextField and which for value with dataValueField

If so, you define the DataSource as:

$("#select").kendoMultiSelect({
    dataTextField : "text",
    dataValueField: "id",
    dataSource    : [
        { text: "Africa", id: 1 },
        { text: "Europe", id: 2 },
        { text: "Asia", id: 3 },
        { text: "North America", id: 4 },
        { text: "South America", id: 5 },
        { text: "Antarctica", id: 6 },
        { text: "Australia", id: 7 }
    ]
});

Now, when we display the values, we get:

KendoUI MultiSelect values when explicitly set text and value fields.
KendoUI MultiSelect values when explicitly set text and value fields.

 

KendoUI Grid with MultiSelect field

Now, it is time for using this MultiSelect in a Grid with the considerations above.

KendoUI Grid displaying MultiSelect cell

1. We have seen that values are stored in an array in KendoUI MultiSelect, so we cannot directly show them in a Grid cell or it will be displayed as an array.

Kendo UI MultiSelect value displayed  in a Grid cell
Kendo UI MultiSelect value displayed in a Grid cell

2. This is actually easy to solve, we use a template in the column definition that serialize MultiSelect value to a string separated by commas using join method.

columns   : [
    ...
    { field: "Cities", width: 300, template: "#= Cities.join(', ') #" }
]
Kendo UI MultiSelect value displayed  in a Grid cell separated by commas
Kendo UI MultiSelect value displayed in a Grid cell separated by commas

 

KendoUI Grid editing MultiSelect cell

Now, we have to inform KendoUI Grid how we want a multi-value cell to be edited: edit using a MultiSelect; and we do this using editor attribute in the column definition.

columns   : [
    ...
    { field: "Cities", width: 300, template: "#= Cities.join(', ') #", editor: citiesEditor }
]

The only remaining thing is define citiesEditor that is pretty simple:

function citiesEditor(container, options) {
    $("<select multiple='multiple' data-bind='value : Cities'/>")
            .appendTo(container)
            .kendoMultiSelect({
                dataSource: CitiesDS
            });
}

Generate an HTML select with option multiple and bind it to field Cities doing data-bind=’value : Cities’. Now our Grid while editing the list of Cities looks like:

KendoUI MultiSelect value formatted using template
KendoUI MultiSelect value formatted using template

So, it turned out not to be so difficult. Although that is still pending the case when we want to save the id instead of the text. This will be covered in the second part of this post.

Kendo UI: Read to Read-Write grid


As you might know, I’m a avid contributor to Stack Overflow in questions related to Kendo UI.

Few days back, someone asked on how to switch a Grid from read-only to read-write on a button click. He/she was trying to play with the Grid option readable option but this options once set is not possible being changed. Well, actually you can change but it has no effect, no matter if you refresh the grid, read the data again,…
Maybe, he/she was looking for a complex solution based on playing with the DataSource schema model and each field attribute but there is a much simpler solution.
So, what is the simplest way of achieving this…

Kendo UI: make read-only Grid writeable

The easiest way is creating two Grid with exactly the same option and, very important, sharing the DataSource, where one has editable set to false. Also, one of the Grids is hidden (just adding CSS class that defines display to none) while the other is visible.
When you click the button for enabling writing, you toggleClass so the hidden becomes visible and viceversa.

Why did I say that is important sharing the DataSource? Because if you navigate through one of the grids and then commute modes, you don’t want to go back to the beginning, making visible that used the trick of two grids.

This is the CSS class that I defined.

.ob-hidden {
    display: none;
}

And this is the HTML with the two Grids.

<div id="grid-editable"></div>
<div id="grid-editable"></div>

Next, define the two grids that only differ in the option editable.

// Define one single and share datasource
var ds = new kendo.data.DataSource({
    data    : data,
    pageSize: 10,
    schema  : {
        model: {
            fields: {
                Id       : { type: 'number' },
                FirstName: { type: 'string' },
                LastName : { type: 'string' },
                City     : { type: 'string' },
                Title    : { type: 'string' },
                BirthDate: { type: 'date' },
                Age      : { type: 'number' }
            }
        }
    }
});

// Grid editable
$("#grid-editable").kendoGrid({
    dataSource: ds,
    editable  : true,
    pageable  : {
        refresh  : true,
        pageSizes: true
    },
    columns   : [
        { field: "FirstName", width: 90, title: "First Name" },
        { field: "LastName", width: 90, title: "Last Name" },
        { field: "City", width: 100 },
        { field: "Title" },
        {
            field   : "BirthDate",
            title   : "Birth Date",
            template: '#= kendo.toString(BirthDate,"dd MMMM yyyy") #'
        },
        { width: 50, field: "Age" }
    ]
});

// And Grid not editable
$("#grid-not-editable").kendoGrid({
    dataSource: ds,
    editable  : false,
    pageable  : {
        refresh  : true,
        pageSizes: true
    },
    columns   : [
        { field: "FirstName", width: 90, title: "First Name" },
        { field: "LastName", width: 90, title: "Last Name" },
        { field: "City", width: 100 },
        { field: "Title" },
        {
            field   : "BirthDate",
            title   : "Birth Date",
            template: '#= kendo.toString(BirthDate,"dd MMMM yyyy") #'
        },
        { width: 50, field: "Age" }
    ]
});

The code for switching modes is:

$("#grid-editable").toggleClass("ob-hidden");
$("#grid-not-editable").toggleClass("ob-hidden");

Simple and fast!

If you want to see this solution in action, try it here.

Sometimes you need to re-think on what you want to achieve instead of insisting on how to get it.

KendoUI move rows between grids


One other post that comes from my experience in Stack Overflow…

This time I will explain something that is commonly used: have two grids side by side and move rows between them.

These typically look like this:

Original two gridsWhere you can select one or more rows in both grids:

Rows selectionAnd then click on a button for moving selected arrows resulting:

Rows moved

Obviously, you can select rows in the second grid and move them back to the first.

KendoUI: moving rows between grids

First, I will start defining a container for both grids and buttons. This would be something like:

<div id="panels">
    <div id="grid1"></div>
    <div id="commands">
        <div><a href="#" id="copySelectedToGrid2" class="k-button">&gt;</a></div>
        <div><a href="#" id="copySelectedToGrid1" class="k-button">&lt;</a></div>
    </div>
    <div id="grid2"></div>
</div>

And I need some CSS styling:

#panels { display: table-row; }
#grid1, #grid2 { width: 400px; display: table-cell; }
#commands { text-align: center; width: 50px; vertical-align: middle; display: table-cell; }
#commands div { padding: 5px; }
#commands div a { width: 35px; text-align: center; }

Then, I define the grids that are something like this:

var grid1 = $("#grid1").kendoGrid({
    dataSource: ds1,
    editable:   "popup",
    selectable: "multiple",
    pageable:   false,
    columns:    [
        { field: "FirstName", width: 90, title: "First Name" } ,
        { field: "LastName", width: 90, title: "Last Name" }
    ]
}).data("kendoGrid");

var grid2 = $("#grid2").kendoGrid({
    dataSource: ds2,
    editable:   "popup",
    selectable: "multiple",
    pageable:   false,
    columns:    [
        { field: "FirstName", width: 90, title: "First Name" } ,
        { field: "LastName", width: 90, title: "Last Name" }
    ]
}).data("kendoGrid");

The only remarkable question is that I’m allowing multiple selection and disabling pagination since I want visible all values of each of the grids (making easier see how rows move between grids).

Moving rows

The first part is defining the click event handler for the two buttons. This is something like:

$("#copySelectedToGrid2").on("click", function (idx, elem) {
    moveTo(grid1, grid2);
});
$("#copySelectedToGrid1").on("click", function (idx, elem) {
    moveTo(grid2, grid1);
});

And moveTo function is:

function moveTo(from, to) {
    var selected = from.select();
    if (selected.length > 0) {
        var items = [];
        $.each(selected, function (idx, elem) {
            items.push(from.dataItem(elem));
        });
        var fromDS = from.dataSource;
        var toDS = to.dataSource;
        $.each(items, function (idx, elem) {
            toDS.add($.extend({}, elem));
            fromDS.remove(elem);
        });
        toDS.sync();
        fromDS.sync();
    }
}

Where I get selected rows and iterate getting the items selected. The reason why I do it in two steps (get the data item and the insert into second grid and remove from the first grid) is because arrays are expected to immutable, which means: I cannot remove one element from an array while iterating on it since this alters the array not being able to correctly continue the iteration.

Finally, I invoke sync on both DataSources for sending the modification to the server.

Pretty easy, don’t think so!

If you want to see it running, there is a JSFiddle here.

KendoUI: Grid row details


Many times we have much more information to show in a Grid than what is physically possible. For those cases KendoUI provides a mechanism through an option in Grid initialization called detailTemplate.

In this post I will show you how to use, the standard way but also how to show that same detailed information not inside the grid but in a tooltip displayed when mouse is over a row.

KendoUI: detailTemplate

Once again KendoUI engineers have  read our minds and thought about our needs, implementing a feature for showing detailed information.

The idea behind is defining a template  that will be displayed inside the Grid (as an expanded row of the original one) including the details (or -actually- whatever you want to include).

This is our DataSource:

var dataSource = new kendo.data.DataSource({
    data    : [
        { symbol: "AAPL", company: "Apple Inc.", price: 509.5892 },
        { symbol: "AMZN", company: "Amazon.com Inc.", price: 245.18  },
        { symbol: "IBM", company: "International Business Machines Corp.", price: 189.83 },
        { symbol: "CSCO", company: "Cisco Systems, Inc", price: 19.4494 },
        { symbol: "MSFT", company: "Microsoft Corp.", price: 26.55 },
        { symbol: "INTC", company: "Intel Corp.", price: 20.23 },
        { symbol: "QCOM", company: "QUALCOMM Inc.", price: 60.6382 },
        { symbol: "ORCL", company: "Oracle Corp.", price: 33.02 },
        { symbol: "HPQ", company: "Hewlett-Packard Company", price: 13.68 },
        { symbol: "CRM", company: "salesforce.com, Inc.", price: 164.18 }
    ],
    pageSize: 5
});

and we want to show in the Grid just the symbol and price (but not company).

This is our Grid initialization:

var grid = $("#stocks_tbl").kendoGrid({
    dataSource    : dataSource,
    columns       : [
        { field: "symbol", title: "Symbol", width: 100 },
        { field: "price", title: "Price", width: 100, format: "{0:c2}", attributes: {style: "text-align:right;"} }
    ],
    pageable      : true
}).data("kendoGrid");

That looks like this:
Capture1
But, I’d like to show the details, in this example, the company name. So, what I do is define a template that displays this additional information.

This template is something like:

<script id="template" type="text/x-kendo-template">
<div>Company: <span style="font-weight: bold;">#= company #</span></div>
</script>

And when the row is expanded it looks like:
Capture2

Display details in a tooltip

That’s ok but I have to click to open the details and in some case I just want to display it as a tooltip. In those case what I’m going to do is something similar (define a template) but instead of displaying it inside the Grid table, I’m going to show it as a tooltip.

The very first thing is defining an HTML block on which we I’m going to display the detailed information.

<div class="k-tooltip ob-hidden" id="tooltip" data-template="template" data-bind="source: this"></div>

Where ob-hidden is defined as:

.ob-hidden {
    display: none;
}

Used for hiding the tooltip.

Then in the JavaScript I’m going to display this tooltip when the mouse is over a grid row and hide it when it exits.

    // Show tooltip when mouse is over a row
    $(grid.element).on("mouseover", "tr", function() {
        $("#tooltip").removeClass("ob-hidden");
    });
    // Hide tooltip when mouse exits a row
    $(grid.element).on("mouseout", "tr", function() {
        $("#tooltip").addClass("ob-hidden");
    });

In addition, when I’m about to display the tooltip, I have to bind the row data to the template and that’s why I have include data-bind=”source: this” in the tooltip definition:

$(grid.element).on("mouseover", "tr", function () {
    // Get the item from the grid
    var item = grid.dataItem(this);
    if (item) {
        // Bind it to the tooltip
        kendo.bind("#tooltip", item);
        // Make tooltip visible
        $("#tooltip").removeClass("ob-hidden");
    }
});

Right now, the tooltip looks like:

Where the tooltip is displayed always in the same position and far from where the cursor is. So the final question would be displaying the tooltip near the cursor.

In this case and for a more precise tooltip position, what I’m going to do is replace the mouseover by a mousemove, this means much more work but the tooltip will follow very precisely the mouse.

The new code for display the tooltip will be:

// Show tooltip when mouse moves over a row
$(grid.element).on("mousemove", "tr", function (e) {
    var item = { item: grid.dataItem(this) };
    if (item.item) {
        kendo.bind("#tooltip", item);
        $("#tooltip")
                .css({top: e.pageY + 5, left: e.pageX + 5})
                .removeClass("ob-hidden");
    }
});

Where I get the position of the cursor from the event argument of the mousemove handler.

And this looks like:

KendoUI: Selectable Widget


Continuing a series of KendoUI widgets (this and this)… This one allows you to mark as selected HTML objects and then ask for which one are actually selected.

As per se, this is not a lot but this is actually used by another widgets and you can find it useful as well.

KendoUI: selectable widget

Selectable widget: source code

/*
 * Copyright (c) 2012. OnaBai Software Solutions.  All rights reserved.
 * If you do not own a commercial license, this file shall be governed by the
 * GNU General Public License (GPL) version 3.
 * For GPL requirements, please review: http://www.gnu.org/copyleft/gpl.html
 */

(function ($) {
    var kendo = window.kendo,
        ui = kendo.ui,
        Widget = ui.Widget,
        CLICK = "click";

    var OBSelectable = Widget.extend({
        init       :function (element, options) {
            var that = this;

            Widget.fn.init.call(that, element, options);
            element = that.element;
            options = that.options;
            var items;
            if (options.selector) {
                items = $(options.selector, that.element);
            } else {
                items = element.children();
            }
            items.bind(CLICK, $.proxy(that._click, that));
        },
        getSelected:function () {
            return $(".ob-selected", this.element);
        },
        options    :{
            name    :"OBSelectable",
            style   :"ob-status-selected",
            multiple:true,
            selector:null
        },
        events     :[
            CLICK
        ],
        _click     :function (ev) {
            if (!this.options.multiple) {
                this.getSelected().removeClass(this.options.style + " ob-selected");
            }
            $(ev.currentTarget).toggleClass(this.options.style + " ob-selected");
        }
    });
    ui.plugin(OBSelectable);
})(jQuery);

Selectable widget: usage

One element is selected by clicking on it, if you click on a selected element, then it is de-selected.

Selectable widget: configuration

style (string, default: ob-status-selected): Style (CSS class) applied to selected elements (clicked).

multiple (boolean, default: true): When true, you might select more than one item, otherwise selecting an item will cause the de-selection of any selected one.

selector: (string, default first level child nodes). If configured, selector allows you to mark as selectable nodes that are not the direct children of this.

Selectable widget: methods

getSelected: Returns list containing the elements that are marked as selected.

Selectable widget: usage example

The HTML:

<ol id="selectable">
    <li class="ob-item">Element 1</li>
    <li class="ob-item">Element 2</li>
    <li class="ob-item">Element 3</li>
    <li class="ob-item">Element 4</li>
    <li class="ob-item">Element 5</li>
</ol>

The JavaScript:

$("#selectable").kendoOBSelectable({
    selector:"[class='ob-item']",
    style:"selected",
    multiple:true
});

I define as selectable those node under the node with id selectable and with class ob-item. This would have been equivalent to say selector:”li” or not defining selector since all li elements area actually first level children of $(“#selectable”).

If I define the selected CSS class as:

.ob-selected {
    background-color: red !important;
    color: #d3d3d3 !important;
}

I get something like this when Element 1 and Element 3 are selected:

KendoUI selectable widget
KendoUI selectable widget