Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hey guys, I'm just wondering if you could help me with a little issue I'm having. I created a notification for my ASP.NET application it all works great but I have a minor problem when I try and catch the user interaction event from the screen in the .js file. For some reason when there are more than one notifications on screen, no matter which one the user clicks it always returns the last one in the queue. Below is the relevant code in the js file so if anyone can spot what I'm doing wrong I'd be very grateful. When I debug the code all the I'd are set correctly its just when the user clicks the close button the base.options.ClientNotificationId is always the last one rendered to the screen.

Entire Js File
JavaScript
(function($) {
    $.notification = function (options, customContainer) {

        //var this = this;
        var $notification = null;
        var isCustom = false; 

        //enum used to capture the event type
        var eventType = { closeButtonClick: 1, userClick: 2, mouseOver: 3, timeOut: 4 };

        this.init = function(options) {
            this.options = $.extend({}, $.notification.defaultOptions, options);
            this.options.type = this.options.cssPrefix + this.options.type;
            this.options.id = this.options.type + '_' + new Date().getTime();
            this.options.layout = this.options.cssPrefix + 'layout_' + this.options.layout;
            this.options.event = '';
          
            if (this.options.custom.container) customContainer = this.options.custom.container;
            isCustom = ($.type(customContainer) === 'object') ? true : false;

            return this.addQueue();
        };

        // Push notification to queue
        this.addQueue = function() {
            var isGrowl = ($.inArray(this.options.layout, $.notification.growls) == -1) ? false : true;
            if (!isGrowl) (this.options.force) ? $.notification.queue.unshift({ options: this.options }) : $.notification.queue.push({ options: this.options });
            return this.render(isGrowl);
        };

        // Render the notification
        this.render = function(isGrowl, Url) {

            // Layout spesific container settings
            var container = (isCustom) ? customContainer.addClass(this.options.theme + ' ' + this.options.layout + ' noty_custom_container') : $('body');
            if (isGrowl) {
                if ($('ul.noty_cont.' + this.options.layout).length == 0)
                    container.prepend($('<ul/>').addClass('noty_cont ' + this.options.layout));
                container = $('ul.noty_cont.' + this.options.layout);
            } else {
                if ($.notification.available) {
                    var fromQueue = $.notification.queue.shift(); // Get noty from queue
                    if ($.type(fromQueue) === 'object') {
                        $.notification.available = false;
                        this.options = fromQueue.options;
                    } else {
                        $.notification.available = true; // Queue is over
                        return this.options.id;
                    }
                } else {
                    return this.options.id;
                }
            }
            this.container = container;

            // Generating noty bar
            this.bar = $('<div class="noty_bar"/>').attr('id', this.options.id).addClass(this.options.theme + ' ' + this.options.layout + ' ' + this.options.type);
            $notification = this.bar;
            $notification.append(this.options.template).find('.noty_text').html(this.options.text);
            $notification.data('noty_options', this.options);

            alert('Generating ' + this.options.ClientNotificationId);

            // Close button display
            (this.options.closeButton) ? $notification.addClass('noty_closable').find('.noty_close').show() : $notification.find('.noty_close').remove();

            // Bind close event to button
            $notification.find('.noty_close').unbind('click').bind('click', function () {
            //$notification.find('.noty_close').bind('click', function () {

                //if we press the close button we need to unbind the close event and create our own.
                //$notification.unbind('click');
                $notification.fadeOut('slow');

             //   if (this.options.ClientNotificationId == 0) {
             //       alert(this.options.ClientNotificationId);
              //      UpdateCustomClientNotification(eventType.closeButtonClick);
             //   }
             //   else {
                    //record if the close button was clicked      
                //     alert(this.options.ClientNotificationId);

                alert($(this).options.ClientNotificationId);

                UpdateClientNotificationEntry($(this).options.ClientNotificationId, eventType.closeButtonClick);

                return false;

                //}
            });

            // If we have a button we must disable closeOnSelfClick and closeOnSelfOver option
            if (this.options.buttons) this.options.closeOnSelfClick = this.options.closeOnSelfOver = false;
          
            if (this.options.closeOnSelfClick) $notification.bind('click', function() {
                $notification.trigger('noty.close');
               
                alert('Click Method' + ClientNotificationId);

                if (this.options.url) {
                    window.location = this.options.url;
                }

               // if (this.options.ClientNotificationId == 0) {
               //     alert(this.options.ClientNotificationId);
              //      UpdateCustomClientNotification(eventType.userClick);
              //  }
               // else
               // {
                 //   alert(this.options.ClientNotificationId);
                    UpdateClientNotificationEntry(this.options.ClientNotificationId, eventType.userClick);
                //}
               
                
            });
            // Close on self mouseover
            if (this.options.closeOnSelfOver) $notification.bind('mouseover', function() {
               $notification.animate(5000);
               $notification.trigger('noty.close');

               //if mouse over is set update client notifications based on that.  
               UpdateClientNotificationEntry(this.options.ClientNotificationId, eventType.mouseOver);


            }).css('cursor', 'pointer');

            // Set buttons if available
            if (this.options.buttons) {
                $buttons = $('<div/>').addClass('noty_buttons');
                $notification.find('.noty_message').append($buttons);
                $.each(this.options.buttons, function(i, button) {
                    bclass = (button.type) ? button.type : 'gray';
                    $button = $('<button/>').addClass(bclass).html(button.text).appendTo($notification.find('.noty_buttons'))
					.bind('click', function() {
					    if ($.isFunction(button.click)) {
					        button.click.call($button, $notification);					        
					    }
					});
                });
            }

            return this.show(isGrowl);
        };

        this.show = function(isGrowl) {

            // is Modal?
            if (this.options.modal) $('<div/>').addClass('noty_modal').addClass(this.options.theme).prependTo($('body')).fadeIn('fast');

            $notification.close = function() { return this.trigger('noty.close'); };

            // Prepend noty to container
            (isGrowl) ? this.container.prepend($('<li/>').append($notification)) : this.container.prepend($notification);

            // topCenter and center specific options
            if (this.options.layout == 'noty_layout_topCenter' || this.options.layout == 'noty_layout_center') {
                $.notification.reCenter($notification);
            }

            $notification.bind('noty.setText', function(event, text) {
                $notification.find('.noty_text').html(text);

                if (this.options.layout == 'noty_layout_topCenter' || this.options.layout == 'noty_layout_center') {
                    $.notification.reCenter($notification);
                }
            });

            $notification.bind('noty.getId', function(event) {
                return $notification.data('noty_options').id;
            });

            // Bind close event
            $notification.one('noty.close', function(event) {
                var options = $notification.data('noty_options');
                 
             
                // Modal Cleaning
                if (options.modal) $('.noty_modal').fadeOut('fast', function() { $(this).remove(); });

                $notification.clearQueue().stop().animate(
						$notification.data('noty_options').animateClose,
						$notification.data('noty_options').speed,
						$notification.data('noty_options').easing,
						$notification.data('noty_options').onClose)
				.promise().done(function() {

				    // Layout spesific cleaning
				    if ($.inArray($notification.data('noty_options').layout, $.notification.growls) > -1) {
				        $notification.parent().remove();
				    } else {
				        $notification.remove();

				        // queue render
				        $.notification.available = true;
				        this.render(false);
				    }

				});
            });

            // Start the show
            $notification.animate(this.options.animateOpen, this.options.speed, this.options.easing, this.options.onShow);

            // If noty is have a timeout option
            if (this.options.timeout) $notification.delay(this.options.timeout).promise().done(function () {

                $notification.removeProp(this.options.url);
                $notification.trigger('noty.close');

                //update client notifications timed out
                UpdateClientNotificationEntry(this.options.notificationId, eventType.timeOut);
               
            });
            return this.options.event;
        };

        // Run initializer
        return this.init(options);
    };

    // API
    $.notification.get = function(id) { return $('#' + id); };
    $.notification.close = function(id) {
        $.notification.get(id).trigger('noty.close');
    };
    $.notification.setText = function(id, text) {
        $.notification.get(id).trigger('noty.setText', text);
    };
    $.notification.closeAll = function() {
        $.notification.clearQueue();
        $('.noty_bar').trigger('noty.close');
    };
    $.notification.reCenter = function(notification) {
        notification.css({ 'left': ($(window).width() - notification.outerWidth()) / 2 + 'px' });
    };
    $.notification.clearQueue = function() {
        $.notification.queue = [];
    };

    $.notification.queue = [];
    $.notification.growls = ['noty_layout_topLeft', 'noty_layout_topRight', 'noty_layout_bottomLeft', 'noty_layout_bottomRight'];
    $.notification.available = true;
    $.notification.defaultOptions = {
        ClientNotificationId : 0,
        layout: 'top',
        theme: 'noty_theme_default',
        animateOpen: { height: 'toggle' },
        animateClose: { height: 'toggle' },
        easing: 'swing',
        text: '',
        url: '',
        type: 'alert',
        speed: 500,
        // timeout: 5000,
        isCustomNotification : false,
        closeButton: false,
        closeOnSelfClick: true,
        closeOnSelfOver: false,
        force: false,
        onShow: false,
        onClose: false,
        buttons: false,
        modal: false,
        template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',
        cssPrefix: 'noty_',
        custom: {
            container: null
        }
    };

    $.fn.notification = function(options) {
        return this.each(function() {
            (new $.noty(options, $(this)));
        });
    };

})(jQuery);

