How can I add a jQuery UI icon to a dynamically generated button?

大兔子大兔子 提交于 2019-12-22 18:16:36

问题


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?


回答1:


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.




回答2:


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! :-)



来源:https://stackoverflow.com/questions/12976396/how-can-i-add-a-jquery-ui-icon-to-a-dynamically-generated-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!