Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.10.2011, 11:13
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Засунуть Panel внутрь RowExpander
Объясню сразу - Ext знаю очень плохо, а сделать надо много, разбираюсь в процессе, но тут застопорилось.
Мне нужно сделать следующее: дерево с таблицей (взяла из примера http://dev.sencha.com/deploy/ext-4.0.../treegrid.html), в него подключила RowExpander - работает. Но пришлось поискать решение проблемы RowExpander подглючивает в 4.0.2. Нашла хак, работает (хак - в 180 строке заменяла:
var rowNode = this.getCmp().view.getNode(rowIdx);  ///BECKY
		var row = Ext.get(rowNode);
		var nextBd = Ext.get(row).down(this.rowBodyTrSelector);
		var record = this.getCmp().view.getRecord(rowNode);

/*        var rowNode = this.view.getNode(rowIdx),
            row = Ext.get(rowNode),
            nextBd = Ext.get(row).down(this.rowBodyTrSelector),
            record = this.view.getRecord(rowNode);*/
- на оф. сайте пишут, что исправленно в версии 4.0.4, но когда она светит и светит ли вообще бесплатным пользователям - ответа на этот вопрос я так и не нашла). Ладно, проехали.
RowExpander делает один длинный td на всю строку, что меня не устраивает - мне нужны те же колонки, что и есть, поэтому скопировала его, переименовала в CellExpander и чуть поправила - в строке 124 приписала o.rowBodyColspan = 1; (чтобы td не соллапсил на всю строку), а в темплейте прописала все нужные td-шки. Все вышло, все работает, шаблон можно использовать.
Но осталась главная проблема. Я хочу в каждую из получившихся ячеек вставить панель и грузить там в нее информацию (не важно, какую).
Попробовала так - добавила в шаблон вывода код <div id="mypanel{id}"></div> (например). Дивы появились, с разными id-шниками, как и положено, но вставить нормально панели так и не получилось.
Вполне возможно, что моя методика изначально неправильная и можно было бы сделать это все как-то проще, но как - я не понимаю. Интуиция подсказывает, что фокус где-то в XTemplate, но я не понимаю, как он работает в упор.
Подскажите, куда идти дальше? Либо нужно вставлять панельки после создания каждой строки (т. е. нужна мне название функции, чтобы по ним пробежаться), либо как там и что... не знаю даже... я привыкла к jquery, в котором твори что хочешь и когда хочешь, а тут дошла до точки - и не могу. Пыталась разобраться в работе RowExpander'а вообще - так вообще ничего и не понимаю. Как он что делает .
Короче,
На всякий случай еще добавлю, что собираюсь в каждую колонку после "раскрытия" вставить дерево, т. е. там будет загрузка данных с разных урлов (в смысле параметр будет разный, id - параметр из строки и номер колонки). Может, так будет понятнее...
Ответить с цитированием
  #2 (permalink)  
Старый 13.10.2011, 12:58
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

В продолжение
Дошла до такого варианта:
в store (который Ext.data.TreeStore) ставим событие

listeners: {
            load: function(){
				Ext.get("mypanel3").dom.innerHTML = "!!!";
				mypanel3 = Ext.create("Ext.Panel", {
					title: 'mypanel3',
					width: 100,
					height: 100,
					html: 'alsdfjasdf',
					renderTo: 'mypanel3'
				})
            },
            scope: this
        }

Событие срабатывает, панелька вставляется, что радует. НО вставляется каким-то дико-странным образом - крошечным квадратиком. Получаемый html выглядит так:

<div id="mypanel3">!!!<div id="panel-1227" class="x-panel x-panel-default" style="width: 100px; height: 100px;" role="presentation" aria-labelledby="component-1229"><div id="header-1228" class="x-panel-header x-panel-header-default x-horizontal x-panel-header-horizontal x-panel-header-default-horizontal x-top x-panel-header-top x-panel-header-default-top x-unselectable x-docked x-docked-top x-panel-header-docked-top x-panel-header-default-docked-top" style="-moz-user-select: none; width: 0px; left: 0px; top: 0px;" role="presentation"><div class="x-panel-header-body x-panel-header-body-default-horizontal x-panel-header-body-default-top x-panel-header-body-default x-panel-header-body-horizontal x-panel-header-body-top x-box-layout-ct" id="ext-gen1654"><div role="presentation" class="x-box-inner" id="ext-gen1656"><div id="component-1229" class="x-component x-box-item x-component-default" role="heading" style="margin: 0pt; width: 0px; left: 0px; top: 0px;"><span class="x-panel-header-text x-panel-header-text-default" id="ext-gen1657">mypanel3</span></div></div></div></div><div class="x-panel-body  x-panel-body-default x-panel-body-default" id="ext-gen1651" style="width: 0px; height: 0px; left: 0px; top: 0px;">alsdfjasdf</div></div></div>


