2012-10-19 10 views
2

При загрузке пользовательского интерфейса jQuery вы получаете таблицу стилей для любой темы, а также несколько файлов изображений, содержащих значки. Я понял, как добавить значок в один элемент <button>, но у меня есть ситуация, когда я динамически генерирую кнопки в сетке (jqGrid) и хочу использовать эти значки. Так, скажем, я хочу использовать эту иконку из файла CSS:Как добавить иконку jQuery UI на динамически сгенерированную кнопку?

.ui-icon-trash { background-position: -176px -96px; } 

Затем добавить кнопки в сеть обработки gridComplete события:

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 }); 
    } 
} 

Я пытался использовать класс в кнопки тега, например, deleteRowButton, а затем с помощью JQuery, как это:

$(".deleteRowButton").button({ 
    icons: { 
     primary: 'ui-icon-trash' 
    }, 
    text: false 
}); 

Но это не работает. Что мне нужно сделать, чтобы мои кнопки имели этот значок?

ответ

4

Я полагаю, что ваш код с $(".deleteRowButton").button({icons: {primary: 'ui-icon-trash'}, text: false}); не работал, потому что вы поместили его в неправильном месте. Если вы создаете <button class='deleteRowButton' ...> внутри gridComplete вы должны сделать вызов $(".deleteRowButton").button(...) также внутри gridComplete непосредственно после того, как код, который вы публикуемую:

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 
    }); 
} 

см the first demo.

Небольшая проблема существует при выполнении вышеуказанного подхода. Используя setRowData, вы внесете изменения на страницу. При каждом изменении на странице происходит пересчет позиций всех остальных элементов, существующих на странице. Поэтому для повышения производительности рекомендуется уменьшить количество изменений в сетке. Таким образом, лучшим способом является использование custom formattrer. Новая версия кода будет практически такой же простой, как предыдущая. Вам просто нужно определить formatter как функцию:

{ name: 'DeleteButton', width: 20, 
    formatter: function (cellvalue, options) { 
     return "<button type='button' class='deleteRowButton' " + 
      "style='height: 22px;width: 20px;' title='Delete'></button>"; 
    }}, 

и уменьшить код gridComplete или loadComplete в

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"); 
    }); 
} 

В исходном коде метод deleteRow должен быть глобальной (она должна быть определена на верхний уровень). Новый код может использовать только обработчик событий click. См. the next demo.

Кстати, вам не нужно связывать каждый <button> с click обработчиком событий. Как известно, если на кнопке нет click обработчика событий, то будет event bubbling. Поэтому вместо привязки обработчика события click каждый раз при загрузке и перезагрузке сетки можно просто определить один раз соответствующий обработчик события на весь корпус сетки. Другими словами, вы можете использовать обратный вызов onCellSelect. использование очень удобно, потому что rowid и индекс столбца щелкнутой ячейки уже рассчитаны. Кроме того, для 4-го параметра e обратного вызова onCellSelect вы можете получить доступ к обработчику событий, где e.tagret является элементом DOM щелкнутого <button>. Таким образом, вы можете заменить выше код gridComplete на следующий код:

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 
    }); 
} 

В пути вы можете более повысить производительность и уменьшить немного памяти, используемой для этой страницы. The demo показывает последний код в прямом эфире. В большинстве случаев вам не нужно использовать такие конструкции, как $(e.target).closest("button.deleteRowButton").length > 0. Вместо этого вы можете просто проверить индекс столбца iCol. Если вам нужно, вы можете протестировать имя столбца. Вы можете использовать

$(this).jqGrid("getGridParam", "colModel")[iCol].name 

преобразовать iCol к соответствующему имени столбца.

1

Я бы предложил переключиться с «кнопки» на «input type =» button »' Вы должны иметь возможность использовать фоновое изображение в CSS для установки значка. Ваша сетка полная функция будет выглядеть примерно так:

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 });  
}  

}

и ваш CSS будет выглядеть следующим образом:

#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 */ 
} 

Вам не нужно будет использовать JQuery, чтобы применить значок, поскольку CSS сделает это за вас. Магия CSS снова побеждает! :-)

+0

Спасибо Frankie. Так как значок на самом деле является частью большего изображения, имеющего все значки в нем, что бы я указал для моего «фонового изображения»? Вот ссылка на набор значков: http://jquery-ui.googlecode.com/svn/tags/1.6rc5/tests/static/icons.html –

+0

Хмммм, это может быть немного сложнее. Что вам нужно сделать, так это указать смещение фона так: background-position: -176px -96px; – FrankieAvocado

+0

Хммм, это не будет обрезать размер вниз, поэтому, в итоге вы получите все остальные значки. Возможно, вам удастся избежать псевдоселектора под названием «Before», но я не думаю, что IE8/7/6 его поддержит, но это будет означать, что вам придется выбирать что-то другое, кроме кнопки, поскольку кнопки не могут содержать другие элементы (возможно, ярлык привязки будет хорош). См. Http://nicolasgallagher.com/css-background-image-hacks/ – FrankieAvocado

Смежные вопросы