// the column model has information about grid columns. // dataIndex maps the column to the specific data field in // the data store // returns a little icon which, when clicked on, redirects the browser to // the grid of a related table function createGridButton(id, table, url, pk) { new Ext.Button({ cls: 'x-btn-text-icon' ,tooltip: 'Jump to this ' + table ,handler: function(btn, e) { Ext.DomHelper.append( Ext.getBody() ,{ tag: 'form' ,name: 'transportform' ,id: 'transportform' ,action: url ,method: 'POST' ,cn: pk } ).submit(); } ,icon: '[% c.uri_for( c.controller('AutoCRUD::Static').action_for('cpacstatic'), "table_go.png" ) %]' }).render(document.body, id); } // text added to FK combo list to hint for the full-text-search option var fk_combo_comment = ' (all matches)'; // create reusable renderer Ext.util.Format.comboRenderer = function(combo, table, field, url) { return function(value,metadata,record,rowindex,colindex,store) { // choose what to render from the combobox store's data if (rowindex === 0) { var rec = combo.findRecord(combo.valueField, value); var retval = rec ? rec.get(combo.displayField) : value; return (retval.indexOf(fk_combo_comment) !== -1) ? value : retval; } if (value) { // create an id, attached to a span, and hang a button off it var id = Ext.id(); // if the related table is "hidden" we are not passed field, // so this get() fails and the plain value is displayed var pk = record.get('cpac__pk_for_' + field); if (pk) { createGridButton.defer(1, this, [id, table, url, pk]); return ('' + value); } return value; } return ''; } }; // used to hack an extra entry into the store results on filters var sfyRecord = Ext.data.Record.create([ { name: 'dbid' }, { name: 'stringified' } ]); // create the combo instances [% FOREACH col IN cpac.tc.cols %] [% NEXT UNLESS cpac.tm.f.$col.is_foreign_key OR cpac.tm.f.$col.extra('is_reverse') %] [% NEXT IF cpac.tm.f.$col.extra('masked_by') %] var fk_combo_[% col | replace('\'', '\\\'') %] = new Ext.form.ComboBox ({ valueField: 'dbid' ,displayField: 'stringified' ,hiddenName: 'combobox.[% col | replace('\'', '\\\'') %]' ,hiddenId: 'fk_combo_[% col | replace('\'', '\\\'') %]' ,loadingText: 'Searching...' ,forceSelection: true ,selectOnFocus: true ,typeAhead: false ,pageSize: 10 ,triggerAction: 'all' ,lazyRender: true ,listClass: 'x-combo-list-small' ,lastQuery: '' ,store: new Ext.data.JsonStore ({ [% IF cpac.tm.f.$col.extra('rel_type') == 'many_to_many' %] url: '[% c.uri_for( c.controller('AutoCRUD::DisplayEngine::ExtJS2').action_for('list_stringified'), [ cpac.g.site, cpac_db, cpac.tm.f.$col.extra('via').0 ] ) %]' [% ELSE %] url: '[% c.uri_for( c.controller('AutoCRUD::DisplayEngine::ExtJS2').action_for('list_stringified'), [ cpac.g.site, cpac_db, cpac_table ] ) %]' [% END %] ,root: 'rows' ,totalProperty: 'total' ,fields: [ 'dbid', 'stringified' ] ,listeners: { beforeload: function(store, options) { var start = options.params.start; var limit = options.params.limit; options.params.page = Math.floor(start / limit) + 1; [% IF cpac.tm.f.$col.extra('rel_type') == 'many_to_many' %] options.params.fkname = '[% cpac.tm.f.$col.extra('via').1 | replace('\'', '\\\'') %]'; [% ELSE %] options.params.fkname = '[% col | replace('\'', '\\\'') %]'; [% END %] if (fk_combo_[% col | replace('\'', '\\\'') %].getRawValue() && (options.params.page === 1)) { // so that we can hack in an extra row options.params.limit = 9; } return true; } ,load: function(store, records, options) { var queryText = fk_combo_[% col | replace('\'', '\\\'') %].getRawValue(); if (queryText.length && (options.params.page === 1)) { // be sure not to accidentally add a 2nd copy of fk_combo_comment if (queryText.indexOf(fk_combo_comment) !== -1) { queryText = queryText.replace(fk_combo_comment,''); } // insert an extra row with full-text-search option store.insert(0, new sfyRecord({ dbid: queryText ,stringified: queryText + fk_combo_comment })); } } } }) ,listeners: { // delete the previous query in the beforequery event or set // combo.lastQuery = null (this will reload the store the next time it expands) beforequery: function(qe) { delete qe.combo.lastQuery; } ,blur : function() { if (this.allowBlank && this.getRawValue() === '') { this.clearValue(); } } } }); [% END %] // we first process the main, ordinary cols (pk and others) // the do the one_to_many cols, and then add a column with a delete button var cm = new Ext.grid.ColumnModel([ [% FOREACH col IN cpac.tc.cols %] [% ',' IF NOT loop.first %]{ header: '[% cpac.tc.headings.$col %]' [% SET link = cpac.tm.f.$col.extra('ref_table') %] [% ',hidden: true' IF cpac.tc.hidden_cols.exists(col) %] [% IF (NOT cpac.tm.f.$col.extra('masked_by')) AND (cpac.tm.f.$col.is_foreign_key OR cpac.tm.f.$col.extra('is_reverse')) %] [% IF cpac.tm.f.$col.extra('rel_type').match('_many') %] ,dataIndex: '[% col | replace('\'', '\\\'') %]' ,editor: fk_combo_[% col | replace('\'', '\\\'') %] //reference to combo instance ,sortable: false ,menuDisabled: true ,tooltip: 'Hover mouse over a cell
to show related data' ,renderer: function (value,metadata,record,rowindex,colindex,store) { if (rowindex === 0) { var combo = fk_combo_[% col | replace('\'', '\\\'') %] var rec = combo.findRecord(combo.valueField, value); var retval = rec ? rec.get(combo.displayField) : value; return (retval.indexOf(fk_combo_comment) !== -1) ? value : retval; } else if (record.get('[% col | replace('\'', '\\\'') %]').join('') === '') { return '' } else { metadata.css += 'half-grey'; metadata.attr += 'ext:qtitle="[% cpac.tc.headings.$col %]" ext:qtip="' + record.get('[% col | replace('\'', '\\\'') %]').join('
') + '"'; return '' + ' Show'; } } [% ELSE %] ,dataIndex: '[% col | replace('\'', '\\\'') %]' ,editor: fk_combo_[% col | replace('\'', '\\\'') %] //reference to combo instance // pass combo instance to reusable renderer [% SET ref_table = cpac.tm.f.$col.extra('ref_table') %] [% IF cpac.c.$cpac_db.t.$ref_table.hidden == 'yes' %] ,renderer: Ext.util.Format.comboRenderer(fk_combo_[% col %]) [% ELSE %] // takes the combo-name, table display name (for tooltip), col // name (for retrieving FK's PK data), and target URL for POST ,renderer: Ext.util.Format.comboRenderer( fk_combo_[% col %] ,'[% cpac.c.$cpac_db.t.$ref_table.display_name %]' ,'[% col | replace('\'', '\\\'') %]' [% IF cpac.g.site == 'default' %] ,'[% c.uri_for( c.controller('AutoCRUD::Root').action_for('table'), [cpac_db], ref_table ) %]' [% ELSE %] ,'[% c.uri_for( c.controller('AutoCRUD::Root').action_for('source'), [cpac.g.site,cpac_db], ref_table ) %]' [% END %] ) [% END %] [% END %] [% ELSE %] ,dataIndex: '[% col | replace('\'', '\\\'') %]' ,editor: new Ext.form.TextField({}) ,renderer: function (value,metadata,record,rowindex,colindex,store) { [% IF cpac.tm.f.$col.extra('extjs_xtype') == 'checkbox' %] if (rowindex === 0) { return '' } if (value == '1') { return ''; } else { return ''; } [% ELSE %] return value; [% END %] } [% END %] } [% END %] [% IF cpac.tc.delete_allowed == 'yes' %] ,{ header: 'Delete' ,width: 35 ,dataIndex: 'cpac-delete-column' ,align: 'left' ,sortable: false ,menuDisabled: true ,renderer: function (value,metadata,record,rowindex,colindex,store) { if (rowindex === 0) { return '' } else { metadata.attr += 'ext:qtitle="Delete" ext:qtip="' + record.get('cpac__display_name') + '"'; return ''; } } } [% END %] ]); // by default columns are sortable cm.defaultSortable = true;