SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Zealot
    Join Date
    Feb 2007
    Location
    Leeds, U.K.
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Jquery plugin scope/best practice

    Hi,

    I've search for this but couldn't find a suitable answer.

    Basically I'm making a new plugin, and I'm using the format from this site:

    http://www.learningjquery.com/2007/1...opment-pattern

    However, I am having trouble with variable scope (or maybe I'm doing it the wrong way).

    If I have this (truncated so it's easier to read):
    Code JavaScript:
    (function($) 
    {
    	$.rp_popup = { 'version' : "0.0.1" };
    	$.fn.rp_popup = function(options)
    	{
    		var $element = $(this);
    		var options = $.extend({}, $.rp_popup.defaults, options);
     
    		$element.click(function()
    		{
    			return false;
    		});
    	};
    	$.rp_popup.open_popup = function()
    	{
                    // I want to access options here
    		debug(options);
    	}
    	$.rp_popup.defaults = {
    		modal		: false	
    	}
    })(jQuery);

    Ignore the fact the plugin does nothing

    How can I access options from the open_popup function? I know I can put it inside the rp_popup function but that seems a little hacky (although this is the way pretty photo does it).

    And jquery UI does it in a way where you pass a function as a string, and then uses eval to call it, so:
    Code JavaScript:
    $.rp_popup("open")
    but I'm not sure about that.

    So yea, sorry for the long post, but what's the best way to do it?

    Cheers in advance

  2. #2
    SitePoint Zealot
    Join Date
    Jun 2010
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    By using "var" keyword, you are making a variable visible globally.
    You can also pass that $.rp_popup to your function as a parameter.

  3. #3
    SitePoint Guru whisher's Avatar
    Join Date
    May 2006
    Location
    Kakiland
    Posts
    732
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,
    I think also a each is missing
    Code JavaScript:
     return this.each(function() {     
       });
    I found this http://blog.jeremymartin.name/2008/0...ugin-that.html very useful
    Bye

  4. #4
    SitePoint Zealot
    Join Date
    Jun 2010
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by whisher View Post
    Hi,
    I think also a each is missing
    Code JavaScript:
     return this.each(function() {     
       });
    I found this http://blog.jeremymartin.name/2008/0...ugin-that.html very useful
    Bye
    I would kindly suggest you don't advise someone on something that you yourself are unsure about, like in this case. Not only was your advice ambiguous, it also makes no sense in the context of answering the original question.

  5. #5
    SitePoint Zealot
    Join Date
    Feb 2007
    Location
    Leeds, U.K.
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Blue - It's the other way around isn't it? "var" makes them local? I guess I'll have to pass them in then as parameters, which does make sense. Cheers.

    @wisher - Cheers for the link, looks good. In my case, wrapping it in an each loop wouldn't be necessary I don't think.

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by MunkyDesigns View Post
    @Blue - It's the other way around isn't it? "var" makes them local? I guess I'll have to pass them in then as parameters, which does make sense. Cheers.
    What you could do as an alternative, is to move the var statement for that variable up out of the function, so that it is then accessible from both functions.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Zealot
    Join Date
    Feb 2007
    Location
    Leeds, U.K.
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cheers pmw57. Would those variables only be available within the function enclosure then?

    I think i'm getting confused because I'm seeing this as more of a class than a function, which it isn't.

  8. #8
    SitePoint Zealot
    Join Date
    Feb 2007
    Location
    Leeds, U.K.
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just tried that actually and I can't access the variables when I place them outside of the functions

  9. #9
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,527
    Mentioned
    84 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by MunkyDesigns View Post
    Just tried that actually and I can't access the variables when I place them outside of the functions
    Please show your code that is having the issue and we'll get you back on track.

    It helps to know that using var to declare a variable inside a function does clobber the variable of the same name from a higher scope.

    In other words, to access a variable from a higher scope (such as outside of a function) do not use the var keyword inside the function for that variable.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  10. #10
    SitePoint Zealot
    Join Date
    Feb 2007
    Location
    Leeds, U.K.
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Below is what I have. It's all working, just not sure if it's best practice.

    I have to pass the options var in to the open function because otherwise if applied this to two elements, it's only keep the latest's value.

    Sorry for the long post!

    Code JavaScript:
    /*
    	TODO	Allow custom classes for errors/rows
    */
    (function($) {
     
    	$.rpPopup = { 'version' : "0.0.1" };
     
    	$.fn.rpPopup = function(options)
    	{
    		var options = $.extend({}, $.rpPopup.defaults, options);
    		var $element = $(this);
    		var $backgroundDiv;
    		var $closeButton;
    		var $popupCont;
    		var	popupActive = false;
     
    		// Click to open
    		$element.click(function()
    		{	
    			$.rpPopup.open(options);
    			return false;
    		});
     
    		// Opening the popup
    		$.rpPopup.open = function(options)
    		{
    			// Create Items
    			$backgroundDiv = $('<div id="rp_popup_background" />')
    				.appendTo($(document.body))
    				.css({
    					 "opacity" : options.backgroundOpacity
    				});
    			$closeButton = $('<a id="rp_close_button" href="#">Close</a>')
    				.appendTo($(document.body));
    			$popupCont = $('<div id="' + options.popupId + '" />')
    				.appendTo($(document.body));
     
    			// Close button click
    			$closeButton.click(function()
    			{
    				$.rpPopup.close();
    				return false;
    			});
     
    			// Background click to close
    			$backgroundDiv.click(function()
    			{
    				if (!options.modal)
    					$.rpPopup.close();
    				return false;
    			});
     
    			var $loaderGif = $('<img src="' + options.loaderGif + '" />');
     
    			popupActive = true;
    			$backgroundDiv.fadeIn("fast");
    			$popupCont.html($loaderGif);
    			$.rpPopup.centre();
    			$popupCont.css({
    				"display"	: "block",
    				"opacity"	: 0
    			}).animate({
    				opacity		: 1
    			}, "fast");
     
    			if (options.content)
    			{
    				$popupCont.load(options.content, function(data)
    				{
    					$closeButton.fadeIn("fast");
    					var $content = $(data);
    					if ($content.find("form").length > 0)
    					{
    						var $form = $("#" + $content.find("form").attr("id"));
    						$form.submit(function(event){
    							$content.prepend($loaderGif);
    							$.rpPopup.centre();
    							if (options.validationUrl)
    							{
    								$.post(options.validationUrl, $form.serialize(), function(response){
     
    									// Remove any errors
    									$('.form_row').removeClass('invalid_row');
    									$form.find('.error').remove();
    									$loaderGif.remove();
     
    									if(response.status == "error") 
    									{
    										$.each(response.errors, function(key){
    											$('#' + key).parents('.form_row').addClass('invalid_row');
    										});
     
    										$form.prepend(response.feedback);
    									}
    									else
    									{
    										if (options.validationCallbackUrl)
    											window.location = options.validationCallbackUrl;
    										else if (response.feedback)
    											$form.before(response.feedback).remove();
    										else
    											$.rpPopup.close();
    									}
    									$.rpPopup.centre();
     
    								}, "json");
    							}
    							else
    							{
    								debug("No validationUrl supplied");
    							};
    							return false;
    						});
    					}
    					$.rpPopup.centre();
    				});
    			}
    			else
    			{
    				$popupCont.html("<p style=\"background:#fff;padding:10px;width:150px;text-align:centre\">No content can be loaded</p>");
    				$.rpPopup.centre();
    				debug("No content to load");
    			}
     
    		}
     
    		// Closing the popup
    		$.rpPopup.close = function()
    		{
    			if (popupActive)
    			{
    				popupActive = false;
    				$backgroundDiv.fadeOut("fast");
    				$popupCont.fadeOut("fast");
    				$closeButton.fadeOut("fast", function() {
    					$backgroundDiv.remove();
    					$popupCont.remove();
    					$closeButton.remove();
    				});
    			}
    		}
     
    		// Centering the popup
    		$.rpPopup.centre = function()
    		{
    			var popupWidth = options.popupWidth ? parseInt(options.popupWidth) : $popupCont.children().outerWidth();
    			var popupHeight = options.popupHeight ? parseInt(options.popupHeight) : $popupCont.children().outerHeight();
    			$popupCont.css({
    				"width"		: popupWidth,
    				"height" 	: popupHeight
    			});
    			var windowWidth = document.documentElement.clientWidth;
    			var windowHeight = document.documentElement.clientHeight;
    			$popupCont.css({
    				"bottom"	: windowHeight / 2  - popupHeight / 2,
    				"left"		: windowWidth / 2  - popupWidth / 2
    			});
    			// only need force for IE6
    			$backgroundDiv.css({
    				"height": windowHeight
    			});
    			// Position close button
    			$closeButton.css({
    				"bottom"	: windowHeight / 2  + popupHeight / 2,
    				"left"		: windowWidth / 2  + popupWidth / 2 - $closeButton.width() - 20
    			});
    		}
     
    		$(window).resize(function() 
    		{
    			if (popupActive)
    			{
    				$.rpPopup.centre();
    			}
    		});	
     
    	};
     
    	// Default options
    	$.rpPopup.defaults = {
    		modal					: false,
    		popupWidth				: null,
    		popupHeight				: null,
    		backgroundOpacity		: 0.7,
    		popupId					: "rp_popup_cont",
    		loaderGif				: "/graphics/rp-popup/ajax_loader.gif",
    		content					: "",
    		validationUrl			: "",
    		validationCallbackUrl	: ""
    	};
     
    	// Debug - so IE doesn't have a fit
    	function debug(value)
    	{
    		if (window.console && window.console.log)
    		{
    			console.log(value);
    		}
    	}
     
    })(jQuery);


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •