JQGrid dynamic context-menu - jqgrid

Using JQGrid-4.3.3 with jquery.contextmenu.js plugin.
I'm using onContextMenu inorder to dynamically show the menu according to a specific cell value inside the selected row. (return true or false).
The problem is after the menu is shown, when I right click another row the menu that was open for the previous row is not closed. If I don't want to show the menu for a row and the menu was opened before , it can't be closed until I show the menu again in another row, or when I left click anywhere in my page.
How can I close the old menu once a onContextMenu returns false ?
UPDATE:
this is my code:
function createGridContextMenu(grid_)
{
$("tr.jqgrow" , grid_).contextMenu('grid_contextmenu' , {
bindings: {
'item1': function(trigger)
{
}
},
menuStyle: { font:'11px Arial, Verdana, Helvetica',
border: '1px solid #000' ,
width: '130px'
},
itemStyle: { border: 'none', padding: '4px' },
itemHoverStyle: { backgroundColor: '#C0C0C0', border: 'none'},
onContextMenu : function(event, menu)
{
var selected_row_id = $(event.target).parent("tr").attr("id");
var row = grid_.jqGrid('getRowData',selected_row_id);
if(row.status == 1)
{
return false;
}
else
{
grid_.setSelection(selected_row_id, true);
return true;
}
},
onShowMenu: function(event, menu)
{
return menu;
}
});
}
I'm calling createGridContextMenu
inside
loadComplete: function()
{
createGridContextMenu($(this));
},
Thank's In Advance.

I suppose that the reason of the problem is the wrong place where you create context menu. The second problem is setting separate context menus on different rows of the grid.
The callback loadComplete will be executed every time on loading of the grid, paging, sorting and so on. The current implementation uses $("tr.jqgrow" , grid_).('grid_contextmenu' , {...});. On the other side you can set the context menu of the whole <table> instead of setting on every <tr> of the body of the table. Because <table> will be not recreated on every filling of the grid you can do the following
// create the grid
$("#grid").jqGrid({
...
});
// set context menu immediately after creating of the grid
// you need remove calling of createGridContextMenu from loadComplete
$("#grid").contextMenu('grid_contextmenu', {
...
});
I hope that such changes will solve your current problem. I would recommend you additionally to update jqGrid which you use to the current version 4.6.0 which you can download from trirand.
UPDATED: You can hide context menu on leaving it. To do this you can modify the lines 57-59 of the code of jquery.contextmenu.js from
.bind('click', function(e) {
e.stopPropagation();
});
to
.bind('click', function(e) {
e.stopPropagation();
}).mouseleave(function (e) {
if (e.pageX === -1 && e.pageY === -1) {
return; // over tooltip
}
hide();
});
Alternatively you can do the same without modification of jquery.contextmenu.js. You need just to do the same after calling of contextMenu. The final code will be
// create the grid
$("#grid").jqGrid({
...
});
// set context menu immediately after creating of the grid
// you need remove calling of createGridContextMenu from loadComplete
$("#grid").contextMenu('grid_contextmenu', {
...
});
// register mouseleave handler which close the menu
$("#jqContextMenu").mouseleave(function (e) {
if (e.pageX === -1 && e.pageY === -1) {
return; // over tooltip
}
$(this).hide().next().hide();
});

Related

Restrict user to select next row in jqgrid

I am using jqgrid in my project.I have requirement that when user select row and click on edit button of inline toolbar control and modify any data in cell after that instead of click on Save button of inline toolbar control user click(select) any other row at that time.I want to show user message like
Wants to save/discard the modified data
if user click on Save button of message dialog then save the data otherwise discard the data.So please let me know how can I implement it.Till user don’t click on save or discard button don’t select the next row on which user click.
First of all you should use restoreAfterSelect: false option of inlineNav (if you use inlineNav). Seconds you can use beforeSelectRow to implement the required behavior and to call saveRow or restoreRow depend on the user choice.
The simplest implementation of beforeSelectRow could be the following:
beforeSelectRow: function (rowid) {
var $self = $(this),
savedRowInfos = $self.jqGrid("getGridParam", "savedRow"),
editingRowId = savedRowInfos == null || savedRowInfos.length < 1 ?
null : savedRowInfos[0].id;
if (editingRowId != null && editingRowId !== rowid) {
if (confirm("Do you want to save the changes?")) {
$self.jqGrid("saveRow", editingRowId);
} else {
$self.jqGrid("restoreRow", editingRowId);
}
}
}
I used confirm method above. You can see the working code on the demo.
Alternatively one can create asynchronous dialog using jQuery UI dialog for example. Then the code of beforeSelectRow could be the following:
beforeSelectRow: function (rowid) {
var $self = $(this),
savedRowInfos = $self.jqGrid("getGridParam", "savedRow"),
editingRowId = savedRowInfos == null || savedRowInfos.length < 1 ?
null : savedRowInfos[0].id;
if (editingRowId == null || editingRowId === rowid) {
return true; // allow selection
}
$("#dialog-confirm").dialog({
resizable: false,
height: "auto",
width: 650,
modal: true,
buttons: {
"Save the changes": function () {
$(this).dialog("close");
$self.jqGrid("saveRow", editingRowId);
$self.jqGrid("setSelection", rowid);
},
"Discard the changes": function () {
$(this).dialog("close");
$self.jqGrid("restoreRow", editingRowId);
$self.jqGrid("setSelection", rowid);
},
"Continue editing": function () {
var tr = $self.jqGrid("getGridRowById", editingRowId);
$(this).dialog("close");
setTimeout(function () {
$(tr).find("input,textarea,select,button,object,*[tabindex]")
.filter(":input:visible:not(:disabled)")
.first()
.focus();
}, 50);
}
}
});
return false; // prevent selection
}
The corresponding demo is here.

