Dynamically add tooltips to kendo grid rows of a column - kendo-ui

I have a column with some notes displaying in the rows. Since the notes are huge, I have cut short the notes in the controller itself and sent that to my aspx page. What I want to achieve is, I want to display the complete notes in the form of a tool tip on mouse over of the grid row ( or if possible exactly on cell ). Is there any way to achieve this? Any help would be highly appreciated. Thanks in Advance.

Posting the answer as it might help anyone.
I got that working after doing this...
columns.Bound(p => p.partialNotes).Title("Description").HeaderHtmlAttributes(new { style = "text-align:center" }).HtmlAttributes(new { style = "text-align:left" }).Width("8%").HtmlAttributes(new { title = "#= completeNotes #" });
I have just added HtmlAttributes(new { title = "#= completeNotes #" })
So now when I place the mouse over the Description column data , I get the complete Notes as a tool tip.

Using a 3rd party widget is also a possibility. I've added qtip tips to column headers like this
KendoUI grid column array item
{
field:"property",
headerTemplate:kendo.template($("#h_Entity_property").html())
},
The header template
<link rel="stylesheet" type="text/css" href="lib/Craga89-qTip2-bfcc9ef/dist/jquery.qtip.min.css"/>
<link rel="stylesheet" type="text/css" href="lib/Craga89-qTip2-bfcc9ef/util/qtip.util.css"/>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/dist/jquery.qtip.min.js"></script>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/util/Dialogues.js"></script>
<script type="text/javascript" src="lib/Craga89-qTip2-bfcc9ef/util/Qtip2Util.js"></script>
<script type="text/x-kendo-template" id="h_Entity_property">
Property
<img onclick="Qtip.local(this, 'i_Entity_property')" src="img/info.gif"/>
<div id="i_Entity_property" style="display:none;">
Elaborate a bit...
</div>
</script>
Tooltip generator
var Qtip = {
local:function (element, contentId) {
$(element).qtip($.extend({}, qTipSharedOptions, {
content:{
text:$('#' + contentId).html(),
title:{
text:' ',
button:true
}
}
}
));
},
...
};
var qTipSharedOptions = {
position:{
at:'top right', // Position the tooltip above the link
my:'bottom left',
viewport:$(window), // Keep the tooltip on-screen at all times
effect:false // Disable positioning animation
},
style:{
classes:'ui-tooltip-tipsy ui-tooltip-shadow'
},
show:{
ready:true,
event:false,
solo:true // Only show one tooltip at a time
},
hide:false
};

you can do like below:
$("#Kendo-grid-div-id").kendoTooltip({
filter: "td:nth-child(2),td:nth-child(3)", //comma separated multiple columns
position: "bottom", //possible values: bottom,top,left,right,center
content: function(e){
var content = e.target.html();
return content;
}
}).data("kendoTooltip");

Related

Conditionally hide button in cell of KendoUIGrid

I have a Kendo UI Grid in which one column has a button, but I musgt hide the button depending on the row which the button is in (in this case first row and last row).
How can I do that?
My code is below.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.silver.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css"/>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid">
</div>
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ width: 150,
command:
[
{
name:"Up",
imageClass: "k-icon k-i-arrow-s",
click: function(e) {
var tr = $(e.target).closest("tr");
var item = this.dataItem(tr);
var dir = "U";
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
moveItem.moveUp(dir,dataItem.order).addCallback(function(response){
alert(response);
})
}
},
]
}
],
dataSource: [
{ name: "Jane Doe", age: 30 },
{ name: "John Doe", age: 33 }
]
});
var grid = $("#grid").data("kendoGrid");
grid.hideColumn(grid.columns[0].columns[0]);
</script>
</body>
</html>
==================
I have added the code that contains the moveItem.moveItemUp method.
In this method I use a remote procedure call to execute some server side javascript. It doesn't have anything to do, really, with hiding of the buttons.
<xe:jsonRpcService
id="jsonRpcService1"
serviceName="moveItem">
<xe:this.methods>
<xe:remoteMethod
name="moveUp"
script="return direction + order">
<xe:this.arguments>
<xe:remoteMethodArg
name="direction"
type="string">
</xe:remoteMethodArg>
<xe:remoteMethodArg
name="order"
type="number">
</xe:remoteMethodArg>
</xe:this.arguments>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
There are three ways to customise Kendo UI Grid row and cell appearance:
http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/style-rows-cells-based-on-data-item-values
Row and column templates do not provide information about the data item index, so the remaining option is to use the dataBound event, get the Grid tbody, locate the first and last child table rows and finally, hide the buttons inside them. The buttons will have a k-grid-Up CSS class, i.e. depending on the command name (case sensitive).
One way of hiding controls within the grid is via CSS. You could create the following styles to hide the first and last buttons in a row:
#grid> tbody > tr:first-child > td > input {
display:none;
}
#grid> tbody > tr:last-child > td > input {
display:none;
}
(You will need to change these styles to get it work with your specific grid and buttons).

