Hybrid View

  1. #1
    Sencha User eirik.lorentsen's Avatar
    Join Date
    Aug 2011
    Location
    Santiago, Chile
    Posts
    33
    Vote Rating
    7
    eirik.lorentsen is on a distinguished road

      6  

    Default Ext.ux.window.Notification

    Ext.ux.window.Notification


    Notification extension for Ext JS 4.0.2+

    Examples and instructions

    New improved features include:
    • Multiple managers and notifications stacks
      The static manager object is eliminated completely, allowing notifications to attach to different components using their x and y coordinates to slide in the notifications.
    • All eight corners and edges of document/manager can be used: 'tl', 'tr', 'br', 'bl', 't', 'l', 'b', 'r'.
    • Both x and y axis can be used on corners. Notifications can slide in sideways.
    • When a notification is closed any notifications above it slide down automatically.
    • Hovering the mouse over the notification delays auto closing.
    • Easy customization of css, animations, delays, spacings/padding etc.
    Find the latest version on GitHub

    Or simply paste this code into a Notification.js file:
    PHP Code:
    /* 
     *    Notification extension for Ext JS 4.0.2+
     *    Version: 2.1.2
     *
     *    Copyright (c) 2011 Eirik Lorentsen (http://www.eirik.net/)
     *
     *    Follow project on GitHub: https://github.com/EirikLorentsen/Ext.ux.window.Notification
     *
     *    Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
     *    and GPL (http://opensource.org/licenses/GPL-3.0) licenses.
     *
     */


    Ext.define('Ext.ux.window.Notification', {
        
    extend'Ext.window.Window',
        
    alias'widget.uxNotification',


        
    cls'ux-notification-window',
        
    autoClosetrue,
        
    autoHeighttrue,
        
    plainfalse,
        
    draggablefalse,
        
    shadowfalse,
        
    focusExt.emptyFn,


        
    // For alignment and to store array of rendered notifications. Defaults to document if not set.
        
    managernull,


        
    useXAxisfalse,


        
    // Options: br, bl, tr, tl, t, l, b, r
        
    position'br',


        
    // Pixels between each notification
        
    spacing6,


        
    // Pixels from the managers borders to start the first notification
        
    paddingX30,
        
    paddingY10,


        
    slideInAnimation'easeIn',
        
    slideBackAnimation'bounceOut',
        
    slideInDuration1500,
        
    slideBackDuration1000,
        
    hideDuration500,
        
    autoCloseDelay7000,
        
    stickOnClicktrue,
        
    stickWhileHovertrue,


        
    // Private. Do not override!
        
    isHidingfalse,
        
    isFadingfalse,
        
    destroyAfterHidefalse,
        
    closeOnMouseOutfalse,


        
    // Caching coordinates to be able to align to final position of siblings being animated
        
    xPos0,
        
    yPos0,


        
    statics: {
            
    defaultManager: {
                
    elnull
            
    }
        },


        
    initComponent: function() {
            var 
    me this;


            
    // Backwards compatibility
            
    if (Ext.isDefined(me.corner)) {
                
    me.position me.corner;
            }
            if (
    Ext.isDefined(me.slideDownAnimation)) {
                
    me.slideBackAnimation me.slideDownAnimation;
            }
            if (
    Ext.isDefined(me.autoDestroyDelay)) {
                
    me.autoCloseDelay me.autoDestroyDelay;
            }
            if (
    Ext.isDefined(me.autoHideDelay)) {
                
    me.autoCloseDelay me.autoHideDelay;
            }
            if (
    Ext.isDefined(me.autoHide)) {
                
    me.autoClose me.autoHide;
            }
            if (
    Ext.isDefined(me.slideInDelay)) {
                
    me.slideInDuration me.slideInDelay;
            }
            if (
    Ext.isDefined(me.slideDownDelay)) {
                
    me.slideBackDuration me.slideDownDelay;
            }
            if (
    Ext.isDefined(me.fadeDelay)) {
                
    me.hideDuration me.fadeDelay;
            }


            
    // 'bc', lc', 'rc', 'tc' compatibility
            
    me.position me.position.replace(/c/, '');


            
    me.updateAlignment(me.position);


            
    me.setManager(me.manager);


            
    me.callParent(arguments);
        },


        
    onRender: function() {
            var 
    me this;
            
    me.callParent(arguments);


            
    me.el.hover(
                function () {
                    
    me.mouseIsOver true;
                },
                function () {
                    
    me.mouseIsOver false;
                    if (
    me.closeOnMouseOut) {
                        
    me.closeOnMouseOut false;
                        
    me.close();
                    }
                },
                
    me
            
    );


        },
        
        
    updateAlignment: function (position) {
            var 
    me this;


            switch (
    position) {
                case 
    'br':
                    
    me.paddingFactorX = -1;
                    
    me.paddingFactorY = -1;
                    
    me.siblingAlignment "br-br";
                    if (
    me.useXAxis) {
                        
    me.managerAlignment "bl-br";
                    } else {
                        
    me.managerAlignment "tr-br";
                    }
                    break;
                case 
    'bl':
                    
    me.paddingFactorX 1;
                    
    me.paddingFactorY = -1;
                    
    me.siblingAlignment "bl-bl";
                    if (
    me.useXAxis) {
                        
    me.managerAlignment "br-bl";
                    } else {
                        
    me.managerAlignment "tl-bl";
                    }
                    break;
                case 
    'tr':
                    
    me.paddingFactorX = -1;
                    
    me.paddingFactorY 1;
                    
    me.siblingAlignment "tr-tr";
                    if (
    me.useXAxis) {
                        
    me.managerAlignment "tl-tr";
                    } else {
                        
    me.managerAlignment "br-tr";
                    }
                    break;
                case 
    'tl':
                    
    me.paddingFactorX 1;
                    
    me.paddingFactorY 1;
                    
    me.siblingAlignment "tl-tl";
                    if (
    me.useXAxis) {
                        
    me.managerAlignment "tr-tl";
                    } else {
                        
    me.managerAlignment "bl-tl";
                    }
                    break;
                case 
    'b':
                    
    me.paddingFactorX 0;
                    
    me.paddingFactorY = -1;
                    
    me.siblingAlignment "b-b";
                    
    me.useXAxis 0;
                    
    me.managerAlignment "t-b";
                    break;
                case 
    't':
                    
    me.paddingFactorX 0;
                    
    me.paddingFactorY 1;
                    
    me.siblingAlignment "t-t";
                    
    me.useXAxis 0;
                    
    me.managerAlignment "b-t";
                    break;
                case 
    'l':
                    
    me.paddingFactorX 1;
                    
    me.paddingFactorY 0;
                    
    me.siblingAlignment "l-l";
                    
    me.useXAxis 1;
                    
    me.managerAlignment "r-l";
                    break;
                case 
    'r':
                    
    me.paddingFactorX = -1;
                    
    me.paddingFactorY 0;
                    
    me.siblingAlignment "r-r";
                    
    me.useXAxis 1;
                    
    me.managerAlignment "l-r";
                    break;
                }
        },
        
        
    getXposAlignedToManager: function () {
            var 
    me this;


            var 
    xPos 0;


            
    // Avoid error messages if the manager does not have a dom element
            
    if (me.manager && me.manager.el && me.manager.el.dom) {
                if (!
    me.useXAxis) {
                    
    // Element should already be aligned vertically
                    
    return me.el.getLeft();
                } else {
                    
    // Using getAnchorXY instead of getTop/getBottom should give a correct placement when document is used
                    // as the manager but is still 0 px high. Before rendering the viewport.
                    
    if (me.position == 'br' || me.position == 'tr' || me.position == 'r') {
                        
    xPos += me.manager.el.getAnchorXY('r')[0];
                        
    xPos -= (me.el.getWidth() + me.paddingX);
                    } else {
                        
    xPos += me.manager.el.getAnchorXY('l')[0];
                        
    xPos += me.paddingX;
                    }
                }
            }


            return 
    xPos;
        },


        
    getYposAlignedToManager: function () {
            var 
    me this;


            var 
    yPos 0;


            
    // Avoid error messages if the manager does not have a dom element
            
    if (me.manager && me.manager.el && me.manager.el.dom) {
                if (
    me.useXAxis) {
                    
    // Element should already be aligned horizontally
                    
    return me.el.getTop();
                } else {
                    
    // Using getAnchorXY instead of getTop/getBottom should give a correct placement when document is used
                    // as the manager but is still 0 px high. Before rendering the viewport.
                    
    if (me.position == 'br' || me.position == 'bl' || me.position == 'b') {
                        
    yPos += me.manager.el.getAnchorXY('b')[1];
                        
    yPos -= (me.el.getHeight() + me.paddingY);
                    } else {
                        
    yPos += me.manager.el.getAnchorXY('t')[1];
                        
    yPos += me.paddingY;
                    }
                }
            }


            return 
    yPos;
        },


        
    getXposAlignedToSibling: function (sibling) {
            var 
    me this;


            if (
    me.useXAxis) {
                if (
    me.position == 'tl' || me.position == 'bl' || me.position == 'l') {
                    
    // Using sibling's width when adding
                    
    return (sibling.xPos sibling.el.getWidth() + sibling.spacing);
                } else {
                    
    // Using own width when subtracting
                    
    return (sibling.xPos me.el.getWidth() - me.spacing);
                }
            } else {
                return 
    me.el.getLeft();
            }


        },


        
    getYposAlignedToSibling: function (sibling) {
            var 
    me this;


            if (
    me.useXAxis) {
                return 
    me.el.getTop();
            } else {
                if (
    me.position == 'tr' || me.position == 'tl' || me.position == 't') {
                    
    // Using sibling's width when adding
                    
    return (sibling.yPos sibling.el.getHeight() + sibling.spacing);                
                } else {
                    
    // Using own width when subtracting
                    
    return (sibling.yPos me.el.getHeight() - sibling.spacing);
                }
            }
        },


        
    getNotifications: function (alignment) {
            var 
    me this;


            if (!
    me.manager.notifications[alignment]) {
                
    me.manager.notifications[alignment] = [];
            }


            return 
    me.manager.notifications[alignment];
        },


        
    setManager: function (manager) {
            var 
    me this;


            
    me.manager manager;


            if (
    typeof me.manager == 'string') {
                
    me.manager Ext.getCmp(me.manager);
            }


            
    // If no manager is provided or found, then the static object is used and the el property pointed to the body document.
            
    if (!me.manager) {
                
    me.manager me.statics().defaultManager;


                if (!
    me.manager.el) {
                    
    me.manager.el Ext.getBody();
                }
            }
            
            if (
    typeof me.manager.notifications == 'undefined') {
                
    me.manager.notifications = {};
            }
        },
        
        
    beforeShow: function () {
            var 
    me this;


            if (
    me.stickOnClick) {
                if (
    me.body && me.body.dom) {
                    
    Ext.fly(me.body.dom).on('click', function () {
                        
    me.cancelAutoClose();
                        
    me.addCls('notification-fixed');
                    }, 
    me);
                }
            }


            if (
    me.autoClose) {
                
    me.task = new Ext.util.DelayedTask(me.doAutoCloseme);
                
    me.task.delay(me.autoCloseDelay);
            }


            
    // Shunting offscreen to avoid flicker
            
    me.el.setX(-10000);
            
    me.el.setOpacity(1);
            
        },


        
    afterShow: function () {
            var 
    me this;


            
    me.callParent(arguments);


            var 
    notifications me.getNotifications(me.managerAlignment);


            if (
    notifications.length) {
                
    me.el.alignTo(notifications[notifications.length 1].elme.siblingAlignment, [00]);
                
    me.xPos me.getXposAlignedToSibling(notifications[notifications.length 1]);
                
    me.yPos me.getYposAlignedToSibling(notifications[notifications.length 1]);
            } else {
                
    me.el.alignTo(me.manager.elme.managerAlignment, [(me.paddingX me.paddingFactorX), (me.paddingY me.paddingFactorY)], false);
                
    me.xPos me.getXposAlignedToManager();
                
    me.yPos me.getYposAlignedToManager();
            }


            
    Ext.Array.include(notificationsme);


            
    // Repeating from coordinates makes sure the windows does not flicker into the center of the viewport during animation
            
    me.el.animate({
                
    from: {
                    
    xme.el.getX(),
                    
    yme.el.getY()
                },
                
    to: {
                    
    xme.xPos,
                    
    yme.yPos,
                    
    opacity1
                
    },
                
    easingme.slideInAnimation,
                
    durationme.slideInDuration,
                
    dynamictrue
            
    });


        },
        
        
    slideBack: function () {
            var 
    me this;


            var 
    notifications me.getNotifications(me.managerAlignment);
            var 
    index Ext.Array.indexOf(notificationsme)


            
    // Not animating the element if it already started to hide itself or if the manager is not present in the dom
            
    if (!me.isHiding && me.el && me.manager && me.manager.el && me.manager.el.dom && me.manager.el.isVisible()) {


                if (
    index) {
                    
    me.xPos me.getXposAlignedToSibling(notifications[index 1]);
                    
    me.yPos me.getYposAlignedToSibling(notifications[index 1]);
                } else {
                    
    me.xPos me.getXposAlignedToManager();
                    
    me.yPos me.getYposAlignedToManager();
                }


                
    me.stopAnimation();


                
    me.el.animate({
                    
    to: {
                        
    xme.xPos,
                        
    yme.yPos
                    
    },
                    
    easingme.slideBackAnimation,
                    
    durationme.slideBackDuration,
                    
    dynamictrue
                
    });
            }
        },


        
    cancelAutoClose: function() {
            var 
    me this;


            if (
    me.autoClose) {
                
    me.task.cancel();
            }
        },


        
    doAutoClose: function () {
            var 
    me this;


            if (!(
    me.stickWhileHover && me.mouseIsOver)) {
                
    // Close immediately
                
    me.close();
            } else {
                
    // Delayed closing when mouse leaves the component.
                
    me.closeOnMouseOut true;
            }
        },


        
    removeFromManager: function () {
            var 
    me this;


            if (
    me.manager) {
                var 
    notifications me.getNotifications(me.managerAlignment);
                var 
    index Ext.Array.indexOf(notificationsme);
                if (
    index != -1) {
                    
    // Requires Ext JS 4.0.2
                    
    Ext.Array.erase(notificationsindex1);


                    
    // Slide "down" all notifications "above" the hidden one
                    
    for (;index notifications.lengthindex++) {
                        
    notifications[index].slideBack();
                    }
                }
            }
        },


        
    hide: function () {
            var 
    me this;


            if (
    me.isHiding) {
                if (!
    me.isFading) {
                    
    me.callParent(arguments);
                    
    // Must come after callParent() since it will pass through hide() again triggered by destroy()
                    
    me.isHiding false;
                }
            } else {
                
    // Must be set right away in case of double clicks on the close button
                
    me.isHiding true;
                
    me.isFading true;


                
    me.cancelAutoClose();


                if (
    me.el) {
                    
    me.el.fadeOut({
                        
    opacity0,
                        
    easing'easeIn',
                        
    durationme.hideDuration,
                        
    removeme.destroyAfterHide,
                        
    listeners: {
                            
    afteranimate: function () {
                                
    me.isFading false;
                                
    me.removeCls('notification-fixed');
                                
    me.removeFromManager();
                                
    me.hide();
                            }
                        }
                    });
                }
            }


            return 
    me;
        },


        
    destroy: function () {
            var 
    me this;
            if (!
    me.hidden) {
                
    me.destroyAfterHide true;
                
    me.hide();
            } else {
                
    me.callParent(arguments);
            }
        }


    }); 
    Last edited by eirik.lorentsen; 13 Sep 2013 at 7:50 AM. Reason: Version 2.1.2

  2. #2
    Sencha User
    Join Date
    Feb 2009
    Posts
    2
    Vote Rating
    0
    shadowman1024 is on a distinguished road

      0  

    Default Very Good

    Very Good


    thanks a lot for this. Excellent work

  3. #3
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,797
    Vote Rating
    834
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Very nice! Love the bounce effects!
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  4. #4
    Sencha User
    Join Date
    Dec 2010
    Posts
    12
    Vote Rating
    0
    kennedyt is on a distinguished road

      0  

    Default


    Very good!

  5. #5
    Sencha Premium Member
    Join Date
    Oct 2009
    Location
    Germany
    Posts
    298
    Vote Rating
    62
    Ekambos is a jewel in the rough Ekambos is a jewel in the rough Ekambos is a jewel in the rough Ekambos is a jewel in the rough

      0  

    Default


    You saved my day

  6. #6
    Sencha User
    Join Date
    Oct 2010
    Posts
    6
    Vote Rating
    0
    thomaschang is on a distinguished road

      0  

    Default not function well within IE7 & IE8

    not function well within IE7 & IE8


    i found it got error message at line 292 within IE7 & IE8

  7. #7
    Sencha User talha06's Avatar
    Join Date
    Jul 2009
    Location
    Turkey
    Posts
    303
    Vote Rating
    0
    talha06 is on a distinguished road

      0  

    Default


    it is working very well with the latest version of Ext JS(4.2.1). Thanks a lot Eirick!
    "People will never forget how you made them feel."
    linkedin.com/in/talhakabakus

  8. #8
    Sencha User
    Join Date
    Dec 2012
    Location
    hyderabad
    Posts
    91
    Vote Rating
    0
    javapurna is on a distinguished road

      0  

    Default list of notifications showing

    list of notifications showing


    Hi eirik.lorentsen,
    how to show list of notifications .for suppose 10 notifications coming from database at once (Array[10])

    i am create like below
    Code:
    for(var i=0;i<event.data.length;i++){
    var notification =Ext.create("MotApp.util.Notification", {
      title: 'Notification',
      position: "br",// Options: br, bl, tr, tl, t, l, b, r
      cls: "ux-notification-window ux-notification-success",
      iconCls: "ux-notification-icon-information",
    Code:
      spacing: 15,
      html:event.data[i].message,
      autoCloseDelay: 7000,
    });
    notification.show();		        		}
    
    

    event.data contains Array[10] objects . i am iterating and displaying . but all notifications close at a time.




    )

  9. #9
    Sencha Premium Member
    Join Date
    Feb 2012
    Location
    Raleigh, NC
    Posts
    418
    Vote Rating
    136
    brian428 is a splendid one to behold brian428 is a splendid one to behold brian428 is a splendid one to behold brian428 is a splendid one to behold brian428 is a splendid one to behold brian428 is a splendid one to behold

      0  

    Default


    If you set them all to close after 7000 ms, then that's when they'll all close.

    Also, showing 10 simultaneous notifications is a really poor UX choice. Either reduce the noise, or combine them into one notification.

  10. #10
    Sencha User
    Join Date
    Oct 2013
    Posts
    9
    Vote Rating
    1
    JK3jp5qMJwKW is on a distinguished road

      0  

    Default


    He released a new version: 2.1.3http://www.eirik.net/Ext/ux/window/Notification.js

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi