1. #151
    Ext User
    Join Date
    Feb 2009
    Posts
    5
    Vote Rating
    0
    roque is on a distinguished road

      0  

    Default onShow of the first card is not triggered

    onShow of the first card is not triggered


    I solved this and other issues moving all the handlers declaration to the initComponent. I dont know why the handler declaration is in the initEvents that's called too late.
    I also think the Card specific handler declararion must reside in the Card instead of the wizard.

    Card.js
    initComponent : function() {
    .....
    Ext.ux.Wiz.Card.superclass.initComponent.call(this);

    this.on('beforehide', this.bubbleBeforeHideEvent, this);
    this.on('beforecardhide', this.isValid, this);
    this.on('show', this.onCardShow, this);
    this.on('hide', this.onCardHide, this);
    }

    Wizard.js
    initComponent : function() {
    .....
    Ext.ux.Wiz.superclass.initComponent.call(this);

    var cards = this.cards;
    for (var i = 0, len = cards.length; i < len; i++) {
    cards[i].on('show', this.onCardShow, this);
    cards[i].on('hide', this.onCardHide, this);
    cards[i].on('clientvalidation', this.onClientValidation, this);
    }
    }

  2. #152
    Ext User
    Join Date
    Feb 2009
    Posts
    5
    Vote Rating
    0
    roque is on a distinguished road

      0  

    Default Lazy loading in Ext.ux.Wiz

    Lazy loading in Ext.ux.Wiz


    If we try to lazy loading the Card in the wizard, it wont work because of the code in Wizard.js

    var cards = this.cards;
    for (var i = 0, len = cards.length; i < len; i++) {
    cards[i].on('show', this.onCardShow, this);
    cards[i].on('hide', this.onCardHide, this);
    cards[i].on('clientvalidation', this.onClientValidation, this);
    }
    }

    and the reason is because cards[i] is undefined at this time, as the cards are not created because of the lazy loading. To solve this problem instead of attaching a listener for the card show and hide events in the wizard, I created two custom events in the Card (onCardShow and onCardHide) that I will bubble it to the container (the wizard).

    Then the fix looks like:

    Card.js

    initComponent : function() {
    .....
    Ext.ux.Wiz.Card.superclass.initComponent.call(this);

    this.on('beforehide', this.bubbleBeforeHideEvent, this);
    this.on('beforecardhide', this.isValid, this);
    this.on('show', this.onCardShow, this);
    this.on('hide', this.onCardHide, this);
    this.enableBubble('oncardshow', 'oncardhide', 'clientvalidation');
    }


    onCardHide: function() {
    if (this.monitorValid) {
    this.stopMonitoring();
    }
    this.fireEvent('oncardhide', this);
    }

    onCardShow: function() {
    if (this.monitorValid) {
    this.startMonitoring();
    }
    this.fireEvent('oncardshow', this);

    }

    });
    Ext.reg('xcard', Ext.ux.Wiz.Card);


    Wizard.js

    initComponent : function() {
    .....
    Ext.ux.Wiz.superclass.initComponent.call(this);
    this.on({
    'oncardshow': this.onCardShow,
    'oncardhide': this.onCardHide,
    'clientvalidation': this.onClientValidation,

    'beforeclose': this.onBeforeClose,
    scope: this
    });


    onCardHide : function(card)
    {
    if (this.cardPanel.layout.activeItem.id === card.id) {
    this.nextButton.setDisabled(true);
    }
    },


    onCardShow : function(card)
    {

    var parent = card.ownerCt;

    var items = parent.items;

    for (var i = 0, len = items.length; i < len; i++) {
    if (items.get(i).id == card.id) {
    break;
    }
    }

    this.currentCard = i;
    this.headPanel.updateStep(i, card.title);

    if (i == len-1) {
    this.nextButton.setText(this.finishButtonText);
    } else {
    this.nextButton.setText(this.nextButtonText);
    }

    if (card.isValid()) {
    this.nextButton.setDisabled(false);
    }

    if (i == 0) {
    this.previousButton.setDisabled(true);
    } else {
    this.previousButton.setDisabled(false);
    }

    }


    Example:

    Ext.onReady(function(){

    Ext.QuickTips.init();

    var wizard = new Ext.ux.Wiz({

    title : 'A simple example for a wizard',

    headerConfig : {
    title : 'Simple Wizard Example'
    },

    cardPanelConfig : {
    defaults : {
    baseCls : 'x-small-editor',
    bodyStyle : 'padding:40px 15px 5px 120px;background-color:#F6F6F6;',
    border : false
    }
    },

    cards : [{
    xtype: 'xcard',
    title: 'Your email-address',
    monitorValid : true,
    defaults:{
    labelStyle : 'font-size:11px'
    },
    items : [{
    border : false,
    bodyStyle : 'background:none;padding-bottom:30px;',
    html : ' Please enter your email-address.'
    }, {
    xtype: 'textfield',
    name : 'email',
    fieldLabel : 'Email-Address',
    allowBlank : false,
    vtype : 'email'
    }]
    }, {
    xtype: 'xcard',
    title : 'Welcome',
    items : [{
    border : false,
    bodyStyle : 'background:none;',
    html : 'Welcome to the example for <strong>Ext.ux.Wiz</string>, '+
    'a Ext JS user extension for creating wizards.<br/><br/>'+
    'Please click the "next"-button and fill out all form values.'
    }]
    }, {
    xtype: 'xcard',
    title: 'Your name',
    monitorValid : true,
    defaults: {
    labelStyle : 'font-size:11px'
    },
    items : [{
    border : false,
    bodyStyle : 'background:none;padding-bottom:30px;',
    html : 'Please enter your first- and your lastname. Only letters, underscores and hyphens are allowed.'
    }, {
    xtype: 'textfield',
    name : 'firstname',
    fieldLabel : 'Firstname',
    allowBlank : false,
    validator : function(v){
    var t = /^[a-zA-Z_\- ]+$/;
    return t.test(v);
    }
    }]
    }]
    });

    // show the wizard
    wizard.show();
    });

  3. #153
    Sencha User charleshimmer's Avatar
    Join Date
    Jul 2008
    Location
    Austin, TX
    Posts
    329
    Vote Rating
    0
    charleshimmer is on a distinguished road

      0  

    Default


    Sweet. I will try this on my implementation of the wizard (been ported to a panel) and report back.

    Thanks for posting this.
    Last edited by charleshimmer; 29 Sep 2009 at 7:45 AM. Reason: typo, not window, panel

  4. #154
    Sencha User charleshimmer's Avatar
    Join Date
    Jul 2008
    Location
    Austin, TX
    Posts
    329
    Vote Rating
    0
    charleshimmer is on a distinguished road

      0  

    Default


    I tried moving those to the initComponent and it didn't change the behavoir. The only thing that seems to work is adding this to the css

    Code:
    .ext-safari .x-form-field-wrap .x-form-trigger{
        	right:inherit;
    	}

  5. #155
    Sencha - Community Support Team mschwartz's Avatar
    Join Date
    Nov 2008
    Location
    San Diego, Peoples' Republic of California
    Posts
    2,053
    Vote Rating
    17
    mschwartz will become famous soon enough mschwartz will become famous soon enough

      0  

    Default


    Where's that scriptlet when you need it?

  6. #156
    Sencha User charleshimmer's Avatar
    Join Date
    Jul 2008
    Location
    Austin, TX
    Posts
    329
    Vote Rating
    0
    charleshimmer is on a distinguished road

      0  

    Default


    scriptlet? What's that?

  7. #157
    Sencha - Community Support Team mschwartz's Avatar
    Join Date
    Nov 2008
    Location
    San Diego, Peoples' Republic of California
    Posts
    2,053
    Vote Rating
    17
    mschwartz will become famous soon enough mschwartz will become famous soon enough

      0  

    Default


    Quote Originally Posted by charleshimmer View Post
    scriptlet? What's that?
    See post #152 in this thread, and also see this thread:

    http://www.extjs.com/forum/showthread.php?t=64377

  8. #158
    Ext JS Premium Member
    Join Date
    Feb 2009
    Posts
    422
    Vote Rating
    1
    Jangla is on a distinguished road

      0  

    Default Quick question...

    Quick question...


    ...is it possible to force this wizard into a tab on a tab panel? If so, how?

  9. #159
    Sencha User charleshimmer's Avatar
    Join Date
    Jul 2008
    Location
    Austin, TX
    Posts
    329
    Vote Rating
    0
    charleshimmer is on a distinguished road

      0  

    Default


    That is how I am using it.

    Here is how I'm doing it.

    Normally there is 3 files, wizard.js, card.js, and the cardlayout extension file. Since the files have to be included in the right order I just put them into one file called WizardAll.js.

    Here is my WizardAll.js which turns the wizard into a panel (which can be a tab panel) instead of a window.
    Code:
    Ext.namespace('Ext.ux');
    
    /**
     * Licensed under GNU LESSER GENERAL PUBLIC LICENSE Version 3
     *
     * @author Thorsten Suckow-Homberg <ts@siteartwork.de>
     * @url http://www.siteartwork.de/wizardcomponent
     */
    
    /**
     * @class Ext.ux.Wiz
     * @extends Ext.Window
     *
     * A specific {@link Ext.Window} that models a wizard component.
     * A wizard is basically a dialog that guides a user through various steps
     * where he has to fill out form-data.
     * A {@link Ext.ux.Wiz}-component consists typically of a {@link Ext.ux.Wiz.Header}
     * and window-buttons ({@link Ext.Button}) which are linked to the {@link Ext.ux.Wiz.Card}s
     * which themself represent the forms the user has to fill out.
     *
     * In order to switch between the cards in the wizard, you need the {@link Ext.ux.layout.CardLayout},
     * which will check if an active-item can be hidden, before the requested new item will be set to
     * 'active', i.e. shown. This is needed since the wizard may not allow a card to be hidden, if
     * the input entered by the user was not valid. You can get this custom layout at
     * {@link http://www.siteartwork.de/cardlayout}.
     *
     * Note:
     * When data has been collected and teh "onFinish" listener triggers an AJAX-request,
     * you should call the "switchDialogState" method so that the the dialog shows a loadmask.
     * Once the requests finishes, call "switchDialogState" again, specially before any call
     * to the "close" method of this component, otherwise the "closable" property of this
     * instance might prevent a "close" operation for this dialog.
     *
     *
     * @constructor
     * @param {Object} config The config object
     */
    Ext.ux.Wiz = Ext.extend(Ext.Panel, {
    
        /**
         * @cfg {Object} An object containing the messages for the {@link Ext.LoadMask}
         * covering the card-panel on request, whereas the property identifies the
         * msg-text to show, and the value is the message text itself. Defaults to
         <pre><code>
    {
        default : 'Saving...'
    }
         </code></pre>
         *
         * Depending on the contexts the loadMask has to be shown in (using the method
         * showLoadMask of this class), the object can be configure to hold
         * various messages.
    <pre><code>
    this.loadMaskConfig = {
        default    : 'Saving...',
        validating : 'Please wait, validating input...',
    };
    // loadMask will be shown, displaying the message 'Please wait, validating input...'
    this.showLoadMask(true, 'validating');
         </code></pre>
         */
        loadMaskConfig: {
            'default': 'Saving...'
        },
    
        /**
         * @cfg {Number} height The height of the dialog. Defaults to "400".
         */
        height: 400,
    
        /**
         * @cfg {Number} width The width of the dialog. Defaults to "540".
         */
        width: 540,
    
        /**
         * @cfg {Boolean} closable Wether the dialog is closable. Defaults to "true".
         * This property will be changed by the "switchDialogState"-method, which will
         * enable/disable controls based on the passed argument. Thus, this config property
         * serves two purposes: Tell the init config to render a "close"-tool, and create a
         * "beforeclose"-listener which will either return true or false, indicating if the
         * dialog may be closed.
         */
        closable: false,
    
        /**
         * @cfg {Boolean} resizable Wether the dialog is resizable. Defaults to "false".
         */
        resizable: false,
    
        /**
         * @cfg {Boolean} resizable Wether the dialog is modal. Defaults to "true".
         */
        modal: false,
    
        /**
         * @cfg {Array} cards A numeric array with the configured {@link Ext.ux.Wiz.Card}s.
         * The index of the cards in the array represent the order in which they get displayed
         * in the wizard (i.e. card at index 0 gets displayed in the first step, card at index 1 gets
         * displayed in the second step and so on).
         */
        cards: null,
    
        /**
         * @cfg {String} previousButtonText The text to render the previous-button with.
         * Defaults to "&lt; Back" (< Back)
         */
        previousButtonText: '&lt; Previous',
    
        /**
         * @cfg {String} nextButtonText The text to render the next-button with.
         * Defaults to "Next &gt;" (Next >)
         */
        nextButtonText: 'Next &gt;',
    
        /**
         * @cfg {String} cancelButtonText The text to render the cancel-button with.
         * Defaults to "Cancel"
         */
        cancelButtonText: 'Cancel',
    
        /**
         * @cfg {String} finishButtonText The text to render the next-button with when the last
         * step of the wizard is reached. Defaults to "Finish"
         */
        finishButtonText: 'Finish',
    
        /**
         * @cfg {Object} headerConfig A config-object to use with {@link Ext.ux.Wiz.Header}.
         * If not present, it defaults to an empty object.
         */
        headerConfig: {},
    
        /**
         * @cfg {Object} cardPanelConfig A config-object to use with {@link Ext.Panel}, which
         * represents the card-panel in this dialog.
         * If not present, it defaults to an empty object
         */
        cardPanelConfig: {},
    
        /**
         * @param {Ext.Button} The window-button for paging to the previous card.
         * @private
         */
        previousButton: null,
    
        /**
         * @param {Ext.Button} The window-button for paging to the next card. When the
         * last card is reached, the event fired by and the text rendered to this button
         * will change.
         * @private
         */
        nextButton: null,
    
        /**
         * @param {Ext.Button} The window-button for canceling the wizard. The event
         * fired by this button will usually close the dialog.
         * @private
         */
        cancelButton: null,
    
        /**
         * @param {Ex.Panel} The card-panel that holds the various wizard cards
         * ({@link Ext.ux.Wiz.Card}). The card-panel itself uses the custom
         * {@link Ext.ux.layout.CardLayout}, which needs to be accessible by this class.
         * You can get it at {@link http://www.siteartwork.de/cardlayout}.
         * @private
         */
        cardPanel: null,
    
        /**
         * @param {Number} currentCard The current {@link Ext.ux.Wiz.Card} displayed.
         * Defaults to -1.
         * @private
         */
        currentCard: -1,
    
        /**
         * @param {Ext.ux.Wiz.Header} The header-panel of the wizard.
         * @private
         */
        headPanel: null,
    
        /**
         * @param {Number} cardCount Helper for storing the number of cards used
         * by this wizard. Defaults to 0 (inherits "cards.length" later on).
         * @private
         */
        cardCount: 0,
    
        /**
         * Inits this component with the specified config-properties and automatically
         * creates its components.
         */
        initComponent: function () {
            this.initButtons();
            this.initPanels();
    
            var title = this.title || this.headerConfig.title;
            title = title || "";
    
            Ext.apply(this, {
                title: title,
                layout: 'border',
                cardCount: this.cards.length,
                buttons: [
                this.previousButton, this.nextButton, this.cancelButton],
                items: [
                this.headPanel, this.cardPanel]
            });
    
            this.addEvents(
            /**
                 * @event cancel
                 * Fires after the cancel-button has been clicked.
                 * @param {Ext.ux.Wiz} this
                 */
            'cancel',
            /**
                 * @event finish
                 * Fires after the last card was reached in the wizard and the
                 * next/finish-button has been clicked.
                 * @param {Ext.ux.Wiz} this
                 * @param {Object} data The collected data of the cards, whereas
                 * the index is the id of the card and the specific values
                 * are objects with key/value pairs in the form formElementName : value
                 */
            'finish');
    
            Ext.ux.Wiz.superclass.initComponent.call(this);
        },
    
        // -------- helper
        /**
         * Returns the form-data of all cards in this wizard. The first index is the
         * id of the card in this wizard,
         * and the values are objects containing key/value pairs in the form of
         * fieldName : fieldValue.
         *
         * @return {Array}
         */
        getWizardData: function () {
            var formValues = {};
            var cards = this.cards;
            for (var i = 0, len = cards.length; i < len; i++) {
                if (cards[i].form) {
                    Ext.apply(formValues, cards[i].form.getValues(false));
                }
            }
    
            return formValues;
        },
    
        /**
         * Resets all the form fields throughout the wizard and sets the resets the 
         * wizards card back to the first card.
         */
        resetWizard: function () {
            /* reset data if rendered */
            if (this.rendered) {
                var cards = this.cards;
                for (var i = 0, len = cards.length; i < len; i++) {
                    if (cards[i].form) {
                        cards[i].form.reset();
                    }
                }
    
                /* select first card */
                this.cardPanel.getLayout().setActiveItem(0);
            }
        },
    
        /**
         * Switches the state of this wizard between disabled/enabled.
         * A disabled dialog will have a {@link Ext.LoadMask} covering the card-panel
         * to prevent user input, and the buttons will be rendered disabled/enabled.
         * If the dialog is closable, the close-tool will be masked, too, and the dialog will not
         * be closable by clicking the "close" tool.
         *
         * @param {Boolean} enabled "false" to prevent user input and mask the elements,
         * otherwise true.
         * @param {String} type The type of msg for the {@Ext.LoadMask} covering
         * the cardPanel, as defined in the cfg property "loadMaskConfig"
         */
        switchDialogState: function (enabled, type) {
            this.showLoadMask(!enabled, type);
    
            this.previousButton.setDisabled(!enabled);
            this.nextButton.setDisabled(!enabled);
            this.cancelButton.setDisabled(true);
    
            var ct = this.tools['close'];
    
            if (ct) {
                switch (enabled) {
                case true:
                    this.tools['close'].unmask();
                    break;
    
                default:
                    this.tools['close'].mask();
                    break;
                }
            }
    
            this.closable = enabled;
        },
    
        /**
         * Shows the load mask for this wizard. By default, the cardPanel's body
         * will be masked.
         *
         * @param {Boolean} show true to show the load mask, otherwise false.
         * @param {String} type The type of message for the {@Ext.LoadMask} covering
         * the cardPanel, as defined in the cfg property "loadMaskConfig"
         */
        showLoadMask: function (show, type) {
            if (!type) {
                type = this.loadMaskConfig[type];
            }
    
            if (show) {
                if (this.loadMask == null) {
                    this.loadMask = new Ext.LoadMask(this.body);
                }
                this.loadMask.msg = type;
                this.loadMask.show();
            } else {
                if (this.loadMask) {
                    this.loadMask.hide();
                }
            }
        },
    
        /**
         * Inits the listener for the various {@link Ext.ux.Wiz.Card}s used
         * by this component.
         */
        initEvents: function () {
            Ext.ux.Wiz.superclass.initEvents.call(this);
    
            this.on('beforeclose', this.onBeforeClose, this);
    
            var cards = this.cards;
    
            for (var i = 0, len = cards.length; i < len; i++) {
                cards[i].on('show', this.onCardShow, this);
                cards[i].on('hide', this.onCardHide, this);
                cards[i].on('clientvalidation', this.onClientValidation, this);
            }
        },
    
        /**
         * Creates the head- and the card-panel.
         * Be sure to have the custom {@link Ext.ux.layout.CardLayout} available
         * in order to make the card-panel work as expected by this component
         * ({@link http://www.siteartwork.de/cardlayout}).
         */
        initPanels: function () {
            var cards = this.cards;
            var cardPanelConfig = this.cardPanelConfig;
    
            Ext.apply(this.headerConfig, {
                steps: cards.length
            });
    
            this.headPanel = new Ext.ux.Wiz.Header(this.headerConfig);
    
            Ext.apply(cardPanelConfig, {
                layout: new Ext.ux.layout.CardLayout(),
                items: cards
            });
    
            Ext.applyIf(cardPanelConfig, {
                region: 'center',
                border: false,
                activeItem: 0
            });
    
            this.cardPanel = new Ext.Panel(cardPanelConfig);
        },
    
        /**
         * Creates the instances for the the window buttons.
         */
        initButtons: function () {
            this.previousButton = new Ext.Button({
                text: this.previousButtonText,
                disabled: true,
                minWidth: 75,
                handler: this.onPreviousClick,
                scope: this
            });
    
            this.nextButton = new Ext.Button({
                text: this.nextButtonText,
                minWidth: 75,
                handler: this.onNextClick,
                scope: this
            });
    
            this.cancelButton = new Ext.Button({
                text: this.cancelButtonText,
                handler: this.onCancelClick,
                scope: this,
                minWidth: 75
            });
        },
    
        // -------- listeners
        /**
         * Listener for the beforeclose event.
         * This listener will return true or false based on the "closable"
         * property by this component. This property will be changed by the "switchDialogState"
         * method, indicating if there is currently any process running that should prevent
         * this dialog from being closed.
         *
         * @param {Ext.Panel} panel The panel being closed
         *
         * @return {Boolean}
         */
        onBeforeClose: function (panel) {
            return this.closable;
        },
    
        /**
         * By default, the card firing this event monitors user input in a frequent
         * interval and fires the 'clientvalidation'-event along with it. This listener
         * will enable/disable the next/finish-button in accordance with it, based upon
         * the parameter isValid. isValid" will be set by the form validation and depends
         * on the validators you are using for the different input-elemnts in your form.
         * If the card does not contain any forms, this listener will never be called by the
         * card itself.
         *
         * @param {Ext.ux.Wiz.Card} The card that triggered the event.
         * @param {Boolean} isValid "true", if the user input was valid, otherwise
         * "false"
         */
        onClientValidation: function (card, isValid) {
            if (!isValid) {
                this.nextButton.setDisabled(true);
            } else {
                this.nextButton.setDisabled(false);
            }
        },
    
        /**
         * This will render the "next" button as disabled since the bindHandler's delay
         * of the next card to show might be lagging on slower systems
         *
         */
        onCardHide: function (card) {
            if (this.cardPanel.layout.activeItem.id === card.id) {
                this.nextButton.setDisabled(true);
            }
        },
    
        /**
         * Listener for the "show" event of the card that gets shown in the card-panel.
         * Renders the next/previous buttons based on the position of the card in the wizard
         * and updates the head-panel accordingly.
         *
         * @param {Ext.ux.Wiz.Card} The card being shown.
         */
        onCardShow: function (card) {
            var parent = card.ownerCt;
    
            var items = parent.items;
    
            for (var i = 0, len = items.length; i < len; i++) {
                if (items.get(i).id == card.id) {
                    break;
                }
            }
    
            this.currentCard = i;
            this.headPanel.updateStep(i, card.title);
    
            if (i == len - 1) {
                this.nextButton.setText(this.finishButtonText);
            } else {
                this.nextButton.setText(this.nextButtonText);
            }
    
            if (card.isValid()) {
                this.nextButton.setDisabled(false);
            }
    
            if (i == 0) {
                this.previousButton.setDisabled(true);
            } else {
                this.previousButton.setDisabled(false);
            }
    
        },
    
        /**
         * Fires the 'cancel'-event. Closes this dialog if the return value of the
         * listeners does not equal to "false".
         */
        onCancelClick: function () {
            if (this.fireEvent('cancel', this) !== false) {
                this.win = this.findParentByType('window');
                if (this.win) {
                    this.win.hide();
                } else {
                    this.close();
                }
            }
        },
    
        /**
         * Fires the 'finish'-event. Closes this dialog if the return value of the
         * listeners does not equal to "false".
         */
        onFinish: function () {
            if (this.fireEvent('finish', this, this.getWizardData()) !== false) {
                this.win = this.findParentByType('window');
                if (!this.win) {
                    this.close();
                }
            }
        },
    
        /**
         * Listener for the previous-button.
         * Switches to the previous displayed {@link Ext.ux.Wiz.Card}.
         */
        onPreviousClick: function () {
            if (this.currentCard > 0) {
                this.cardPanel.getLayout().setActiveItem(this.currentCard - 1);
            }
        },
    
        /**
         * Listener for the next-button. Switches to the next {@link Ext.ux.Wiz.Card}
         * if the 'beforehide'-method of it did not return false. The functionality
         * for this is implemented in {@link Ext.ux.layout.CardLayout}, which is needed
         * as the layout for the card-panel of this component.
         */
        onNextClick: function () {
            if (this.currentCard == this.cardCount - 1) {
                this.onFinish();
            } else {
                this.cardPanel.getLayout().setActiveItem(this.currentCard + 1);
            }
        }
    });
    
    Ext.namespace('Ext.ux.Wiz');
    
    /**
     * Licensed under GNU LESSER GENERAL PUBLIC LICENSE Version 3
     *
     * @author Thorsten Suckow-Homberg <ts@siteartwork.de>
     * @url http://www.siteartwork.de/wizardcomponent
     */
    
    /**
     * @class Ext.ux.Wiz.Header
     * @extends Ext.BoxComponent
     *
     * A specific {@link Ext.BoxComponent} that can be used to show the current process in an
     * {@link Ext.ux.Wiz}.
     *
     * An instance of this class is usually being created by {@link Ext.ux.Wiz#initPanels} using the
     * {@link Ext.ux.Wiz#headerConfig}-object.
     *
     * @private
     * @constructor
     * @param {Object} config The config object
     */
    Ext.ux.Wiz.Header = Ext.extend(Ext.BoxComponent, {
    
        /**
         * @cfg {Number} height The height of this component. Defaults to "55".
         */
        height: 55,
    
        /**
         * @cfg {String} region The Region of this component. Since a {@link Ext.ux.Wiz}
         * usually uses a {@link Ext.layout.BorderLayout}, this property defaults to
         * "north". If you want to change this property, you should also change the appropriate
         * css-classes that are used for this component.
         */
        region: 'north',
    
        /**
         * @cfg {String} title The title that gets rendered in the head of the component. This
         * should be a text describing the purpose of the wizard.
         */
        title: 'Wizard',
    
        /**
         * @cfg {Number} steps The overall number of steps the user has to go through
         * to finish the wizard.
         */
        steps: 0,
    
        /**
         * @cfg {String} stepText The text in the header indicating the current process in the wizard.
         * (defaults to "Step {0} of {1}: {2}").
         * {0} is replaced with the index (+1) of the current card, {1} is replaced by the
         * total number of cards in the wizard and {2} is replaced with the title-property of the
         * {@link Ext.ux.Wiz.Card}
         * @type String
         */
        stepText: "Step {0} of {1}: {2}",
    
        /**
         * @cfg {Object} autoEl The element markup used to render this component.
         */
        autoEl: {
            tag: 'div',
            cls: 'ext-ux-wiz-Header',
            children: [{
                tag: 'div',
                cls: 'ext-ux-wiz-Header-title'
            },
            {
                tag: 'div',
                children: [{
                    tag: 'div',
                    cls: 'ext-ux-wiz-Header-step'
                },
                {
                    tag: 'div',
                    cls: 'ext-ux-wiz-Header-stepIndicator-container'
                }]
            }]
        },
    
        /**
         * @param {Ext.Element}
         */
        titleEl: null,
    
        /**
         * @param {Ext.Element}
         */
        stepEl: null,
    
        /**
         * @param {Ext.Element}
         */
        imageContainer: null,
    
        /**
         * @param {Array}
         */
        indicators: null,
    
        /**
         * @param {Ext.Template}
         */
        stepTemplate: null,
    
        /**
         * @param {Number} lastActiveStep Stores the index of the last active card that
         * was shown-
         */
        lastActiveStep: -1,
    
        // -------- helper
        /**
         * Gets called by  {@link Ext.ux.Wiz#onCardShow()} and updates the header
         * with the approppriate information, such as the progress of the wizard
         * (i.e. which card is being shown etc.)
         *
         * @param {Number} currentStep The index of the card currently shown in
         * the wizard
         * @param {String} title The title-property of the {@link Ext.ux.Wiz.Card}
         *
         * @private
         */
        updateStep: function (currentStep, title) {
            var html = this.stepTemplate.apply({
                0: currentStep + 1,
                1: this.steps,
                2: title
            });
    
            this.stepEl.update(html);
    
            if (this.lastActiveStep != -1) {
                this.indicators[this.lastActiveStep].removeClass('ext-ux-wiz-Header-stepIndicator-active');
            }
    
            this.indicators[currentStep].addClass('ext-ux-wiz-Header-stepIndicator-active');
    
            this.lastActiveStep = currentStep;
        },
    
        // -------- listener
        /**
         * Overrides parent implementation to render this component properly.
         */
        onRender: function (ct, position) {
            Ext.ux.Wiz.Header.superclass.onRender.call(this, ct, position);
    
            this.indicators = [];
            this.stepTemplate = new Ext.Template(this.stepText);
            this.stepTemplate.compile();
    
            var el = this.el.dom.firstChild;
            var ns = el.nextSibling;
    
            this.titleEl = new Ext.Element(el);
            this.stepEl = new Ext.Element(ns.firstChild);
            this.imageContainer = new Ext.Element(ns.lastChild);
    
            this.titleEl.update(this.title);
    
            var image = null;
            for (var i = 0, len = this.steps; i < len; i++) {
                image = document.createElement('div');
                image.innerHTML = " ";
                image.className = 'ext-ux-wiz-Header-stepIndicator';
                this.indicators[i] = new Ext.Element(image);
                this.imageContainer.appendChild(image);
            }
        }
    });
    
    Ext.namespace('Ext.ux.Wiz');
    
    /**
     * Licensed under GNU LESSER GENERAL PUBLIC LICENSE Version 3
     *
     * @author Thorsten Suckow-Homberg <ts@siteartwork.de>
     * @url http://www.siteartwork.de/wizardcomponent
     */
    
    /**
     * @class Ext.ux.Wiz.Card
     * @extends Ext.FormPanel
     *
     * A specific {@link Ext.FormPanel} that can be used as a card in a
     * {@link Ext.ux.Wiz}-component. An instance of this card does only work properly
     * if used in a panel that uses a {@see Ext.layout.CardLayout}-layout.
     *
     * @constructor
     * @param {Object} config The config object
     */
    Ext.ux.Wiz.Card = Ext.extend(Ext.FormPanel, {
    
        /**
         * @cfg {Boolean} header "True" to create the header element. Defaults to
         * "false". See {@link Ext.form.FormPanel#header}
         */
        header: false,
    
        /**
         * @cfg {Strting} hideMode Hidemode of this component. Defaults to "offsets".
         * See {@link Ext.form.FormPanel#hideMode}
         */
        hideMode: 'display',
    
        initComponent: function () {
            this.addEvents(
            /**
                 * @event beforecardhide
                 * If you want to add additional checks to your card which cannot be easily done
                 * using default validators of input-fields (or using the monitorValid-config option),
                 * add your specific listeners to this event.
                 * This event gets only fired if the activeItem of the ownerCt-component equals to
                 * this instance of {@see Ext.ux.Wiz.Card}. This is needed since a card layout usually
                 * hides it's items right after rendering them, involving the beforehide-event.
                 * If those checks would be attached to the normal beforehide-event, the card-layout
                 * would never be able to hide this component after rendering it, depending on the
                 * listeners return value.
                 *
                 * @param {Ext.ux.Wiz.Card} card The card that triggered the event
                 */
            'beforecardhide');
    
            Ext.ux.Wiz.Card.superclass.initComponent.call(this);
    
        },
    
        // -------- helper
        isValid: function () {
            if (this.monitorValid) {
                return this.bindHandler();
            }
    
            return true;
        },
    
        // -------- overrides
        /**
         * Overrides parent implementation since we allow to add any element
         * in this component which must not be neccessarily be a form-element.
         * So before a call to "isValid()" is about to be made, this implementation
         * checks first if the specific item sitting in this component has a method "isValid" - if it
         * does not exists, it will be added on the fly.
         */
        bindHandler: function () {
            this.form.items.each(function (f) {
                if (!f.isValid) {
                    f.isValid = Ext.emptyFn;
                }
            });
    
            Ext.ux.Wiz.Card.superclass.bindHandler.call(this);
        },
    
        /**
         * Overrides parent implementation. This is needed because in case
         * this method uses "monitorValid=true", the method "startMonitoring" must
         * not be called, until the "show"-event of this card fires.
         */
        initEvents: function () {
            var old = this.monitorValid;
            this.monitorValid = false;
            Ext.ux.Wiz.Card.superclass.initEvents.call(this);
            this.monitorValid = old;
    
            this.on('beforehide', this.bubbleBeforeHideEvent, this);
    
            this.on('beforecardhide', this.isValid, this);
            this.on('show', this.onCardShow, this);
            this.on('hide', this.onCardHide, this);
        },
    
        // -------- listener
        /**
         * Checks wether the beforecardhide-event may be triggered.
         */
        bubbleBeforeHideEvent: function () {
            var ly = this.ownerCt.layout;
            var activeItem = ly.activeItem;
    
            if (activeItem && activeItem.id === this.id) {
                return this.fireEvent('beforecardhide', this);
            }
    
            return true;
        },
    
        /**
         * Stops monitoring the form elements in this component when the
         * 'hide'-event gets fired.
         */
        onCardHide: function () {
            if (this.monitorValid) {
                this.stopMonitoring();
            }
        },
    
        /**
         * Starts monitoring the form elements in this component when the
         * 'show'-event gets fired.
         */
        onCardShow: function () {
            if (this.monitorValid) {
                this.startMonitoring();
            }
        }
    
    });

  10. #160
    Ext JS Premium Member
    Join Date
    Feb 2009
    Posts
    422
    Vote Rating
    1
    Jangla is on a distinguished road

      0  

    Default


    Awesome! I'm at home now but will have a look at your implementation method tomorrow.

Thread Participants: 96

  1. Animal (2 Posts)
  2. franklt69 (1 Post)
  3. jay@moduscreate.com (1 Post)
  4. Digital God (1 Post)
  5. mystix (4 Posts)
  6. fangzhouxing (3 Posts)
  7. mike1993 (2 Posts)
  8. KRavEN (1 Post)
  9. jsakalos (2 Posts)
  10. Ylodi (1 Post)
  11. Fabyo (2 Posts)
  12. anestesiadorhvs (1 Post)
  13. John Sourcer (1 Post)
  14. kmiyashiro (3 Posts)
  15. anjelika (6 Posts)
  16. cutigersfan (1 Post)
  17. mjlecomte (1 Post)
  18. kevinwu8 (2 Posts)
  19. JEBriggs (3 Posts)
  20. CutterBl (5 Posts)
  21. gelleneu (1 Post)
  22. Spirit (1 Post)
  23. Michelangelo (9 Posts)
  24. wm003 (1 Post)
  25. Juvs (3 Posts)
  26. Mthor (2 Posts)
  27. sean.zhou (2 Posts)
  28. donssmith (3 Posts)
  29. sigaref (1 Post)
  30. ajaxvador (1 Post)
  31. prodigy7 (2 Posts)
  32. mask_hot (2 Posts)
  33. ec-cts (1 Post)
  34. dorgan (2 Posts)
  35. DhakouaniM (1 Post)
  36. Romantik (2 Posts)
  37. franck34 (4 Posts)
  38. sirioz10 (1 Post)
  39. razor (15 Posts)
  40. chalu (2 Posts)
  41. cirvine (2 Posts)
  42. ClemsonJeeper (1 Post)
  43. GOTTMODUS (1 Post)
  44. rnfbr1 (2 Posts)
  45. walldorff (2 Posts)
  46. jlowe (1 Post)
  47. moegal (1 Post)
  48. johnstontrav (1 Post)
  49. mirko (1 Post)
  50. J.B (1 Post)
  51. niaz (1 Post)
  52. Jack_S (2 Posts)
  53. knarz (1 Post)
  54. hatch79 (1 Post)
  55. Eki (1 Post)
  56. accilies (3 Posts)
  57. SamuraiJack1 (1 Post)
  58. gthe (2 Posts)
  59. Scorpie (1 Post)
  60. supercharge2 (1 Post)
  61. lucasmarin (1 Post)
  62. alienwebz (7 Posts)
  63. kellyt (2 Posts)
  64. charleshimmer (20 Posts)
  65. nomdeguerre (3 Posts)
  66. perdar (2 Posts)
  67. agalue (2 Posts)
  68. pablitobs (4 Posts)
  69. jmariani (4 Posts)
  70. wemerson.januario (3 Posts)
  71. mschwartz (2 Posts)
  72. Stju (3 Posts)
  73. TheColonel (1 Post)
  74. lakilevi (1 Post)
  75. roque (2 Posts)
  76. Jangla (8 Posts)
  77. cchic (1 Post)
  78. MH61 (2 Posts)
  79. MasterAM (1 Post)
  80. pezze (8 Posts)
  81. phpfreak (1 Post)
  82. talha06 (1 Post)
  83. swarm (7 Posts)
  84. udalaitz (2 Posts)
  85. esh (1 Post)
  86. reci (1 Post)
  87. ccrotty (3 Posts)
  88. CarlosLuiz (3 Posts)
  89. guyfomi (1 Post)
  90. yugikhoi (1 Post)
  91. drunkmoose (1 Post)
  92. occiso (2 Posts)
  93. slckysr (3 Posts)
  94. samir_ware (1 Post)
  95. eCoast (2 Posts)
  96. wpenton (1 Post)

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar