[jQuery] Re: Plugin development: Defaults & options: Questions?
Hi Scott! Thanks again for the help. I really appreciate it. :) > Looks right to me. One alternative, which wouldn't break the chain if > target is not supplied properly, would be this: Ah, right. That is a smart solution. Thanks for the clarification! > I don't think it's overkill for your initial jQuery object. I would > .. > matched element. Ah, very interesting. Thanks! I will probably stick with jQuery.each(), but it is nice to see alternative syntax. > But this leads to a more fundamental question, of why would this be a > .. > You could still use jQuery inside the function. Interesting... That is a great observation! Lol. You know, I will probably end up using a function now that you point it out... But this has been a great learning experience. Here is my actual code (simply splitting a ol/ul into two divs): == $.fn.splitList = function(id) { var $target = $('#' + id); if($target.length > 0) { // Traverse all nodes: return this.each(function() { var $this = $(this); var $clone = $this.clone(); $('li:odd', $this).remove(); $('li:even', $clone).remove(); $target.append($clone); }); } // $target }; })(jQuery); $('#catList').splitList('catFlow'); == > Perhaps it's just to learn jQuery plug-ins, and there's nothing wrong > with that. But if it doesn't work on multiple elements, should it > really be a plug-in? Food for thought, anyway. Definitely food for thought. Seems like a simple function would do the trick. I would love to figure out how to make it work on more than UL/OL... For example, I am using the call twice: $('#catList').splitList('catFlow'); $('#venList').splitList('venFlow'); Might be cool to do something like this: $('#catList, #venList').splitList({ 'catFlow', 'venFlow' }); But, hehe, that might be overkill and/or just plain silly! :D Thanks again for the help Scott! I owe you one. Have an excellent day! Cheers, Micky
[jQuery] Re: Plugin development: Defaults & options: Questions?
On Dec 21, 4:06 pm, Micky Hulse wrote: > Ok, so how does this look: > > (function($) { > $.fn.myFunction = function(id) { > var $target = $('#' + id); > if($target.length > 0) { > return this.each(function() { > // Do stuff here. > }); > } // $target > }; > })(jQuery); > > $('#div').myFunction('targ'); Looks right to me. One alternative, which wouldn't break the chain if target is not supplied properly, would be this: (function($) { $.fn.myFunction = function(id) { var $target = $('#' + id); if ($target.length != 1) return this; return this.each(function() { // Do stuff here. }); }; })(jQuery); > My plugin will only be used on an #id, and the output will only > manipulate a unique #id... In other words, there will only be one > unique id in both cases. With that said, is it overkill to use > "this.each()"? If so, what is the alternative syntax? I don't think it's overkill for your initial jQuery object. I would suggest that you don't do anything with .each for the target; I can't see any reason for that. jQuery.each() doesn't add much overhead. If you really wanted an alternative syntax, you might simply work with this[0], assuming it exists. In jQuery, that will be the first matched element. But this leads to a more fundamental question, of why would this be a plug-in if it only works on a single DOM element, presumably with an id selector? Why not a plain JS function of the following form?: function myFunction(source, target) You could still use jQuery inside the function. Perhaps it's just to learn jQuery plug-ins, and there's nothing wrong with that. But if it doesn't work on multiple elements, should it really be a plug-in? Food for thought, anyway. Good luck, -- Scott
[jQuery] Re: Plugin development: Defaults & options: Questions?
Hi Scott! Many thanks for your pro help and super fast reply! I really appreciate it. :) > There are a few options. I often add an optional errorHandler > .. > Then your code can check that the required parameter is there. Oooh, that is nice! Cool technique! Thanks for sharing. :) > Alternatively, you can simply fail silently, but merely document that > the parameter is required. For my simple plugin, this sounds like the most logical (and simple) route to take. > Absolutely, and I would recommend it. I'd also lose the "#" and just > add it in in the code: Great idea. Done. :) > Because it's the only required parameter, and in fact the only > parameter, I would definitely treat it differently. If you had five > .. > dividing line would be, but a single mandatory parameter definitely > falls in the simpler-is-better category. Cool! Ok, so how does this look: == (function($) { // // Plugin definition: // $.fn.myFunction = function(id) { var $target = $('#' + id); if($target.length > 0) { // Traverse all nodes: return this.each(function() { // Do stuff here. }); } // $target }; })(jQuery); $('#div').myFunction('targ'); == It appears to work... Simpler than what I had before. :) One last question: My plugin will only be used on an #id, and the output will only manipulate a unique #id... In other words, there will only be one unique id in both cases. With that said, is it overkill to use "this.each()"? If so, what is the alternative syntax? == Thanks again Scott, I really appreciate the help! Have a great day! Cheers, Micky
[jQuery] Re: Plugin development: Defaults & options: Questions?
On Dec 21, 3:08 pm, Micky Hulse wrote: > But, I guess I am wondering what the best way to handle javascript > error checking for required options? There are a few options. I often add an optional errorHandler function; my defaults would include: errorHandler: function(status, message) {} and then in development, I can pass in $(selector).plugin({errorHandler: function(status, msg) {alert(msg + ": " + status);}); then pull it out for most production code. Then your code can check that the required parameter is there. if (!target) { opts.errorHandler(1234, "You forgot to pass a target"); return; } Alternatively, you can simply fail silently, but merely document that the parameter is required. > $('#div').myFunction({ target: '#targ' }); > If the only option is "target", can I do something like this instead: > $('#div').myFunction('#targ'); Absolutely, and I would recommend it. I'd also lose the "#" and just add it in in the code: $("#" + target).doSomething(); > Because "#targ" is a required argument, should I handle it differently > than your normal "options" object? Because it's the only required parameter, and in fact the only parameter, I would definitely treat it differently. If you had five required parameter and nine optional ones, they should probably all go into an options hash, and you would have to deal with the fact that some are required mainly in the documentation. I'm not sure where the dividing line would be, but a single mandatory parameter definitely falls in the simpler-is-better category. Cheers, -- Scott
[jQuery] Re: Plugin Development
Anyone else able to shed some light on this? Spot wrote: Nathan, Ok, I am aware of the base use of each() (been coding in PHP for about eight years), but I cannot see how it is viable in this case. Making a long story short... This plug-in is a selector(auto-completer). To be more specific, it is several selectors. I have a specific plugin for each selector, and am $.extend()ing a base (external) DataSelector class, which has the boilerplate functionality (pulling data, building DOM elements, handling arrow keys, etc), and the plugins only have code specific to that data type. The problem I am having, is that even when using two different plugins, I get namespace conflicts (e.g. the last called plugin on the page, overwrites the namespace for all the previous). Ok, now because I am specifically hooking the plugin to only _one_ element each time, I cannot see how each() is helpful. Unless it needs to somehow return the one element with an index. Does this make sense? Again, I appreciate your assistance greatly. Thanks! Nathan wrote: Yeah, Copy/paste gets ya no where for sure. For each() you should check out: http://docs.jquery.com/Core/each Which states: "Execute a function within the context of every matched element" From my previous example, "this.each()" is the same as saying: $('#divNameHere').each(); So that runs your plugin only within that element. So this: $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }) Is also this in each instance: $('#divNameHere #nav a').click(function(){ $('#someDiv').fadeIn(); }) So it's changing out what '#divNameHere' is depending on what elements you are applying your plugin to. Hopefully that helps answer your question. If you're not already. Use Firefox with Firebug and put something like console.log('this is: ', this); in your plugin within the this.each() funciton. Firebug then will log what this is in each instance. And FYI console.log will give you a JS error in IE so comment it out before testing in IE. On Apr 7, 2:58 pm, Spot wrote: Nathan, first off, thank you for responding. I understand about passing the obj as scope. That makes perfect sense. However I am a little confused as to the purpose of returning this.each. What is the goal there? I find it better to understand why something works, as opposed to just copy/pasting. It saves everyone time in the long run. :) Thanks again! Nathan wrote: To do this you need to have "return this.each" and optionally change the instance of "this" which is the name of the object you are apply the plugin to, to "obj" using "var obj = $(this);". Then when you call a selector, you'll need to add "$('#nav a', obj)" note the ", obj". This will keep it within the name space of what ever selector you apply this to when the plugin is initialize. (function($){ $.fn.extend({ plauginNameHere: function() { return this.each(function() { var obj = $(this); // this just changes the use of 'this' to obj $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }); }) } }); })(jQuery); On the page level you will then need to initialize the plugin on the HTML page level. $(function(){ $('#divNameHere'). plauginNameHere(); // first instance$('#secondDivNameHere'). plauginNameHere(); // second instance}); So what ever the selector name is above, for example "#secondDivNameHere", will then be the 'this' that we changed to 'obj' using a var in plugin script. So in this example the plugin's "obj" is "#secondDivNameHere". Let me know if that helps. On Apr 6, 1:44 pm, Spot wrote: How would one develop a plugin which can exist multiple times on the same page, without conflicting with each others namespaces?
[jQuery] Re: Plugin Development
Nathan, Ok, I am aware of the base use of each() (been coding in PHP for about eight years), but I cannot see how it is viable in this case. Making a long story short... This plug-in is a selector(auto-completer). To be more specific, it is several selectors. I have a specific plugin for each selector, and am $.extend()ing a base (external) DataSelector class, which has the boilerplate functionality (pulling data, building DOM elements, handling arrow keys, etc), and the plugins only have code specific to that data type. The problem I am having, is that even when using two different plugins, I get namespace conflicts (e.g. the last called plugin on the page, overwrites the namespace for all the previous). Ok, now because I am specifically hooking the plugin to only _one_ element each time, I cannot see how each() is helpful. Unless it needs to somehow return the one element with an index. Does this make sense? Again, I appreciate your assistance greatly. Thanks! Nathan wrote: Yeah, Copy/paste gets ya no where for sure. For each() you should check out: http://docs.jquery.com/Core/each Which states: "Execute a function within the context of every matched element" From my previous example, "this.each()" is the same as saying: $('#divNameHere').each(); So that runs your plugin only within that element. So this: $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }) Is also this in each instance: $('#divNameHere #nav a').click(function(){ $('#someDiv').fadeIn(); }) So it's changing out what '#divNameHere' is depending on what elements you are applying your plugin to. Hopefully that helps answer your question. If you're not already. Use Firefox with Firebug and put something like console.log('this is: ', this); in your plugin within the this.each() funciton. Firebug then will log what this is in each instance. And FYI console.log will give you a JS error in IE so comment it out before testing in IE. On Apr 7, 2:58 pm, Spot wrote: Nathan, first off, thank you for responding. I understand about passing the obj as scope. That makes perfect sense. However I am a little confused as to the purpose of returning this.each. What is the goal there? I find it better to understand why something works, as opposed to just copy/pasting. It saves everyone time in the long run. :) Thanks again! Nathan wrote: To do this you need to have "return this.each" and optionally change the instance of "this" which is the name of the object you are apply the plugin to, to "obj" using "var obj = $(this);". Then when you call a selector, you'll need to add "$('#nav a', obj)" note the ", obj". This will keep it within the name space of what ever selector you apply this to when the plugin is initialize. (function($){ $.fn.extend({ plauginNameHere: function() { return this.each(function() { var obj = $(this); // this just changes the use of 'this' to obj $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }); }) } }); })(jQuery); On the page level you will then need to initialize the plugin on the HTML page level.$(function(){ $('#divNameHere'). plauginNameHere(); // first instance $('#secondDivNameHere'). plauginNameHere(); // second instance }); So what ever the selector name is above, for example "#secondDivNameHere", will then be the 'this' that we changed to 'obj' using a var in plugin script. So in this example the plugin's "obj" is "#secondDivNameHere". Let me know if that helps. On Apr 6, 1:44 pm, Spot wrote: How would one develop a plugin which can exist multiple times on the same page, without conflicting with each others namespaces?
[jQuery] Re: Plugin Development
Yeah, Copy/paste gets ya no where for sure. For each() you should check out: http://docs.jquery.com/Core/each Which states: "Execute a function within the context of every matched element" >From my previous example, "this.each()" is the same as saying: $('#divNameHere').each(); So that runs your plugin only within that element. So this: $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }) Is also this in each instance: $('#divNameHere #nav a').click(function(){ $('#someDiv').fadeIn(); }) So it's changing out what '#divNameHere' is depending on what elements you are applying your plugin to. Hopefully that helps answer your question. If you're not already. Use Firefox with Firebug and put something like console.log('this is: ', this); in your plugin within the this.each() funciton. Firebug then will log what this is in each instance. And FYI console.log will give you a JS error in IE so comment it out before testing in IE. On Apr 7, 2:58 pm, Spot wrote: > Nathan, first off, thank you for responding. > > I understand about passing the obj as scope. That makes perfect sense. > However I am a little confused as to the purpose of returning this.each. > What is the goal there? > > I find it better to understand why something works, as opposed to just > copy/pasting. It saves everyone time in the long run. :) > > Thanks again! > > > > Nathan wrote: > > > To do this you need to have "return this.each" and optionally change > > the instance of "this" which is the name of the object you are apply > > the plugin to, to "obj" using "var obj = $(this);". > > > Then when you call a selector, you'll need to add "$('#nav a', obj)" > > note the ", obj". > > > This will keep it within the name space of what ever selector you > > apply this to when the plugin is initialize. > > > (function($){ > > $.fn.extend({ > > plauginNameHere: function() { > > return this.each(function() { > > var obj = $(this); // this just changes the use > > of 'this' to obj > > > $('#nav a', obj).click(function(){ > > $('#someDiv').fadeIn(); > > }); > > > }) > > } > > }); > > })(jQuery); > > > On the page level you will then need to initialize the plugin on the > > HTML page level. > > > > > $(function(){ > > $('#divNameHere'). plauginNameHere(); // first instance > > $('#secondDivNameHere'). plauginNameHere(); // second instance > > }); > > > > > So what ever the selector name is above, for example > > "#secondDivNameHere", will then be the 'this' that we changed to 'obj' > > using a var in plugin script. So in this example the plugin's "obj" is > > "#secondDivNameHere". > > > Let me know if that helps. > > > On Apr 6, 1:44 pm, Spot wrote: > > >> How would one develop a plugin which can exist multiple times on the > >> same page, without conflicting with each others namespaces?
[jQuery] Re: Plugin Development
Nathan, first off, thank you for responding. I understand about passing the obj as scope. That makes perfect sense. However I am a little confused as to the purpose of returning this.each. What is the goal there? I find it better to understand why something works, as opposed to just copy/pasting. It saves everyone time in the long run. :) Thanks again! Nathan wrote: To do this you need to have "return this.each" and optionally change the instance of "this" which is the name of the object you are apply the plugin to, to "obj" using "var obj = $(this);". Then when you call a selector, you'll need to add "$('#nav a', obj)" note the ", obj". This will keep it within the name space of what ever selector you apply this to when the plugin is initialize. (function($){ $.fn.extend({ plauginNameHere: function() { return this.each(function() { var obj = $(this); // this just changes the use of 'this' to obj $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }); }) } }); })(jQuery); On the page level you will then need to initialize the plugin on the HTML page level. $(function(){ $('#divNameHere'). plauginNameHere(); // first instance $('#secondDivNameHere'). plauginNameHere(); // second instance }); So what ever the selector name is above, for example "#secondDivNameHere", will then be the 'this' that we changed to 'obj' using a var in plugin script. So in this example the plugin's "obj" is "#secondDivNameHere". Let me know if that helps. On Apr 6, 1:44 pm, Spot wrote: How would one develop a plugin which can exist multiple times on the same page, without conflicting with each others namespaces?
[jQuery] Re: Plugin Development
To do this you need to have "return this.each" and optionally change the instance of "this" which is the name of the object you are apply the plugin to, to "obj" using "var obj = $(this);". Then when you call a selector, you'll need to add "$('#nav a', obj)" note the ", obj". This will keep it within the name space of what ever selector you apply this to when the plugin is initialize. (function($){ $.fn.extend({ plauginNameHere: function() { return this.each(function() { var obj = $(this); // this just changes the use of 'this' to obj $('#nav a', obj).click(function(){ $('#someDiv').fadeIn(); }); }) } }); })(jQuery); On the page level you will then need to initialize the plugin on the HTML page level. $(function(){ $('#divNameHere'). plauginNameHere(); // first instance $('#secondDivNameHere'). plauginNameHere(); // second instance }); So what ever the selector name is above, for example "#secondDivNameHere", will then be the 'this' that we changed to 'obj' using a var in plugin script. So in this example the plugin's "obj" is "#secondDivNameHere". Let me know if that helps. On Apr 6, 1:44 pm, Spot wrote: > How would one develop a plugin which can exist multiple times on the > same page, without conflicting with each others namespaces?
[jQuery] Re: plugin development
http://www-128.ibm.com/developerworks/library/x-ajaxjquery.html - Original Message - From: "phpLord" <[EMAIL PROTECTED]> To: Sent: Tuesday, April 17, 2007 7:55 PM Subject: [jQuery] plugin development Hi; do you know any guide about plugin development except the documentation wiki page ? like a tutorial on a simple plugin? tHanks
[jQuery] Re: plugin development
I've got a tutorial here that might help: http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/ It's simple in that it's a reusable plugin, but it doesn't have any logic outside of the 'each' loop - which is where you can really beef up the power of your plugin. I'm sure there will be other examples the community can offer, otherwise I'll knock up a quick tutorial. Good luck.