Есть идеи, как избавиться от всех этих width: 0px и height: 0px? Откуда они вообще берутся?
Ответить с цитированием
  #3 (permalink)  
Старый 13.10.2011, 13:35
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Прогресс - если выбрать
layout: 'form',

получится не квадратик, а линия на всю строку (что правильно и хорошо). html в нее тоже вставляется. Вот только, если пробую вставить панель как items, все нафиг пропадает...
Ответить с цитированием
  #4 (permalink)  
Старый 13.10.2011, 14:03
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Ну, да, ну, да, снова неудача. layout: 'form', на самом деле вызывает ошибку... блин, помогите!
Ответить с цитированием
  #5 (permalink)  
Старый 13.10.2011, 21:51
Аватар для DreamTheater
Профессор
Отправить личное сообщение для DreamTheater Посмотреть профиль Найти все сообщения от DreamTheater
 
Регистрация: 15.02.2011
Сообщений: 471

Не понял суть проблемы, можете сформулировать иначе?
Ответить с цитированием
  #6 (permalink)  
Старый 17.10.2011, 12:31
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Да, наверное, я написала слишком запутанно, сорри. Начнем с начала.
Есть у меня Ext.tree.Panel с колонками - TreeGrid (как вот в этом примере http://dev.sencha.com/deploy/ext-4.0.../treegrid.html). К нему подключен rowexpander. Т. е. открывается/закрывается некое полное описание, но при этом еще могут быть и подразделы, у которых свое полное описание.
И вот в это "полное описание" я хочу вставить панель TreePanel. А у меня не получается. А то, как я это "вставляю" и описано выше. Могу дать более полный код, может, понятнее будет, чем со словесных объяснений. Сейчас, только почищу его от своего мусора
Ответить с цитированием
  #7 (permalink)  
Старый 17.10.2011, 12:52
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Вот упрощенный вариант того, что я делаю:
html-страница:
<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
<html>
    <head>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
        <title></title>
        <link rel='stylesheet' type='text/css' href='/js/lib/extjs/resources/css/ext-all.css'>
        <script type='text/javascript' src='/js/lib/extjs/bootstrap.js'></script>
<link rel='stylesheet' type='text/css' href='/js/lib/extjs/examples/ux/css/ItemSelector.css'>

        <script type='text/javascript' src='/js/crm-project1.js'></script>
    </head>
<body>
<div id='content'>
</div>
</body>
</html>


Скрипт:
Ext.Loader.setConfig({
    enabled: true
});
Ext.Loader.setPath('Ext.ux', '/js/lib/extjs/examples/ux');
Ext.require(['Ext.*', 'Ext.ux.*', 'Ext.ux.RowExpander', 'Ext.ux.form.ItemSelector', 'Ext.ux.form.MultiSelect', 'Ext.tab.*', 'Ext.tree.*', 'Ext.data.*', 'Ext.tip.*']);

Ext.onReady(function(){
    Ext.QuickTips.init();
    
    
    Ext.define('Task', {
        extend: 'Ext.data.Model',
        fields: [{
            name: 'id',
            type: 'int'
        }, {
            name: 'priority',
            type: 'int'
        }, {
            name: 'text',
            type: 'string'
        }, {
            name: 'description',
            type: 'html'
        }]
    });
    
    
    var store = Ext.create('Ext.data.TreeStore', {
        model: 'Task',
        proxy: {
            type: 'ajax',
            url: '/data.json'
        },
        folderSort: true,
        sorters: [{
            property: 'priority',
            direction: 'DESC'
        }]
    });
	
	templateHtml = '<div>{description}</div><div id="mypanel{id}"></div>';
	
    var tree = Ext.create("Ext.tree.Panel", {
        plugins: [{
            ptype: 'rowexpander',
            rowBodyTpl: [templateHtml]
        }],
        store: store,
        collapsible: true,
        rootVisible: false,
        useArrows: true,
        multiSelect: true,
        singleExpand: false,
		region: 'center',
        columns: [{
            xtype: 'treecolumn',
            text: 'text',
            dataIndex: 'text',
            flex: 1,
            enableSort: true,
            ddAppendOnly: true
        }, {
            text: 'id',
            flex: 1,
            dataIndex: 'id',
        }, {
            text: 'priority',
            flex: 1,
            dataIndex: 'priority',
        }],
    });
    var ProjectPanel = Ext.create("Ext.Viewport", {
        id: 'project-panel',
        renderTo: 'content',
        layout: 'border',
        items: [tree]
    });
    
});


Вот. Мне нужно вместо дивов mypanel3 и т. д. вставить панели TreePanel, а у меня не получается
Ответить с цитированием
  #8 (permalink)  
Старый 17.10.2011, 12:54
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Стандартный rowexpander в версии 4.0.2 (даже на http://dev.sencha.com/deploy/ext-4.0...d-plugins.html он не работает) не рабочий, поэтому вот исправленный код его заодно, который я использую (если есть другой - буду только рада заменить):

/*

This file is part of Ext JS 4

Copyright (c) 2011 Sencha Inc

Contact:  [url]http://www.sencha.com/contact[/url]

GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: [url]http://www.gnu.org/copyleft/gpl.html[/url].

If you are unsure which license is appropriate for your use, please contact the sales department at [url]http://www.sencha.com/contact[/url].

*/
// feature idea to enable Ajax loading and then the content
// cache would actually make sense. Should we dictate that they use
// data or support raw html as well?

/**
 * @class Ext.ux.RowExpander
 * @extends Ext.AbstractPlugin
 * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
 * a second row body which expands/contracts.  The expand/contract behavior is configurable to react
 * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
 *
 * @ptype rowexpander
 */
Ext.define('Ext.ux.RowExpander', {
    extend: 'Ext.AbstractPlugin',
    alias: 'plugin.rowexpander',

    rowBodyTpl: null,

    /**
     * @cfg {Boolean} expandOnEnter
     * <tt>true</tt> to toggle selected row(s) between expanded/collapsed when the enter
     * key is pressed (defaults to <tt>true</tt>).
     */
    expandOnEnter: true,

    /**
     * @cfg {Boolean} expandOnDblClick
     * <tt>true</tt> to toggle a row between expanded/collapsed when double clicked
     * (defaults to <tt>true</tt>).
     */
    expandOnDblClick: true,

    /**
     * @cfg {Boolean} selectRowOnExpand
     * <tt>true</tt> to select a row when clicking on the expander icon
     * (defaults to <tt>false</tt>).
     */
    selectRowOnExpand: false,

    rowBodyTrSelector: '.x-grid-rowbody-tr',
    rowBodyHiddenCls: 'x-grid-row-body-hidden',
    rowCollapsedCls: 'x-grid-row-collapsed',



    renderer: function(value, metadata, record, rowIdx, colIdx) {
        if (colIdx === 0) {
            metadata.tdCls = 'x-grid-td-expander';
        }
        return '<div class="x-grid-row-expander">&#160;</div>';
    },

    /**
     * @event expandbody
     * <b<Fired through the grid's View</b>
     * @param {HtmlElement} rowNode The &lt;tr> element which owns the expanded row.
     * @param {Ext.data.Model} record The record providing the data.
     * @param {HtmlElement} expandRow The &lt;tr> element containing the expanded data.
     */
    /**
     * @event collapsebody
     * <b<Fired through the grid's View.</b>
     * @param {HtmlElement} rowNode The &lt;tr> element which owns the expanded row.
     * @param {Ext.data.Model} record The record providing the data.
     * @param {HtmlElement} expandRow The &lt;tr> element containing the expanded data.
     */

    constructor: function() {
        this.callParent(arguments);
        var grid = this.getCmp();
        this.recordsExpanded = {};
        // <debug>
        if (!this.rowBodyTpl) {
            Ext.Error.raise("The 'rowBodyTpl' config is required and is not defined.");
        }
        // </debug>
        // TODO: if XTemplate/Template receives a template as an arg, should
        // just return it back!
		
        var rowBodyTpl = Ext.create('Ext.XTemplate', this.rowBodyTpl),
            features = [{
                ftype: 'rowbody',
                columnId: this.getHeaderId(),
                recordsExpanded: this.recordsExpanded,
                rowBodyHiddenCls: this.rowBodyHiddenCls,
                rowCollapsedCls: this.rowCollapsedCls,
                getAdditionalData: this.getRowBodyFeatureData,
                getRowBodyContents: function(data) {
                    return rowBodyTpl.applyTemplate(data);
                }
            },{
                ftype: 'rowwrap'
            }];

        if (grid.features) {
            grid.features = features.concat(grid.features);
        } else {
            grid.features = features;
        }

        grid.columns.unshift(this.getHeaderConfig());
        grid.on('afterlayout', this.onGridAfterLayout, this, {single: true});
    },

    getHeaderId: function() {
        if (!this.headerId) {
            this.headerId = Ext.id();
        }
        return this.headerId;
    },

    getRowBodyFeatureData: function(data, idx, record, orig) {
        var o = Ext.grid.feature.RowBody.prototype.getAdditionalData.apply(this, arguments),
            id = this.columnId;
        o.rowBodyColspan = o.rowBodyColspan - 1;
        o.rowBody = this.getRowBodyContents(data);
        o.rowCls = this.recordsExpanded[record.internalId] ? '' : this.rowCollapsedCls;
        o.rowBodyCls = this.recordsExpanded[record.internalId] ? '' : this.rowBodyHiddenCls;
        o[id + '-tdAttr'] = ' valign="top" rowspan="2" ';
        if (orig[id+'-tdAttr']) {
            o[id+'-tdAttr'] += orig[id+'-tdAttr'];
        }
        return o;
    },

    onGridAfterLayout: function() {
        var grid = this.getCmp(),
            view, viewEl;

        if (!grid.hasView) {
            this.getCmp().on('afterlayout', this.onGridAfterLayout, this, {single: true});
        } else {
            view = grid.down('gridview');
            viewEl = view.getEl();

            if (this.expandOnEnter) {
                this.keyNav = Ext.create('Ext.KeyNav', viewEl, {
                    'enter' : this.onEnter,
                    scope: this
                });
            }
            if (this.expandOnDblClick) {
                view.on('itemdblclick', this.onDblClick, this);
            }
            this.view = view;
        }
    },

    onEnter: function(e) {
        var view = this.view,
            ds   = view.store,
            sm   = view.getSelectionModel(),
            sels = sm.getSelection(),
            ln   = sels.length,
            i = 0,
            rowIdx;

        for (; i < ln; i++) {
            rowIdx = ds.indexOf(sels[i]);
            this.toggleRow(rowIdx);
        }
    },

    toggleRow: function(rowIdx) {
		var rowNode = this.getCmp().view.getNode(rowIdx);  ///BECKY
		var row = Ext.get(rowNode);
		var nextBd = Ext.get(row).down(this.rowBodyTrSelector);
		var record = this.getCmp().view.getRecord(rowNode);

/*        var rowNode = this.view.getNode(rowIdx),
            row = Ext.get(rowNode),
            nextBd = Ext.get(row).down(this.rowBodyTrSelector),
            record = this.view.getRecord(rowNode);*/

        if (row.hasCls(this.rowCollapsedCls)) {
            row.removeCls(this.rowCollapsedCls);
            nextBd.removeCls(this.rowBodyHiddenCls);
            this.recordsExpanded[record.internalId] = true;
            this.view.fireEvent('expandbody', rowNode, record, nextBd.dom);
        } else {
            row.addCls(this.rowCollapsedCls);
            nextBd.addCls(this.rowBodyHiddenCls);
            this.recordsExpanded[record.internalId] = false;
            this.view.fireEvent('collapsebody', rowNode, record, nextBd.dom);
        }
        this.view.up('gridpanel').invalidateScroller();
    },

    onDblClick: function(view, cell, rowIdx, cellIndex, e) {

        this.toggleRow(rowIdx);
    },

    getHeaderConfig: function() {
        var me                = this,
            toggleRow         = Ext.Function.bind(me.toggleRow, me),
            selectRowOnExpand = me.selectRowOnExpand;

        return {
            id: this.getHeaderId(),
            width: 24,
            sortable: false,
            fixed: true,
            draggable: false,
            hideable: false,
            menuDisabled: true,
            cls: Ext.baseCSSPrefix + 'grid-header-special',
            renderer: function(value, metadata) {
                metadata.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';

                return '<div class="' + Ext.baseCSSPrefix + 'grid-row-expander">&#160;</div>';
            },
            processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
                if (type == "mousedown" && e.getTarget('.x-grid-row-expander')) {
                    var row = e.getTarget('.x-grid-row');
                    toggleRow(row);
                    return selectRowOnExpand;
                }
            }
        };
    }
});
Ответить с цитированием
  #9 (permalink)  
Старый 17.10.2011, 16:24
Новичок на форуме
Отправить личное сообщение для MaryM Посмотреть профиль Найти все сообщения от MaryM
 
Регистрация: 13.10.2011
Сообщений: 8

Нашла такой вариант:
Если в файле rowexpander'а код вставки панели вставить после
this.recordsExpanded[record.internalId] = true;

то панелька вставляется при открытии полного просмотра (ну, и удалять ее после - вставить удаление после
this.recordsExpanded[record.internalId] = false;

Но это (очевидно) кривое решение. Если есть варианты - слушаю
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск