Reputation: 16729
When downloading jQuery UI you get a stylesheet for whatever theme was selected, as well as several image files containing icons. I've figured out how to add an icon to a single <button>
element, but I have a situation where I'm dynamically generating buttons in a grid (jqGrid) and want to use these icons. So, say I want to use this icon from the CSS file:
.ui-icon-trash { background-position: -176px -96px; }
Then, I add the buttons to the grid by handling the gridComplete
event:
gridComplete: function () {
var ids = $("#myGrid").jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var deleteButton = "<button type='button' style='height: 22px;width: 20px;' title='Delete' onclick=deleteRow(" + ids[i] + ")></button>";
$("#myGrid").jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });
}
}
I've tried using a class in the button tag, for example, deleteRowButton
, and then using jQuery like this:
$(".deleteRowButton").button({
icons: {
primary: 'ui-icon-trash'
},
text: false
});
But this doesn't work. What do I have to do to get my buttons to have this icon?
Upvotes: 2
Views: 3457
Reputation: 222017
I suppose that your code with $(".deleteRowButton").button({icons: {primary: 'ui-icon-trash'}, text: false});
didn't worked because you placed it in the wrong place. If you create the <button class='deleteRowButton' ...>
inside of gridComplete
you should make the call $(".deleteRowButton").button(...)
also inside of gridComplete
directly after the code which you posted:
gridComplete: function () {
var $this = $(this), ids = $this.jqGrid('getDataIDs'), l = ids.length,
i, deleteButton;
for (i = 0; i < l; i++) {
deleteButton = "<button type='button' style='height:22px;width:20px;'" +
" class='deleteRowButton' title='Delete' onclick=deleteRow(" +
ids[i] + ")></button>";
$this.jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });
}
$(".deleteRowButton").button({
icons: {
primary: 'ui-icon-trash'
},
text: false
});
}
see the first demo.
The small problem exists in the performance of the above approach. Using setRowData
you make changes on the page. Every change on the page follow recalculation of positions of all other elements existing on the page. So to improve performance it's recommended to reduce the number of changes on the grid. So the better way is the usage of custom formattrer. The new version of the code will be practically exactly so easy as the previous one. You just need to define formatter
as function:
{ name: 'DeleteButton', width: 20,
formatter: function (cellvalue, options) {
return "<button type='button' class='deleteRowButton' " +
"style='height: 22px;width: 20px;' title='Delete'></button>";
}},
and reduce the code of gridComplete
or loadComplete
to
gridComplete: function () {
$(".deleteRowButton").button({
icons: {
primary: 'ui-icon-trash'
},
text: false
}).click(function (e) {
var $tr = $(e.target).closest("tr.jqgrow");
alert("the row with id=" + $tr.attr("id") + " need be deleted");
});
}
In your original code the method deleteRow
must be global (it should be defined on the top level). The new code can use just click
event handler. See the next demo.
By the way you don't really need to bind every <button>
to click
event handler. As well known if there are no click
event handler on the button the event bubbling will take place. So instead of binding click
event handler every time on loading and reloading of the grid one can just define once the corresponding event handler on the whole grid body. In other words you can use onCellSelect
callback. the usage is very comfortable because the rowid
and the index of the column of the clicked cell are already calculated. Moreover per 4-th parameter e
of the onCellSelect
callback you can access to the event handler where e.tagret
is the DOM element of the clicked <button>
. So you can replace the above code of gridComplete
to the following code:
onCellSelect: function (rowid, iCol, cellcontent, e) {
if ($(e.target).closest("button.deleteRowButton").length > 0) {
alert("the row with id=" + rowid + " need be deleted");
}
},
gridComplete: function () {
$(".deleteRowButton").button({
icons: {
primary: 'ui-icon-trash'
},
text: false
});
}
In the way you can more improve the performance and reduce a little the memory used for the page. The demo shows the last code live. In the most cases you don't need to use constructs like $(e.target).closest("button.deleteRowButton").length > 0
. Instead of that you can just verify the column index iCol
. If you need you can test the column name instead. You can use
$(this).jqGrid("getGridParam", "colModel")[iCol].name
to convert the iCol
to the corresponding column name.
Upvotes: 4
Reputation: 343
I'd suggest switching from 'button' to 'input type="button"' You should be able to use the background image in CSS to set an icon. Your grid complete function would look something like this:
gridComplete: function () {
var ids = $("#myGrid").jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var deleteButton = "<input type='button' class='HasIcon' style='height: 22px;width: 20px;' title='Delete' onclick=deleteRow(" + ids[i] + ")/>";
$("#myGrid").jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });
}
}
and your CSS would look like this:
#myGrid input[type=button].HasIcon
{
background-image: url(/* icon location */);
background-repeat: no-repeat;
text-align: center;
padding-left: 20px; /* slightly longer than your icon */
}
You won't need to use jquery to apply the icon, since CSS will do that for you. The magic of CSS triumphs again! :-)
Upvotes: 1