PDA

View Full Version : How to reference the same buttons from differents components



Ant0nin
10 Apr 2014, 1:19 AM
Hi Sencha Touch community ! I need to build a reusable wizard component. In fact, it's a classic window which in we have a panel with card layout. Each item of this panel is a "step card" (or step panel if you want). My problem is that buttons which are in the bottom of the panel are composed of classic next, previous and finish buttons, but also of all buttons contained in the "step cards extraButtons configs". However, I realized that's not the sames buttons in reality...Would there be possibility to have the same references, from the "panel with card layout" and from the "step card", to the corresponding buttons ? Or should you have any other approach to suggest ? Here are my related classes :Wizard.js --> The window
Ext.namespace('Ext.ux.wizard');Ext.ux.wizard.Wizard = Ext.extend(Ext.Window, { // required stepCards: null, title: "Assistant de configuration", modal: true, resizable: false, maximizable: false, closeAction: 'destroy', height: 700, layout: 'hbox', layoutConfig: { align: 'stretch', defaultMargins: { top: 5, bottom: 5, left: 5, right: 5 } }, // custom events listeners: { next: function(container, numStep, card) { this.onNext(container, numStep, card); }, previous: function(container, numStep, card) { this.onNext(container, numStep, card); }, finish: function(container) { this.onFinish(container); } }, // handlers (to override) onNext: Ext.emptyFn, onPrevious: Ext.emptyFn, onFinish: function() { this.close(); }, constructor: function(config) { var stepCards = config.stepCards ? config.stepCards : this.stepCards; var items = [ { flex: 1, xtype: 'stepcardscontainer', stepCards: stepCards // delegate } ]; var width = document.body.clientWidth - 300; config = Ext.applyIf({ width: width }, config); config = Ext.apply({ items: items }, config); // Superconstructeur Ext.ux.wizard.Wizard.superclass.constructor.call(this, config); }});Ext.reg('wizard', Ext.ux.wizard.Wizard);CardsContainer.js --> Contains the panel with card layout
Ext.ns('Ext.ux.wizard');// privateExt.ux.wizard.CardsContainer = Ext.extend(Ext.Container, { // private stepCards: null, hideTextInfo: false, // TODO layout: { type: 'vbox', align: 'stretch' }, defaults: { flex: 1 }, constructor: function(config) { // Controle if(!config.stepCards) throw new Error('[wizard.CardsContainer] Aucune stepCard détectée.'); var buttonWidth = 180; var displayFieldInfo = new Ext.form.DisplayField(); var boxLogo = new Ext.BoxComponent({ width: 72, autoEl: { tag: 'img', src: null } }); var containerInfo = { layout: { type: 'hbox', align: 'stretch', defaultMargins: { top: 0, bottom: 5, left: 0, right: 5 } }, border: false, height: 72, items: [ boxLogo, { layout: { type: 'hbox', align: 'middle' }, flex: 1, border: false, items: [ displayFieldInfo ] } ] }; var buttonPrevious = new Ext.Button({ text: "Revenir à l'étape précédente", width: buttonWidth, scale: 'medium', iconCls: 'precedent-medium', scope: this, hidden: true, handler: function() { this.previousEtape(); } }); var buttonNext = new Ext.Button({ text: "Passer à l'étape suivante", width: buttonWidth, scale: 'medium', iconCls: 'suivant-medium btnSuivant', iconAlign: 'right', scope: this, handler: function() { this.nextEtape(); } }); var buttonFinish = new Ext.Button({ text: "Terminer", width: buttonWidth, scale: 'medium', hidden: true, // TODO : iconCls iconAlign: 'right', scope: this, handler: function() { this.finish(); } }); // Ajout des extraButtons var allExtraButtons = []; Ext.each(config.stepCards, function(card, index) { Ext.each(card.extraButtons, function(btn) { btn.relatedCardIndex = index; // TODO : retirer ? allExtraButtons.push(btn); }); }); var buttons = [ '->', buttonPrevious, buttonNext, buttonFinish ]; buttons = allExtraButtons.concat(buttons); var cardEtapePanel = new Ext.Panel({ title: ' ', frame: true, flex: 1, layout: { type: 'card', layoutOnCardChange: true }, activeItem: 0, items : config.stepCards, defaults: { xtype: 'stepcard' }, buttonAlign: 'left', buttons: buttons }); var items = [ containerInfo, cardEtapePanel ]; config = Ext.apply({ items: items, logo: boxLogo, displayFieldInfo: displayFieldInfo, cardsPanel: cardEtapePanel, buttonPrevious: buttonPrevious, buttonNext: buttonNext, buttonFinish: buttonFinish }, config); Ext.ux.wizard.CardsContainer.superclass.constructor.call(this, config); }, initComponent: function() { var me = this; Ext.ux.wizard.CardsContainer.superclass.initComponent.call(me); var firstCard = me.cardsPanel.items.itemAt(0); firstCard.on('afterrender', me.refresh, me); me.on('activeitemchange', me.refresh, me); }, refresh: function(currentCard) { var me = this, textInfo = me.displayFieldInfo, logo = me.logo, panel = me.cardsPanel, items = panel.items, numStep = items.indexOf(currentCard)+1, nbStep = items.getCount(); textInfo.setValue(currentCard.description); logo.autoEl.src = currentCard.iconSrc; // TODO : Problème rafraichissement logo panel.setTitle("Etape"+' '+numStep+' / '+nbStep+' : '+currentCard.title); me.manageButtons(); }, manageButtons: function() { var me = this, panel = me.cardsPanel, layout = panel.getLayout(), activeCard = layout.activeItem, previousCard = activeCard.previousSibling(), nextCard = activeCard.nextSibling(); if(previousCard) me.buttonPrevious.show(); else me.buttonPrevious.hide(); if(nextCard) { me.buttonNext.show(); me.buttonFinish.hide(); } else { me.buttonNext.hide(); me.buttonFinish.show(); } me.manageExtraButtons(panel, activeCard); }, manageExtraButtons: function(panel, activeCard) { var buttons = panel.buttons; // On masque tous les extraButtons sauf ceux de la card active Ext.each(buttons, function(btn) { if(btn.getXType() !== 'button') return false; // On sort de la boucle lorsqu'on est sur '->' if(btn.relatedCardIndex === panel.items.indexOf(activeCard)) btn.show(); else btn.hide(); }); }, nextEtape: function() { var me = this, container = me.cardsPanel, layout = container.getLayout(), activeCard = layout.activeItem, nextCard = activeCard.nextSibling(), window = me.ownerCt; layout.setActiveItem(nextCard); var newCard = layout.activeItem, numStep = container.items.indexOf(newCard)+1; me.fireEvent('activeitemchange', newCard); window.fireEvent('next', me, numStep, newCard); // delegate }, previousEtape: function() { var me = this, container = me.cardsPanel, layout = container.getLayout(), activeCard = layout.activeItem, previousCard = activeCard.previousSibling(), window = me.ownerCt; layout.setActiveItem(previousCard); var newCard = layout.activeItem, numStep = container.items.indexOf(newCard)+1; me.fireEvent('activeitemchange', newCard); window.fireEvent('previous', me, numStep, newCard); // delegate }, finish: function() { var me = this, window = me.ownerCt; window.fireEvent('finish', me); // delegate }});Ext.reg('stepcardscontainer', Ext.ux.wizard.CardsContainer);StepCard.js --> One instance by step
Ext.ns('Ext.ux.wizard');Ext.ux.wizard.StepCard = Ext.extend(Ext.Panel, { // required title: null, description: null, extraButtons: null, iconSrc: null, header: false, layout: 'vbox', layoutConfig: { align: 'stretch' }, defaults: { flex: 1 }, constructor: function(config) { var extraButtons = config.extraButtons ? config.extraButtons : null; if(extraButtons) { Ext.each(extraButtons, function(btn) { btn = Ext.applyIf(btn, { xtype: 'button' }); }); } config = Ext.apply({ iconSrc: 'Images/Button-info-icon.png', extraButtons: extraButtons }, config); Ext.ux.wizard.StepCard.superclass.constructor.call(this, config); } });Ext.reg('stepcard', Ext.ux.wizard.StepCard);Example of using wizard (through custom class) :
Ext.namespace('Ext.ux.ldap');Ext.ux.ldap.WindowAdminGroupes = Ext.extend(Ext.ux.wizard.Wizard, { title: "Synchronisation des groupes avec l'annuaire LDAP", stepCards: [ { title: 'test1', description: 'blabla1', html: 'StepCard1' }, { title: 'test2', description: 'blabla2', html: 'StepCard2' }, { title: 'test3', description: 'blabla3', html: 'StepCard1', layout: 'fit', items: { xtype: 'button', text: 'test3' }, extraButtons: [ { text: 'action1' }, { text: 'action2' } ] } ], initComponent: function() { var me = this; Ext.ux.ldap.WindowAdminGroupes.superclass.initComponent.call(this); me.add(new Ext.GridJobsLDAP({ title: "Liste des travaux", flex: 0.8 })); }});Sorry for the formatting but I don't understand why my linebreaks are ignored. Thanks in advance for your help !

Ant0nin
10 Apr 2014, 7:04 AM
I finally found an other approach and it's working. However I have this error when I close and try to reopen a wizard instance (window) : "Uncaught NotFoundError: Failed to execute 'appendChild' on 'Node': The new child element is null. " (ext-all-debug.js, line 17072, onLayout method). Obviously my wizard stay closed.