📜 ⬆️ ⬇️

Component for integrating Ext.grid.Panel lines with Ext.toolbar.Toolbar

As part of the creation of the administrative part of one of the projects, I was lucky to develop a rather slim component that elegantly complements the fairly rich functionality of the ExtJS 4 library.

Usage example: http://siterra.org/examples/rowtoolbar.html
Repository: https://github.com/siterra/RowToolbar
Tested with ExtJS 4.1.1a.


I decided to place it in free access under the Apache License 2.0 license. Moreover, it turned out to be quite easy, but very convenient to use.
')
The problem that the component solves sounds like the need to create function buttons for each individual row in the table in the most flexible way.

Of course, there is an “actioncolumn” for solving this problem. However, for its element there is no normal possibility to add a label to the button. But instead of placing the buttons in an additional column, it was decided to transfer them to a new line for greater clarity, since it is often enough for the employee to read the first cell in order to start reaching for the function button.

/* Copyright 2013 Siterra Ltd. (www.siterra.org) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ Ext.define('Ext.ux.grid.features.RowToolbar', { extend: 'Ext.grid.feature.Feature', alias: 'feature.rowtoolbar', rowToolbarCls: 'app-grid-feature-rowtoolbar', /* @param renderTimeout (int) * Timeout for delay before render items. Required, because we have no events to call * our render after data loads and grid rendered. It can be edit, then computer is too * slow to render so fast. */ renderTimeout: 1, toolbar: {}, init: function() { this.toolbar = Ext.applyIf(this.toolbar, { xclass: 'Ext.toolbar.Toolbar', padding: '0 16 0 0', cls: 'grid-feature-rowtoolbar-instance', baseCls: '', baseId: Ext.id() + '-rowtoolbar', /* @optional * @param isDisabledForRecord (function) * Function gives a record to check enable item or not for it * inputs * @param record * @return boolean */ /* @optional * @param isVisibleForRecord (function) * Function gives a record to check visibility of item * inputs * @param record * @return boolean */ /* @optional * @param hiddenItemsSavePosition (boolean) * With this flag is true and element is hidden, then it's width * doesn't 0. Visibility doesn't influence on positioning othe items. */ listeners: { scope: this, afterrender: function(tbar) { Ext.each(tbar.items.items, function(item) { if (item.isDisabledForRecord) { var is_disabled = item.isDisabledForRecord(item, tbar.record); item.setDisabled(is_disabled); } if (item.isVisibleForRecord) { var is_visible = item.isVisibleForRecord(item, tbar.record); if (item.hiddenItemsSavePosition) { item.getEl().dom.style.visibility = (is_visible ? 'visible' : 'hidden'); } else { item.setVisible(is_visible); } } }, this); } } /* @variable renderedItems * Keeps rendered components created with help of this toolbar config */ /* each renderedItem has * @variable record * what links to it's own record in store * Keeps rendered components created with help of this toolbar config */ }); }, renderItems: function() { this.toolbar.renderedItems = []; var els = Ext.query('.'+ this.toolbar.baseId +'-wrap', this.grid.getEl().dom); Ext.each(els, function(el) { // clone toolbar config for each row var tb_clone = Ext.clone(this.toolbar); tb_clone.items = Ext.clone(this.items); // find record in store for current row var row = Ext.get(el).up('.x-grid-row'); if (row) { tb_clone.record = this.grid.getView().getRecord(row); } // create and render toolbar for current row tb_clone = Ext.create(tb_clone); el.innerHTML = ''; tb_clone.render(el); // remember an item this.toolbar.renderedItems.push(tb_clone); }, this); }, getRowToolbar: function() { var tpl = '<tr class="'+ this.rowToolbarCls +'">'+ '<td class="'+ this.rowToolbarCls +'" colspan="{[ this.embedColSpan() ]}">'+ '<div class="'+ this.toolbar.baseId +'-wrap '+ this.rowToolbarCls +'-btn"></div>'+ '</td>'+ '</tr>'; return tpl; }, embedColSpan: function() { return '{rowToolbarColspan}'; }, getAdditionalData: function(data, idx, record, orig) { var colspan = this.view.headerCt.getColumnCount(); return { rowToolbarCls: this.rowToolbarCls, rowToolbarColspan: colspan }; }, mutateMetaRowTpl: function(metaRowTpl) { metaRowTpl.push(this.getRowToolbar()); }, getMetaRowTplFragments: function() { // render toolbar after some time Ext.defer(this.renderItems, this.renderTimeout, this); return { embedColSpan: this.embedColSpan }; } }); 


The presented development is connected to the table as a “feature”. At the same time, it requires the connection of the rowwrap component. This is necessary to preserve the visual design of the table and conveniently manage the rows.

 features: [{ ftype: 'rowtoolbar', items: [ ... ] },{ ftype: 'rowwrap' }] 


Items declared in the items field will be created as many times as there will be rows in the table after the data is loaded. Sometimes it is necessary to change the flags "hidden" and "disabled". Therefore, the isDisabledForRecord and isVisibleForRecord functions are created in RowToolbar. Each of the functions receives 2 parameters: an instance of the RowToolbar element, and Ext.data.Record (Ext.data.Model), associated with the table row being processed. Thus, depending on the content of the line, it becomes possible to change the display of elements.

Source: https://habr.com/ru/post/168413/


All Articles