kendo ui autocomplete - json file datasource - template - 404 Not Found error - /undefined URL

Below code has been thankfully provided by machun for toggling between RTL and LTR directions in Kendo UI widgets.
The code consists of:
HTML:
kendo autocomplete form plus a button to activate support for RTL and LTR language.
Script:
k-rtl class container
datasource (json file)
kendo autocomplete widget initializing + template to show image beside data and to open data links in the same tab
k-rtl class
The problem is that links don't open correctly. It shows a 404 Not Found error plus a /undefined at the end of the URL.
Live demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script>
</head>
<body>
<div id="container">
<input type="button" id="toggleRTL" value="Activate RTL Support" class="k-button" />
<input id="autocomplete" type="text" />
</div>
</body>
</html>
<script>
/*------k-rtl class container----------*/
function createAutoComplete(){
if($("#autocomplete").data("kendoAutoComplete") != null){
$("#autocomplete").parent().remove();
$("#container").append("<input id='autocomplete' type='text' />")
}
/*------datasource (json file)---------*/
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "json.txt",
dataType: "json",
data: {
q: "javascript"
}
}
},
schema: {
data: "results"
}
});
/*------kendo autocomplete widget initializing + template to show image beside data and to open data links in the same tab----------*/
$("#autocomplete").kendoAutoComplete({
dataSource: dataSource,
dataTextField: "name",
template: '<span><img src="/kendo-autocomplete-test/img/#: id #.jpg" /></span>' + '<span data-href="#:link#">#:name#</span>',
select: function(e) {
var href = e.item.find("span").data("href");
location.assign(href);
}
});
}
/*------k-rtl class----------*/
createAutoComplete();
$('#toggleRTL').on('click', function(event) {
var form = $('#container');
console.log(form);
if (form.hasClass('k-rtl')) {
console.log("test1");
form.removeClass('k-rtl')
} else {
console.log("test2");
form.addClass('k-rtl');
}
createAutoComplete();
})
</script>
I advice to debug your function first then simply check the variable and make sure it contain the right thing. You overlooked a simple thing that your jquery dom selector isn't quite right resulting var href contain "undefined".
Change
var href = e.item.find("span").data("href");
To
var href = e.item.find("span[data-href]").attr("data-href");
Take a look here

Performing operations on substrings of text objects generated by D3

I'm wondering about having narrative text paragraphs scrolling down the side of a webpage while the user is progressing through data visualisation. As part of this it would be nice to add functionality to certain substrings of that text, for example to open a pop-up image it relates to. But I cannot think of any way to tell D3 to objectify substrings of text elements so they can respond to operators like mouseover.
Here's an example, plus jfiddle
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<title>Substring click</title>
<script type="text/javascript" src="scripts/d3.v3.js"></script>
</head>
<body>
<!-- example line -->
<p>The most interesting man in the world</p>
<div/>
<script type="text/javascript">
var link = "https://en.wikipedia.org/wiki/The_Most_Interesting_Man_in_the_World";
d3.select("body").selectAll("div").append("text").text("The most interesting man in the world");
// is there any way to make 'man' link to 'wiki_link' or perform some other operation?
</script>
</body>
</html>
Yes, it is possible, though you will need to format data in a way which is amenable to d3.
Demo
var data = [{ text: 'The most interesting ', href: false },
{ text: 'man', href: 'https://en.wikipedia.org/wiki/The_Most_Interesting_Man_in_the_World' },
{ text: ' in the world', href: false}];
var text = d3.select("body").selectAll("div").append("text");
text.selectAll('tspan')
.data(data)
.enter()
.append('tspan')
.html(function (d) {
return d.href
? '<a href=' + encodeURI(d.href) + '>' + d.text + '</a>'
: d.text;
});

Kendo UI: Can't add a node to treeview when using custom schema

I have a kendo tree initialized with the following datasource:
var dataSource = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: '/Quota/Home/GetTemplateHierarchy',
dataType: 'json',
data: { hierarchyID: hierarchyID, quotaSetID: quotaSetID, batchSize: 10 }
}
},
schema: {
model: {
id: 'id',
hasChildren: 'hasChildren',
children: 'items',
fields: {
text: 'text'
}
}
}
});
Does anyone know how to add and create a new node for this datasource? I've tried the generic treeview.append({ text: "Boo"}) but it doesn't do anything. I've successfully removed nodes, but can't seem to add any. The documentation is not clear as to how to add anything when using custom schemas.
Not sure what do you want to be the text of the node that you want to display. So I will guess that you want to display the only element in the schema nodelevel
The data in that case should be: { nodelevel : 99 }
Following a complete example where I have an initial node and then I append sub-nodes to the selected node.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Tree View</title>
<!-- Kendo UI Web styles-->
<link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css"/>
<link href="styles/kendo.default.css" rel="stylesheet" type="text/css"/>
<!-- Kendo UI Web scripts-->
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/kendo.web.min.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
var count = 0;
var data = [
{ nodelevel: count++ }
];
var dataSource = new kendo.data.HierarchicalDataSource({
data :data,
schema:{
model:{
id :'id',
hasChildren:'hasChildren',
children :'items',
fields :{
nodelevel:{
type :'number',
editable:true,
nullable:false
}
}
}
}
});
var tree = $("#tree").kendoTreeView({
dataSource :dataSource,
dataTextField:"nodelevel"
}).data("kendoTreeView");
$("#add").click(function () {
var selected = tree.select();
if (selected.length > 0) {
tree.append({ nodelevel: count++ }, selected);
}
});
});
</script>
</head>
<body>
Add to selected
<div id="tree"></div>
</body>
</html>
Paul, I'd like to propose another solution...
<!-- Kendo UI Web styles-->
<link href="../styles/kendo.common.min.css" rel="stylesheet" type="text/css"/>
<link href="../styles/kendo.default.min.css" rel="stylesheet" type="text/css"/>
<!-- Kendo UI Web scripts-->
<script src="../js/jquery.min.js" type="text/javascript"></script>
<script src="../js/kendo.web.min.js" type="text/javascript"></script>
<!-- Local Styles -->
<style type="text/css">
</style>
<!-- Initialize Form Elements -->
<script type="text/javascript">
$(document).ready(function () {
function loadMore() {
var uid = $(this).data("uid");
var node = tree.findByUid(uid);
tree.insertBefore(content, node);
tree.remove(node);
addLoadMore(".k-i-pencil");
}
function addLoadMore(clss) {
$(clss, tree.element).closest(".k-item").on("click", loadMore);
}
var content = [
{
text :"node1",
items:[
{ text:"node1.1" },
{ text:"node1.2" },
{ text:"node1.3", spriteCssClass:"k-icon k-i-pencil" },
{ text:"node1.4" }
]
}
];
var tree = $("#tree").kendoTreeView({
dataSource:content
}).data("kendoTreeView");
addLoadMore(".k-i-pencil");
});
</script>
</head>
<body>
<div id="tree"></div>
</body>
</html>
Here I create a tree with a content loaded from JSON (it should be replaced by your ajaxAntiForgery). There is one node in the tree that has an icon (k-i-pencil). Then I call a function addLoadMore that intercepts clicks on the node with k-i-pencil and add new content to this node -using insertBefore for inserting the new content before the content with k-i-pencil and then removes the old node).
I think that this example is pretty similar to what you are doing with your button.
So, take a look into loadMore function to see how I detect the node corresponding to where I clicked (I extract the uid and the find the node with this uid by using tree.findByUid).
Finally I remove the original node (invoking tree.remove) and set again the interceptor for the new nodes with k-i-pencil.
Hopefully this is pretty close to what you have.
The treeview.append should work and append new node to the root level if you do not specify a note to append it to.
You could also use the dataSource.insert({text:"foo"}) or dataSource.add.

Jqgrid ColumnChooser column order change is not working

I am new to jQuery & jgrid. I am trying to use columnchooser to both to let user remove columns and change column order. Removing and adding columns are working fine. But changing the column order is not working. Below is what I have in the code.
<head>
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jquery/ui-lightness/jquery-ui-1.8.6.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jqgrid/ui.jqgrid.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/edi/standard.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/xxxx/resources/css/jquery/ui-multiselect/ui.multiselect.css" />
<script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-ui-1.8.6.custom.min.js"></script>
<!-- <script type="text/javascript" src="/xxxx/resources/js/jquery/jquery-ui-1.8.11.custom.js"></script>-->
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/grid.locale-en.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jquery/ui.multiselect.js"></script>
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.jqGrid.min.js"></script>
<script type="text/javascript">
var jq = jQuery.noConflict();
jq.jgrid.no_legacy_api = false;
</script>
<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.jqGrid.min.js"></script> <!-- 3.8.2 version-->
<!--<script type="text/javascript" src="/xxxx/resources/js/jqgrid/jquery.searchFilter.js"></script>-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>XXXX</title>
</head>
ui.multiselect.js file contains the suggested fix already.
$.widget("ui.multiselect", {
options: {
sortable: true,
searchable: true,
doubleClickable: true,
animated: 'fast',
show: 'slideDown',
hide: 'slideUp',
dividerLocation: 0.6,
nodeComparator: function(node1,node2) {
var text1 = node1.text(),
text2 = node2.text();
return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1);
}
}},
destroy: function() {
this.element.show();
this.container.remove();
// Modified to work with jquery.ui.1.8
if ($.Widget === undefined)
$.widget.prototype.destroy.apply(this, arguments);
else {
$.Widget.prototype.destroy.apply(this, arguments);
return this;
}}
And I am using the columnchooser as below.
jq("#grid").jqGrid('navButtonAdd','#pager',
{ caption: "Columns",
title: "Reorder Columns",
onClickButton : function (perm){
jq("#grid").jqGrid('columnChooser');
}
});
Below is what I have tried so far.
When I add {"msel_opts": $.ui.multiselect.defaults} as an option, I am getting ui undefined JS error.
When I tried to include grid.jqueryui.js, got object or method not supported.
I am stuck # this. Would somebody help please?
It is difficult to find the error in your code, because you posted only one code fragment. Probably you try to add the button in the navigator toolbar with respect of 'navButtonAdd' before you created the navigator toolbar with respect of 'navGrid'.
In any way one small working example here could help you to find your error.
For others who are in the same requirement, you may consider my columnchooser implementation.
My Dialog Form Declaration. (Dialog box which will be shown when columnchooser button is clicked.
All required fields will not be allowed to remove.
Creating the ColumnChooser Button for my Grid.
jq("#grid").jqGrid('navButtonAdd','#pager',{
caption: "Columns",
title: "Customize Columns",
onClickButton : function (){
/*jq("#grid").jqGrid('columnChooser',{
height:columnChooserHt
});*/
createDialogDiv();
jq( "#dialog-form" ).dialog('open');
}
});
Adding Save(OK) and Cancel Buttons to my Div.
jq(function(){
jq( "#dialog-form" ).dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function() {
changeColView();
jq( "#dialog-form" ).dialog('close');
},
Cancel: function() {
jq( "#dialog-form" ).dialog('close');
}
},
close: function() {
}
});
});
Function which inserts the column names with the select boxes which needed to be displayed on the ColumnChooser Dialog Box.
function createDialogDiv(){
var colModelDiv = jq("#grid").jqGrid('getGridParam','colModel');
var colNamesDiv = jq("#grid").jqGrid('getGridParam','colNames');
//alert(JSON.stringify(colModelDiv));
//alert(JSON.stringify(colNameDiv));
var container = document.getElementById('dialog-form');
//alert(colNamesDiv.length);
var chckBox="";
for(i=0;i<colNamesDiv.length;i++){
if(colModelDiv[i].hidden && colModelDiv[i].hidden == true ){
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"'>"+colNamesDiv[i]+"</input><br/>";
}else{
if(colModelDiv[i].editrules && colModelDiv[i].editrules.required){
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"' disabled>"+colNamesDiv[i]+"</input><br/>";
}
else
chckBox+="<input type='checkbox' id='"+colNamesDiv[i]+"' name='"+colNamesDiv[i]+"' value='"+colModelDiv[i].name+"' checked>"+colNamesDiv[i]+"</input><br/>";
}
}
container.innerHTML=chckBox;
}
Finally the actual method which changes the Columns chosen from Columnchooser.
function changeColView(){
var colModelDiv = jq("#grid").jqGrid('getGridParam','colModel');
var colNamesDiv = jq("#grid").jqGrid('getGridParam','colNames');
for(i=0;i<colNamesDiv.length;i++){
var chckBox=document.getElementById(colNamesDiv[i]);
if(chckBox && chckBox.value && (!(chckBox.checked || chckBox.disabled))){
jq("#grid").jqGrid('hideCol',chckBox.value);
}
if(chckBox && chckBox.checked){
jq("#grid").jqGrid('showCol',chckBox.value);
}
}
jq("#grid").trigger('reloadGrid');
}
Plz let me know your thoughts on this one.

Resources