Drag rows in jqGrid

I want to implement draggable rows feature in jqGrid and it's working also using option
$('#MyGrid').jqGrid('gridDnD', {
connectWith: '#MyGrid2'});
Now, my client want to show "Drag here" text in target grid row at the position where the row will be dragged from existing to new one, how can I show this text while dragging row from source to target? Any help is appreciated...
I find your question interesting. So I modified the old demo from the answer and created the demo which demonstrates a possible implementation. The grid during dropping looks like on the picture below:
It uses the following code
$("#grid1").jqGrid("gridDnD", {
connectWith: "#grid2",
drop_opts: {
activeClass: "",
hoverClass: ""
},
onstart: function (ev, ui) {
ui.helper.addClass("ui-widget ui-widget-content")
.css({
"font-size": "11px",
"font-weight": "normal"
});
},
onstop: function (ev, ui) {
$("#dragHelper").hide();
},
droppos: "afterSelected", // "beforeSelected"
beforedrop: function (e, ui, getdata, $source, $target) {
var names = $target.jqGrid("getCol", "name2");
if ($.inArray(getdata.name2, names) >= 0) {
// prevent data for dropping
ui.helper.dropped = false;
alert("The row \"" + getdata.name2 + "\" is already in the destination grid");
}
$("#dragHelper").hide();
$("#grid2").jqGrid("setSelection", this.id, true, e);
},
ondrop: function (ev, ui, getdata) {
var selRow = $("#grid2").jqGrid("getGridParam", "selrow"),
$tr = $("#" + $.jgrid.jqID(selRow));
if ($tr.length > 0) {
$("#grid2").jqGrid("setSelection", $("#grid2")[0].rows[$tr[0].rowIndex + 1].id, true);
}
}
});
// make every row of the destination grid droppable and select row on over
$("#grid2 tr.jqgrow").droppable({
hoverClass: "ui-state-hover",
over: function (e, ui) {
$("#grid2").jqGrid("setSelection", this.id, true, e);
$("#dragHelper").show().position({my: "right center", at: "left bottom", of: $(this)});
}
});
I reserve some place for the tooltip "Drag here ↣" on the left of the grid and marked the row under the moved row additionally to make the position of the dropped row mostly clear. I used free jqGrid which have support of "afterSelected" and "beforeSelected" position of addRowData originally suggested in the answer. So I used droppos: "afterSelected". The dropped rows will be inserted after the selected row.

Mootools Add click event with Drag.Cart

I use this example under jsfiddle.net, to build a drag&drop system and if I create a click event on shirts images (draggables), this event doesn't work.
How to combine drag and click events to the draggables elements with Mootools?
window.addEvent('domready', function(){
$$('.item').addEvent('mousedown', function(event){
//event.stop();
// `this` refers to the element with the .item class
var shirt = this;
var clone = shirt.clone().setStyles(shirt.getCoordinates()).setStyles({
opacity: 0.7,
position: 'absolute'
}).inject(document.body);
var drag = new Drag.Move(clone, {
droppables: $('cart'),
onDrop: function(dragging, cart){
dragging.destroy();
if (cart != null){
shirt.clone().inject(cart);
cart.highlight('#7389AE', '#FFF');
}
},
onEnter: function(dragging, cart){
cart.tween('background-color', '#98B5C1');
},
onLeave: function(dragging, cart){
cart.tween('background-color', '#FFF');
},
onCancel: function(dragging){
dragging.destroy();
}
});
drag.start(event);
});
// This doesn't work
$$('.item').addEvent('click', function(event){
console.log('click');
});
});
the event.stop(); will preventDefault and stopPropagation so the mousedown won't bubble into click.
furthermore, it clones and applies stuff to a new element and somewheere along the lines, mootools-more will stop the event once again.
so replace the event.stop with this.fireEvent('click', event); to bubble it up manually - though strictly speaking, a click is on mouseup and you kind of need to wait for that instead.
http://jsfiddle.net/dimitar/qsjj1jpe/4/

