Pavel Sidorov 19 февраля 2015 0 27
Доброго времени суток.

Есть такой виджет, мне нужно чтобы при выборе пункта из комбобокса, обновлялась таблица ниже в соответствии с выбранным id в комбо.


состоящий, собственно, из:
1. combo
Tests.combo.Test = function(config) {
    config = config || {};
    Ext.applyIf(config,{
        name: 'tests_id',
        hiddenName: 'tests_id',
        fieldLabel: _('tests_tests'),
        displayField: 'name',
        valueField: 'id',
        fields: ['id','name'],
        pageSize: 5,
        width: 400,
        editable: true,
        allowBlank: true,
        hideMode: 'offsets',
        anchor: '100%',
        url: Tests.config.connector_url,
        baseParams: {
            action: 'mgr/test/getlist',
        },
    });
    Tests.combo.Test.superclass.constructor.call(this,config);
};
Ext.extend(Tests.combo.Test,MODx.combo.ComboBox);
Ext.reg('tests-combo-test',Tests.combo.Test);


2. кнопка
Tests.window.btnCreateTest = function (config) {
    config = config || {};
    if (!config.id) {
        config.id = 'tests-test-window-btn';
    }
    Ext.applyIf(config, {
        title: _('tests_test_create'),
        width: 550,
        autoHeight: true,
        url: Tests.config.connector_url,
        action: 'mgr/test/create',
        fields: this.getFields(config),
        keys: [{
            key: Ext.EventObject.ENTER, shift: true, fn: function () {
                this.submit()
            }, scope: this
        }]
    });
    Tests.window.btnCreateTest.superclass.constructor.call(this, config);
};

Ext.extend(Tests.window.btnCreateTest, MODx.Window, {

    getFields: function (config) {
        return [{
            xtype: 'textfield',
            fieldLabel: _('tests_test_name'),
            name: 'name',
            id: config.id + '-name',
            anchor: '99%',
            allowBlank: false,
        }];
    }
});
Ext.reg('tests-test-window-btn', Tests.window.btnCreateTest);

3. таблица: в топ баре таблицы и находится кнопка с выпадающим списком
[{
            xtype: 'tests-combo-test',
            name: 'tests_id',
            hiddenName: 'tests_id',
             listeners: {
                select: {fn: this.selectedTest, scope: this}
            }
        }, {
            xtype: 'button',
            text: 'Create test',
            cls: 'buttonOnCreate',
            scale: 'small',
            handler: function () {
                var w = MODx.load({
                    xtype: 'tests-test-window-btn',
                    id: Ext.id(),
                    listeners: {
                        success: {
                            fn: function () {
                                w.submit();
                            }, scope: this
                        }
                    }
                });
                w.reset();
                w.setValues();
                w.show();
            }


при выборе пункта из комбо, запускатеся вот это:
selectedTest: function (combo) {

        MODx.Ajax.request({
            url: Tests.config.connector_url,
            params: {
                action: 'mgr/question/getlist',
                tests_id: combo.value<s></s>
            },
            listeners: {
                success: {
                    fn: function () {
                        this.refresh();
                        console.log();
                    }, scope: this
                }
            }
        });
    },

которое нифига не обновляет таблицу в соотвестии с запросом, а хотелось бы.
И как вообще получить value комбо не используя Ext.getCmp другим к примеру элементам, кнопкам и прочее. Ведь там есть кнопка создать вопрос, которая при создании должна добавлять вопрос с тем id что указан в combo.
27 комментариев
Fi1osof1
Fi1osof 19 февраля 2015г в 13:52 #
Павел, во-первых, хорошо бы cut прописывать, чтобы статья в списке не была простыней.
Во-вторых, в следующий раз не удаляйте содержимое статьи, даже если вопрос уже решенный.
P
Pavel Sidorov 19 февраля 2015г в 13:53 #
Каюсь, прописал =)
По второму учту, и прошу извинить.
Fi1osof1
Fi1osof 19 февраля 2015г в 14:10 #
Неправильно при выборе значения в комбобоксе слать запрос от его имени и что-то потом с ответом делать. Надо данные его подставлять в фильтры стора и вызывать обновление его данных. Смотрите здесь пример.
P
Pavel Sidorov 19 февраля 2015г в 14:39 #
Мде, а я вот всю голову поломал от не знания. Спасибо Вам Николай ;)
Fi1osof1
Fi1osof 19 февраля 2015г в 17:38 #
Пожалуйста!
P
Pavel Sidorov 19 февраля 2015г в 15:12 #
А как вообще обращаться к другим объектам? К примеру как мне произвести какие нибудь манипуляции с combo при нажатии на кнопку?
Fi1osof1
Fi1osof 19 февраля 2015г в 17:41 #
Обратите внимание на эту строчку в инициализации компонента. scope: this.
scope — это то, что будет внутри ивентов данного компонента. В нашем случае инициализация происходит внутри грида, и передавая в scope this, мы передаем ссылку на текущий объект. В результате внутри функций, навешанных на различные события, this — это будет сам грид. Ну а далее и до стора рукой подать — this.store.
Смотрите внимательней это.
P
Pavel Sidorov 20 февраля 2015г в 10:06 #
Ну а если есть такой элемент:
id: 'testsComboBoxTest',
            xtype: 'tests-combo-test',
            name: 'tests_id',
            hiddenName: 'tests_id',
           

Мне его нужно обновить. Я сейчас делаю так:
var testsComboBoxTest = Ext.getCmp('testsComboBoxTest');
                                testsComboBoxTest.store.load();
                                

Но честно говоря мне не совсем так нравится, тем более объекты в пределах 1 грида.
Мне нужно в combobox добавить scope: this для обращения к нему через store?
Я все равно не пойму как обратится к какому то своему элементу через store…
Пытался через браузер смотреть this.store но ничего не нашел =(

Я уже использую такое (из ваших исходников): но там ведь добавление параметра, а не обращение к элементу.(не считая getbottomtoolbar)
var store = this.getStore();
store.setBaseParam('tests_id', combo.getValue());
this.getBottomToolbar().changePage(0);
Fi1osof1
Fi1osof 20 февраля 2015г в 10:19 #
Объявляйте компонент не лениво, а полностью через new, как здесь, к примеру.

И еще краткий пример:
this.field = new new MODx.combo.Context({
..........,
,listeners:{
select: {
fn: function(combo){
var context_key = combo.getValue();
var store = this.getStore();
var field = this.field;
}
,scope: this
}
}
});
P
Pavel Sidorov 20 февраля 2015г в 10:29 #
Пользовался руководствами от сюда: bezumkin.ru/training/course1/2202/

Sendex.combo.User = function(config) {
	config = config || {};
	Ext.applyIf(config,{
		name: 'user_id'
		,fieldLabel: _('sendex_subscriber')
		,hiddenName: config.name || 'user_id'
		,displayField: 'username'
		,valueField: 'id'
		,anchor: '99%'
		,fields: ['username','id','fullname']
		// Количество результатов на странице
		,pageSize: 20
		// Используем родной процессор MODX
		,url: MODx.config.connectors_url + 'security/user.php'
		// Комбо можно редактировать, то есть - искать юзеров
		,editable: true
		// Можно оставлять пустым
		,allowBlank: true
		// Текст по умолчанию
		,emptyText: _('sendex_select_user')
		// Данные для отправки процессору
		,baseParams: {
			action: 'getlist'
			,combo: 1
		}
		// Шаблон оформления, похоже на Smarty
		,tpl: new Ext.XTemplate(''
			+'<tpl for="."><div class="sendex-list-item">'
			+'<span><small>({id})</small> <b>{username}</b> ({fullname})</span>'
			+'</div></tpl>',{
			compiled: true
		})
		// Какой элемент является селекторо. То есть, выбор будет при клике на этот элемент
		,itemSelector: 'div.sendex-list-item'
	});
	Sendex.combo.User.superclass.constructor.call(this,config);
};
Ext.extend(Sendex.combo.User,MODx.combo.ComboBox);
Ext.reg('sendex-combo-user',Sendex.combo.User);


,tbar: [{
	xtype: 'sendex-combo-user'
	// Имя поля
	,name: 'user_id'
	,hiddenName: 'user_id'
	// Ширина - 50%
	,width: '50%'
	,listeners: {
		// При выборе позиции нужно запустить метод addSubscriber таблицы
		select: {fn: this.addSubscriber, scope: this}
	}
]}


вроде бы практически аналогично и у меня. Разьве так не правильно? Потом добавлять xtype ??
P
Pavel Sidorov 20 февраля 2015г в 10:32 #
Но если тут к примеру есть:
select: {fn: this.addSubscriber, scope: this}


Как мне потом к этому объекту обратится?
proxyfabio1
proxyfabio 20 февраля 2015г в 10:36 #
В данном случае функция `this.addSubscriber` будет вызвана в контексте `this`
P
Pavel Sidorov 20 февраля 2015г в 10:38 #
Я имел ввиду scope:this там есть, то как мне обратится к
xtype: 'sendex-combo-user' в tbar?
proxyfabio1
proxyfabio 20 февраля 2015г в 10:45 #
Если тебе нужен `combo`, то `scope` можешь не передавать. Твоя функция будет вызвана в контексте `combo`
P
Pavel Sidorov 20 февраля 2015г в 10:51 #
Не понял, еще раз на пальцах:
есть вот это:
xtype: 'sendex-combo-user'
        // Имя поля
        ,name: 'user_id'
        ,hiddenName: 'user_id'
        // Ширина - 50%
        ,width: '50%'
        ,listeners: {
                // При выборе позиции нужно запустить метод addSubscriber таблицы
                select: {fn: this.addSubscriber, scope: this}
        }

как мне его к примеру обновить нажав на кнопку, находящуюся в том же gride?

Сейчас добавляю id, и получаю через getcmp(), но есть ли альтернативные варианты получения данного объекта? все таки ведь на одном гриде…
proxyfabio1
proxyfabio 20 февраля 2015г в 11:07 #
Обновить что?

При выборе значения в `combo` у тебя и так значение поменяется. Также мне не понятно зачем слать запрос из `combo`, если ты делаешь кнопку…

Отработай событие `click` на кнопке, сделав `fireEvent` со своим кастомным событием, при этом разрешив для компонента всплывание события.

Это событие сможет отловить твой grid. В этом месте ты сможешь получить значение `combo` (у grid будет метод `findById`. Через него ты сможешь достучаться до своего дочернего `combo`). Если значение выбрано, то уже здесь имеет смысл отправить запрос на добавление записи и на success обновить `grid`.

P.S.: если тебе нужно получить родителя в дочернем компоненте, то в целом у каждого элемента есть свойство `ownerCt`. Там сидит родитель, но этим в целом лучше не злоупотреблять имо
P
Pavel Sidorov 20 февраля 2015г в 11:14 #
Да я сейчас так и делаю на кнопке
success: {
                            fn: function () {
                                var ccc=this.combo;
                                var testsComboBoxTest = Ext.getCmp('testsComboBoxTest');
                                testsComboBoxTest.store.load();
                                this.refresh();
                            }, scope: this
                        }


getCmp или findById — получение объекта по его id
Вот я и спрашиваю как мне получить combo не через его ID owner, child и прочее, т.к. следуя статье
habrahabr.ru/post/132923/
Избегайте использования owneCt свойства
Избегайте использования Ext.getCmp
Не делайте обрамляющие панели.
proxyfabio1
proxyfabio 20 февраля 2015г в 11:23 #
Так возьми и погляди ману от сенчи, я тебе привел только один метод, к примеру. Там же не только по айдишнику можно поискать… Есть целый ряд способов поиска, не говоря уже о том, что можно в контексте грида типа такого сделать: `this.toolbars[0].items`

На счет обрамляющих панелей я не согласен. Если у меня мой грид выполняет какие-то атомарные функции, то я прочим его не разбавляю. Не стоит доводит до абсолюта какое-то правило, если в данном случае тебе его нарушение даст преимущество.
proxyfabio1
proxyfabio 20 февраля 2015г в 11:24 #
proxyfabio1
proxyfabio 20 февраля 2015г в 12:40 #
А вообще накидал бы свой пример в jsfiddle или senchafiddle. Я бы поглядел что там у тебя не выходит.
proxyfabio1
proxyfabio 20 февраля 2015г в 13:39 #
P
Pavel Sidorov 20 февраля 2015г в 15:04 #
Охохох, спасибо Сергей огромное. Я ваш должник ;)
Fi1osof1
Fi1osof 20 февраля 2015г в 18:57 #
Я ваш должник ;)
Внизу есть форма для донейтов. Всегда можно должок вернуть :)
P
Pavel Sidorov 20 февраля 2015г в 15:09 #
Но, наверное, в будущем буду элементы создавать как предлагал Николай
Вообщем еще раз спасибо вам обоим =)
proxyfabio1
proxyfabio 20 февраля 2015г в 10:51 #
Я бы вот как решил твою задачу:
1. Обернул все компоненты в `FormPanel`, к примеру
2. По клику на кнопку выбрасывал в родит. панель событие через `bubbleEvent`
3. На это событие в панели делал проверку на наличие значения в `combo`
4. Если не пусто, то отправлял запрос на добавление на бэкенд и если все успешно, то обновлял `grid`.
P
Pavel Sidorov 20 февраля 2015г в 10:57 #
Не пойму они ведь по сути обернуты и так в одном grid.
Как мне по кнопке опять же получить объект на текущем grid?

Прочтите пожалуйста комментарий выше, у меня такое ощущение что мы о разном говорим.
Fi1osof1
Fi1osof 20 февраля 2015г в 19:08 #
Вы очень много задаете вопросов, и мало смотрите на то, что вам уже сказано. Я решение описал еще здесь. Смотрите пример jsfiddle.net/1bbeks4n/ и больше никаких вопросов. Разбирайтесь сами. Мы вашими руками ваш код писать не будем.
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.