How to Pass Data to Url from Jqgrid Row If Hyperlink Is Clicked

How to pass data to url from jqgrid row if hyperlink is clicked

I understand the problem very good. I agree that both predefined formatter which one can use currently ('showlink' and 'link' formatters) are not flexible enough.

I can suggest you another formatter which you could download here. The usage of the formatter is very easy:

{label: "AddToCart", name: "Addtocrt_addtocrt", formatter: "dynamicLink",
formatoptions: {
url: function (cellValue, rowId, rowData) {
return '/Store/AddToCart' + rowId + '?' +
$.param({
quantity: rowData.Stocks_valkogus
});
}
}
}

The url defined as function will be used in the <a> as the value of href attribute.

Additionally to the url formatoptions the 'dynamicLink' formatter supports target option (with the same meaning as by 'showlink'), cellValue which can be also function and onClick callback with rowId, iRow, iCol, cellValue, e as parameters. If the onClick callback is defined the value of url will be ignored. So one can skip the definition of the formatter option url.

The demo demonstrate the usage of the 'dynamicLink' formatter:

Sample Image

The current code of the formatter: 'dynamicLink' you can find below:

/*global jQuery */
(function ($) {
'use strict';
/*jslint unparam: true */
$.extend($.fn.fmatter, {
dynamicLink: function (cellValue, options, rowData) {
// href, target, rel, title, onclick
// other attributes like media, hreflang, type are not supported currently
var op = {url: '#'};

if (typeof options.colModel.formatoptions !== 'undefined') {
op = $.extend({}, op, options.colModel.formatoptions);
}
if ($.isFunction(op.target)) {
op.target = op.target.call(this, cellValue, options.rowId, rowData, options);
}
if ($.isFunction(op.url)) {
op.url = op.url.call(this, cellValue, options.rowId, rowData, options);
}
if ($.isFunction(op.cellValue)) {
cellValue = op.cellValue.call(this, cellValue, options.rowId, rowData, options);
}
if ($.fmatter.isString(cellValue) || $.fmatter.isNumber(cellValue)) {
return '<a' +
(op.target ? ' target=' + op.target : '') +
(op.onClick ? ' onclick="return $.fn.fmatter.dynamicLink.onClick.call(this, arguments[0]);"' : '') +
' href="' + op.url + '">' +
(cellValue || ' ') + '</a>';
} else {
return ' ';
}
}
});
$.extend($.fn.fmatter.dynamicLink, {
unformat: function (cellValue, options, elem) {
var text = $(elem).text();
return text === ' ' ? '' : text;
},
onClick: function (e) {
var $cell = $(this).closest('td'),
$row = $cell.closest('tr.jqgrow'),
$grid = $row.closest('table.ui-jqgrid-btable'),
p,
colModel,
iCol;

if ($grid.length === 1) {
p = $grid[0].p;
if (p) {
iCol = $.jgrid.getCellIndex($cell[0]);
colModel = p.colModel;
colModel[iCol].formatoptions.onClick.call($grid[0],
$row.attr('id'), $row[0].rowIndex, iCol, $cell.text(), e);
}
}
return false;
}
});
}(jQuery));

I plan to place the code of the formatter and some other plugins to jqGrid on the github.

UPDATED: Free jqGrid extends the options of formatter: "showlink" (see the wiki article and the answer). So one don't need to use the formatter: "dynamicLink" in case of usage free jqGrid.

jqGrd hyperlink or showlink

I agree that the predefined formatter showlink is oriented on hyperlink and it's not comfortable in case when you need to start your custom JavaScript function on click on the link. Nevertheless in the answer you would find the code which explain how you can use showlink in the case.

If you want to add Edit/Delete/Custom hyperlinks in separate columns you can easy use dynamicLink which I wrote and described here. You are right, if you write that the function which you call in onclick attribute of <a> must be defined on the global level. You should not forget, that one can use some common global namespace like jQuery and define many functions which can be called from the jQuerynamespace. For example dynamicLink which you can download from here can be used in the same way as showlink. For example

{ name: 'editlink', formatter: 'dynamicLink',
formatoptions: {
onClick: function (rowid, iRow, iCol, cellText, e) {
// any your code
}
}}

In the implementation the method $.fn.fmatter.dynamicLink.onClick from the dynamicLink will be used in the onclick attribute.

