BreadCrumbWizard.js (6592B)
1 /** 2 * BreadCrumbWizard for ExtJS 4.x, a container that acts as wizard. 3 * It also has breadcrumbs at the top to help navigating between views. 4 * 5 * The BreadCrumbWizard is based on the Extjs Container, so that it can be nested directly in the page or in a pop up window. 6 * The child views can still be declared in the items config, and internally it will use card layout to switch between them. 7 * The child views need one extra field 'breadCrumbTitle' to set the text be displayed in the bread crumb. 8 * 9 * The BreadCrumbWizard will fire three events {'validate','submit','close'} 10 * The 'validate' event will be fired when leaving from the current view, so validation code can be put in the listener. 11 * The 'submit' event will be fired when submit button in the last view is clicked, and the submit data is collected by calling getSubmitData on all child views. 12 * Feel free to add/override the getSubmitData method in each view component. 13 * 14 * @author: twinssbc 15 * @version 1.0.1 16 * @requires BreadCrumbWizard.css 17 * @xtype breadcrumbwizard 18 */ 19 Ext.define('Ext.ux.BreadCrumbWizard', { 20 extend: 'Ext.container.Container', 21 alias: ['widget.breadcrumbwizard'], 22 layout: { 23 type: 'vbox', 24 align: 'stretch' 25 }, 26 defaults: { 27 cls: 'x-wizard-component' 28 }, 29 initComponent: function () 30 { 31 var me = this, 32 breadCrumbComponents = [], 33 cardItems = [], 34 index, 35 childView; 36 37 me.currentIndex = 0; 38 for (index = 0; index < me.items.length; index += 1) { 39 childView = me.items[index]; 40 breadCrumbComponents.push({ 41 xtype: 'button', 42 cls: 'x-wizard-breadcrumb', 43 disabledCls: 'wizard-breadcrumb-disabled', 44 overCls: 'wizard-breadcrumb-over', 45 pressedCls: 'wizard-breadcrumb-pressed', 46 enableToggle: true, 47 toggleGroup: 'breadCrumbGroup', 48 allowDepress: false, 49 disabled: index !== 0, 50 pressed: index === 0, 51 index: index, 52 text: childView.breadCrumbTitle + " ยป ", 53 listeners: { 54 toggle: { 55 fn: function (button, pressed) 56 { 57 if (pressed) { 58 this.switchView(button.index); 59 } 60 }, 61 scope: me 62 } 63 } 64 }); 65 cardItems.push(childView); 66 } 67 68 me.breadCrumbContainer = Ext.create('widget.container', { 69 layout: 'hbox', 70 items: breadCrumbComponents 71 }); 72 me.cardContainer = Ext.create('widget.container', { 73 layout: 'card', 74 flex: 1, 75 items: cardItems 76 }); 77 me.items = [ 78 { 79 xtype: 'container', 80 layout: 'center', 81 style: 'background-color: white; padding: 5px;', 82 items: Ext.create('Ext.Img', { 83 height: 90, 84 width: 495, 85 src: 'images/partkeepr-setup.svg', 86 alt: 'PartKeepr' 87 }), 88 }, 89 me.breadCrumbContainer, 90 me.cardContainer, 91 { 92 xtype: 'container', 93 layout: { 94 type: 'hbox', 95 pack: 'end' 96 }, 97 defaults: { 98 xtype: 'button', 99 cls: 'x-wizard-navigation' 100 }, 101 items: [ 102 { 103 text: 'Previous', 104 itemId: 'previousButton', 105 handler: me.onPrevious, 106 disabled: true, 107 scope: me 108 }, 109 { 110 text: 'Next', 111 itemId: 'nextBtn', 112 handler: me.onNext, 113 scope: me 114 } 115 ] 116 } 117 ]; 118 119 me.callParent(); 120 }, 121 switchView: function (index) 122 { 123 var nextBtn = this.down('#nextBtn'), 124 previousButton = this.down('#previousButton'), 125 childViewCount = this.cardContainer.items.getCount(); 126 if (index < childViewCount) { 127 nextBtn.enable(); 128 129 this.cardContainer.getLayout().setActiveItem(index); 130 this.currentIndex = index; 131 132 if (index === 0) { 133 previousButton.disable(); 134 } else { 135 previousButton.enable(); 136 } 137 138 if (index === childViewCount - 1) { 139 nextBtn.setText('Submit'); 140 } else { 141 nextBtn.setText('Next'); 142 } 143 } else { 144 throw new Error('Invalid view index: ' + index); 145 } 146 }, 147 onPrevious: function () 148 { 149 var me = this, 150 childViewCount = this.cardContainer.items.getCount(), 151 currentIndex = me.currentIndex, 152 breadCrumbButton; 153 154 for (var i = currentIndex; i < childViewCount; i++) { 155 breadCrumbButton = me.breadCrumbContainer.items.getAt(i); 156 breadCrumbButton.disable(); 157 } 158 breadCrumbButton = me.breadCrumbContainer.items.getAt(currentIndex - 1); 159 breadCrumbButton.toggle(); 160 161 }, 162 onNext: function () 163 { 164 var me = this, 165 nextBreadCrumbButton, 166 currentIndex = me.currentIndex, 167 childViews = me.cardContainer.items, 168 currentView = childViews.getAt(currentIndex); 169 170 if (this.fireEvent('validate', me, currentView) !== false) { 171 if (currentIndex < childViews.getCount() - 1) { 172 nextBreadCrumbButton = me.breadCrumbContainer.items.getAt(currentIndex + 1); 173 nextBreadCrumbButton.enable(); 174 nextBreadCrumbButton.toggle(); 175 } else { 176 me.fireEvent('submit', me, me.getSubmitData()); 177 } 178 } 179 }, 180 onClose: function () 181 { 182 this.fireEvent('close', this); 183 }, 184 getSubmitData: function () 185 { 186 var submitData = {}; 187 this.cardContainer.items.each(function (childView) 188 { 189 if (childView.getSubmitData) { 190 Ext.merge(submitData, childView.getSubmitData()); 191 } 192 }); 193 return submitData; 194 } 195 });