//Helper
function notification(options) {
    return jQuery.notification(options); // returns an id
}
Posted
Updated 25-Mar-14 8:28am
v5

1 solution

Please try is as below.

// Bind close event to button
$notification.find('.noty_close').unbind('click').bind('click', function () {
 
$(this).fadeOut('slow');
 

//record if the close button was clicked      
UpdateClientNotificationEntry(base.options.ClientNotificationId, eventType.closeButtonClick);

retrun false;//to prevent the browser actually following the links.

});


UPDATE

On your scenario you cannot cache the base object like this var base = this;.If you do so it always take the last cached item.That's why you get the last id always.So the solution is remove above line of code and use this instead of it for each and every places where you use it (please keep a copy of your code before do the changes.It'll help for you. :)).

NOTE

Still I couldn't find the place where you set the value for the 'base.options.ClientNotificationId' ? Where is it ?
 
Share this answer
 
v4
Comments
frostcox 25-Mar-14 10:27am    
Hey thanks for your reply, the issue is still there. the base.options.ClientNotificationId is always the I'd of the last notification rendered to the screen even after making your change. Any more ideas?
Sampath Lokuge 25-Mar-14 10:40am    
Can you tell us more about this 'base.options.ClientNotificationId' ? May be code snippet of it help us.
frostcox 25-Mar-14 11:23am    
Ok I have say 3 or 4 separate notifications which each are passed to the js file in the format,
{"ClientNotificationId" : 220,
"text": "You have 1 notifications waiting to be processed. Click to view or X to remove all.",
"url": null,
"theme": "noty_theme_facebook",
"layout": "bottomRight",
"type": "alert",
"speed": 500,
"closeButton": true,
"closeOnSelfClick": true,
"closeOnSelfOver": false,
"modal": false
}
So each notification has its own ClientNotificationId sat 218,219, 220 etc...,
I have put various alerts in the js files to check that this Id is unique across all notifications and they all are. But when I try and capture the ClientNotificationId in the Close event it always returns the notification with 220.
frostcox 25-Mar-14 11:34am    
I can post the entire js file if that will help.
Sampath Lokuge 25-Mar-14 11:36am    
Yes,Please do that.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900