How to set Row data using rowid and column name in jQgrid

I've added a custom icon using below code in jqgrid Actions column. When the cutom icon is clicked, a pop up is opened with Textarea, Save and Close buttons. When I click Save button I wanted to save the text entered in textarea to a hidden field column in jQgrid. I tried 'setRowData' and 'setCell' properties but nothing works. Am I missing something here?
afterInsertRow: function (rowid, rowdata, rowelem) {
$(this).triggerHandler("afterInsertRow.jqGrid", [rowid, rowdata, rowelem]);
//...//
//Start: Code for Notes Icon in Actions column
var iCol = getColumnIndexByName(grid, 'actions');
$(this).find(">tbody>tr#" + rowid + ">td:nth-child(" + (iCol + 1) + ")")
.each(function () {
$("<div>", {
title: "Custom",
mouseover: function () {
$(this).addClass('ui-state-hover');
},
mouseout: function () {
$(this).removeClass('ui-state-hover');
},
click: function (eve) {
$("#change_dialog").dialog({
buttons: {
'Save': function () {
var selRow = $(eve.target).closest("tr.jqgrow").attr("id");
var txtNotes = $("#mytext").val();
$("#gridJQ").setRowData(selRow, { 'notesHidden': txtNotes });
$("#gridJQ").jqGrid('setCell', selRow, 'notesHidden', txtNotes);
$("#gridJQ").jqGrid('setRowData', selRow, 'notesHidden', txtNotes);
$(this).dialog("close");
},
'Close':function() {
$(this).dialog("close");
}
}
});
return false;
}
}
).css({ "margin-right": "5px", float: "left", cursor: "pointer" })
.addClass("ui-pg-div ui-inline-custom")
.append('<span class="ui-icon ui-icon-document"></span>')
.prependTo($(this).children("div"));
});
Instead of using this code to get the row
var selRow = $(eve.target).closest("tr.jqgrow").attr("id");
Try something a more direct such as
var selRow = $("#gridJQ").jqGrid('getGridParam', 'selrow');
Or even just var selRow = rowid.
Does that help at all?

Problems using modal within non-modal window

I am trying to use a modal window within another window as a confirm/message popup, but there are some issues I am not sure if I can't get around.
Here's a jsfiddle of my situation: Fiddle
The problems I am trying to fix are:
Using a modal window while also using appendTo seems to have issues with the back drop, I see its there until you click elsewhere, then it disappears.
It would be great if I could center the modal within my window rather than the Window
Even though dragging is disabled on the modal, if you grab the modal title bar, it will move the outside window.
If I click the 'X' to close the inner modal, it closes my external window.
Can anyone suggest solutions to any of these issues?
$('<div id="confirmModal"><div id="confirmWindow">Is This Correct?<p><input type="button" id="btnYes" value="Yes" /><input type="button" id="btnNo" value="No" /></p></div></div>').prependTo('#Window');
$('#confirmWindow').kendoWindow({
modal: true,
resizable:false,
draggable:false,
appendTo: '#Window',
close: function() {
setTimeout(function(){
$('#confirmWindow').kendoWindow('destroy');
}, 200);
}
});
$('#confirmWindow').find('#btnNo').click(function () {
$('#confirmWindow').kendoWindow('close');
});
$('#confirmWindow').find('#btnYes').click(function () {
$('#confirmWindow').kendoWindow('close');
});
Edit
I have edited the fiddle as the first one was an older version of what i meant to post.
From appendTo documentation:
The element that the Window will be appended to. Note that this does not constrain the window dragging within the given element.
So, Kendo windows are floating, they are not constrained to the element that you append it to. This means that does not make sense prepend the confirmation window to an HTML element and then append it to that same element.
Check response from a telerik enginer
http://www.kendoui.com/forums/kendo-ui-web/window/kendowindow-appendto-boundaries.aspx
<script type="text/javascript">
$(document).ready(function () {
$("#windowName").data("kendoWindow").dragging._draggable.bind("drag", function (e) {
var wnd = $("#window").data("kendoWindow");
var position = wnd.wrapper.position();
var minT = 0;
var minL = 0;
//Get the Window width and height and
//place them in position of the hard-coded width and height
var maxT = 600 - wnd.wrapper.height();
var maxL = 900 - wnd.wrapper.width();
if (position.left < minL) {
coordinates = { left: minL };
$(wnd.wrapper).css(coordinates);
}
if (position.top < minT) {
coordinates = { top: minT };
$(wnd.wrapper).css(coordinates);
}
if (position.left > maxL) {
coordinates = { left: maxL };
$(wnd.wrapper).css(coordinates);
}
if (position.top > maxT) {
coordinates = { top: maxT };
$(wnd.wrapper).css(coordinates);
}
})
})
</script>

Resources