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:
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 jQuery
namespace. 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
Retrieving Binary File Content Using JavaScript, Base64 Encode It and Reverse-Decode It Using Python
Javascript: Check If Mouse Button Down
Secure Random Numbers in JavaScript
Deep Copy in Es6 Using the Spread Syntax
Angular2 Dynamic Input Field Lose Focus When Input Changes
Executing JavaScript from Python
How to Filter Array When Object Key Value Is in Array
Testing If a Checkbox Is Checked with Jquery
How to Convert JSON Object to JavaScript Array
Fulfill (Don't Resolve) Promise with Another Promise
How to Filter JSON Data in JavaScript or Jquery
Why Were Es5 Object Methods Not Added to Object.Prototype
How to Get Subarray from Array
Iterate Over Object Literal Values
Why Does Isnan(" ") (String with Spaces) Equal False
Jquery - Script Tags in the HTML Are Parsed Out by Jquery and Not Executed