If you prefer to use unobtrusive JavaScript style I would recommend you to read the following answers: this, this and this with the corresponding demos this, this and this. Alternatively you can use doInEachRow which simplify a little the enumeration

loadComplete: function() {
var iCol = getColumnIndexByName.call(this, 'editlink'); // get index of the column

$(this).jqGrid('doInEachRow', function (row, rowId, localRowData) {
$(row.cells[iCol]).children("a").click(function (e) {
e.preventDefault();
// any your code here
});
});
}

where

var getColumnIndexByName = function (columnName) {
var $this = $(this), cm = $this.jqGrid('getGridParam', 'colModel'), i,
l = cm.length;

for (i = 0; i < l; i++) {
if (cm[i].name === columnName) {
return i; // return the index
}
}
return -1;
};

You can easy modify the above code for the case if you place many <a> hyperlinks in one column. In the case you can just replace .children("a") part of $(row.cells[iCol]).children("a").click(function (e) { to .children("a").eq(0) or .children("a").eq(1) and .children("a").eq(2) to define binding to the first, second or third hyperlink ("edit"/"add"/"delete"). You should better to save $(row.cells[iCol]).children("a") in a variable and use .eq(1) with the variable.

One more way will be don't define any <a> an all and use for example <span> instead (with underlining decoration or with background image). In the case you don't need to suppress default hyperlink action and the click event will be bubble till the <table> element which define the grid body. So you can use onCellSelect or beforeSelectRow events to bind your JavaScript code. The Event (e parameter) of the events can be used to get all information about the clicked row and column. var $cell = $(e.target).closest('td') will get you the clicked cell, var $row = $cell.closest('tr.jqgrow') will get you the clicked row, $row.attr('id') will be the rowid and var iCol = $.jgrid.getCellIndex($cell[0]) get you the column index. The this.p.colModel[iCol].name is the name of the column which was clicked. You can read here more bout the way.

How you can see you have really many options which you can use. So you can choose the way which better corresponds your requirements.

How to perform ajax call and redirect to other page if clicked in free jqgrid column

showAction can be used to set the part of URL only. It you want to use the option then you have to use javascript: prefix (see the answer) to start addToCartOnClick which mast be defined as the global function.

The better would be to use new option onClick in formatoptions of formatter: "showlink". I made the corresponding changes of the code of free jqGrid directly after reading of your question. You should refresh the sources which you use from GitHub. Now you can use

{name: "Addtocrt_addtocrt", label: "Add to cart",
search: false, sortable: false, viewable: false,
formatter: "showlink",
formatoptions: {
onClick: function (options) {
// object options contains properties, which could be helpful
// iCol - index of the column in colModel
// iRow - index of the row
// rowid
// cm - element of colModel
// cmName - the same as cm.name
// cellValue: the text inside of `<a>`
// a - DOM element of clicked <a>
// event - Event object of the click event
location.href = "http://www.google.com/";
return false; // it's important to suppress the default a action
}
}}

Creating a link in JQGrid

When click on providerId edit column you will redirect to edit page of editProvider.
mentionformatter: editLink at providerId colModel for call editLink function. In this way creating link in jqGrid.

Code:

$(document).ready(function(){
//jqGrid
$("#providerList").jqGrid({
url:'<%=request.getContextPath() %>/Admin/getProvidersList',
datatype: "json",
colNames:['Id','Edit','Provider Name'],
colModel:[
{name:'providerId',search:false,index:'providerId',hidden:true},
{name:'providerId',search:false,index:'providerId', width:30,sortable: false, formatter: editLink},
{name:'providerName',index:'providerName', width:200},
rowNum:20,
rowList:[10,20,30,40,50],
rownumbers: true,
pager: '#pagerDiv',
sortname: 'providerName',
viewrecords: true,
sortorder: "desc",
});
$('#gridContainer div:not(.ui-jqgrid-titlebar)').width("100%");
$('.ui-jqgrid-bdiv').css('height', window.innerHeight * .65);
$('#load_providerList').width("130");
$("#providerList").jqGrid('navGrid','#pagerDiv',{edit:false,add:false,del:false},{},{},{}, {closeAfterSearch:true});
$(".inline").colorbox({inline:true, width:"20%"});
});
function editLink(cellValue, options, rowdata, action)
{
return "<a href='<%=request.getContextPath()%>/Admin/editProvider/" + rowdata.providerId + "' class='ui-icon ui-icon-pencil' ></a>";
}


Related Topics



Leave a reply



Submit