Purr – a MooTools notifications / alert class.

I have written up a notifications / alert class for a recent project and thought I would share it. Too much to go into in a post, so there is a big page for it here.

Before anyone brings it up, this is not yet in the MooTools Forge, but it will be soon assuming I don’t become distracted by something else…

trackback

Tags: , , no responses »

Leave a Reply

ok to use:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

bonus!

If you want to post code, you can use:

<pre lang="[language]">[code]</pre>

Where [language] is a valid geshi language type, and where [code] is your code.

MooTools Tips extension: Tips.Glossary

This is just a little something I whipped up because I found it useful. Tips.Glossary is used for helpful tool-tips that gracefully degrade when JavaScript is not available for whatever reason. The basic idea is that you include an HTML glossary in the page, and if Tips.Glossary is available, the tips will come up however you specify, if not, they are simply anchors to their entries in the HTML.

This probably works with most MooTools stuff post 1.2, you are smart and will figure it out.

Check it out here.

Download the example.

or have a look at the code:

Selectors.Pseudo.hash = function(hash){
	if(!$chk(hash))
		return this.get('href').contains('#');
	var currentHash = this.get('href').split('#')[1];
	return currentHash === hash;
}
 
 
Tips.Glossary = new Class({
 
	Extends: Tips,
 
	options: {
		'anchorClass':	false,
		'hideGlossary':	true
	},
 
	initialize: function(glossary, options){
		this.parent(options);
		this.glossary = $(glossary);
		if(!$chk(this.glossary))
			throw "Glossary not found / defined, quitting";
		if(this.options.hideGlossary)
			this.glossary.setStyle('display', 'none');
		this.indexGlossary();
		return this;
	},
 
	indexGlossary: function(){
		this.items = this.glossary.getElements('*[id]');
		this.anchors = new Elements();
		this.items.each(function(e){
			var anchor = $(document.body).getElement('a:hash('+e.get('id')+')');
			if($chk(anchor)){
				if(this.options.hideGlossary);
				anchor.addEvent('click', function(event){
					new Event(event).stop();
				});
				this.setTipContent(anchor, e);
				this.anchors.push(anchor);
			}
			if(this.options.anchorClass)
				this.anchors.addClass(this.options.anchorClass);
			this.attach(this.anchors);
		}, this);
	},
 
	setTipContent: function(anchor, target){
		anchor.store('tip:title', target.get('title'));
		anchor.store('tip:text', target.get('html'));
		this.fireEvent('settingContent', [anchor, target]);
	}
 
});

On a side note, notice the psuedo selector being added. This has been added because for whatever reason, the following CSS3 selector is goofy:

$(document.body).getElements('a[href="http://trickeries.com"]'); // works
$(document.body).getElements('a[href="#glossary-username"]');    // does not work

Anyone have any idea why?

trackback

Tags: , , , 1 response »
  1. khela's gravatar

    Nice work :)

Leave a Reply

ok to use:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

bonus!

If you want to post code, you can use:

<pre lang="[language]">[code]</pre>

Where [language] is a valid geshi language type, and where [code] is your code.

rAccordion – a MooTools 1.2 recursive accordion

So I have managed to create a recursive mootools accordion, which is something I have wanted to get done for a long time.

The secret ingredient to get this made up was some CSS3 selectors and a bit of recursion.

You basically just pass in a class for the toggles, a class for the elements, and a parent container to reference.

The usage ends up fairly simple:

new rAccordion('container', 'toggle', 'element');

In the example, container is the id of the parent that the classes are in, toggle is the class that each toggle has, and element is the class that each element has. A fourth argument can be passed, which is the options argument for the mootools Accordion class.

There are some kinks thatstill need working out. There are inherit problems with just jamming accordions inside of each other. The way mootools creates the accordion requires quite a bit of inline styles, which include defined heights. These heights become problematic when accordions inside accordions need to expand or contract, but their parent element has a defined height and overflow which will not allow the newly expanded portion to be seen.

I do have something of a solution in place, but it feels a little hacky, but I am not sure it will get any better unless I rewrite the accordion.

If anyone has any ideas on how to address this issue, please drop me a comment.

example

download w/the example

Here is the class:

var rAccordion = new Class({
 
	initialize: function(container, toggleClass, elementClass, options){
		this.container = container;
		this.tClass = toggleClass;
		this.eClass = elementClass;
		this.options = options;
		this.selector = '#' + this.container + ' > .';
		this.makeAccordion();
	},
 
	makeAccordion: function(){
		new Accordion(
			$$(this.selector+this.tClass),
			$$(this.selector+this.eClass),
			this.options
		).addEvents({
			// The onActive and onComplete events added to the stack here to
			// attempt to address some of the css issues.
			'onActive': function(toggle){
				if(toggle.getParent().getStyle('height') != 0)
					toggle.getParent().setStyle('height', '');
			},
			'onComplete': function(a){
				if ($defined(a)) {
					var height = 0;
					a.getParent().getChildren().each(function(e){
						height = height + e.offsetHeight;
					});
					if(height != a.getParent().offsetHeight && a.getParent().offsetHeight != 0)
						a.getParent().setStyle('height','');
				}
			}
		});
		this.selector += this.eClass + ' > .';
		if($defined($$(this.selector)[0]))
			this.makeAccordion();
	}
 
});

trackback

Tags: , , , , , 19 responses »
  1. Daniel Buchner's gravatar
    Daniel Buchner Says:

    I think a cure for you overflow ailment with slide/accordion might lie in an ‘extend’ of the class. This is a great way to let Fx.Slide do overflow auto (it is set to hidden automatically too, annoying!), for refrence:

    http://we.designandco.de/2008/06/10/mootools-fxslide-flicker-bug/
    http://we.designandco.de/2008/06/20/mootools-fxslide-flicker-bug-ii/

    I am not sure if internally Accordion is dependent on Slide for its actions, but anyhow, ‘extend’ use could give you the option I believe that you desire without actually rewriting the Accordion class.

    This script is well done, I’ll be using it in the next few days, thanks!

    - Daniel

  2. atom's gravatar

    @Daniel, the accordion class does not use Fx.Slide, but rather is extending the Fx class directly. I read it over and I think there are some clues to how to fix this, so I will be investigation those further.

  3. @atom's gravatar

    Hi atom, thanks for this great script.
    I’m trying to save the active state via cookie, but I don’t get it to work.

    Is it possible to make the menu stay open at a certain place when invoked? (ie. if you opened the first nest and clicked an item, when you went to its page, the menu would stay open at that item)

    This would really help for knowing where you are on a website if this menu was used on it

  4. atom's gravatar

    My first though is no, mostly because this is intended to work with however many accordions you have.

    However, it can probably be done without too much work, so I will probably have a look at it and see what I can do without making this too complicated.

  5. Thorsten's gravatar

    Hi there, just a little short question: what would a piece of extra code look like, to use a mouseover event for the accordion instaead of a click??

  6. atom's gravatar

    @Thorsten,

    It wouldn’t be too difficult really, but you would have to work with the actual Accordion class that this is utilizing.

    After creating the accordions, you would need to add a mouseover event to each toggler bound to the accordion’s display function, and remove the click events.

  7. Thorsten's gravatar

    @atom,

    well, I’m not so good with js but a friend helped me out. Last question: do I have to change your js in order to use plain list elements (ul li)?? I tried that with the same names for the classes but nothing was working. Maybe I’m too stupid. Could you help me out?

  8. Janies's gravatar

    Hi there, I’m learning to work with mootools and This example is exactly what I have tried to achieve for the past 1 week but to no avail! Thanks for sharing this!

    There are two problems that I’ve encountered while working with the script.

    1. The expanding and collapsing is not consistent. sometimes the whole menu collapse and sometimes it doesn’t.

    2. changing the css style of the 2nd class of toggle. For eg.

    Toggle 1
    > Toggle 2
    > element 3
    > Toggle 2a

    I have tried to play around with the script but i can’t change the style of Toggle 2 or Toggle 2a.

    Any idea if question 2 can be fixed?

    Thanks!

  9. Janies's gravatar

    Toggle 1
    >> Toggle 2
    >>>> Element 3
    >> Toggle 2.a
    >>>> Element 4

    After posting the above post, i realised the indent is omited. To prevent confusion, here is what i meant of the toggle 2.

  10. liv's gravatar

    hi atom thanks for the great script.

    I am also trying to get the menu to stay open when invoked. has this been developed? I have been trying out some if statements within the raccordion definition (creating a class “current” and then having the display option depend on it) without any luck.

  11. yolanda's gravatar

    Hi, I’m also trying to get the menu to stay open. Has anyone had any luck?
    Also can’t change the active style of the second level.
    Thanks

  12. Justino A. Arciga Jr.'s gravatar

    Hi,
    I have some problem with the height. When it firts load the page the height of the first accordion did not wrapped exactly with the content it hide it. what is the solution or workaroud can i do with this problem.

    Thanks for any help!

    jR.

  13. Alex K's gravatar

    @atom, thank you very much for this! I am in dire need to get the active state working! Please email me if you have implemented it. Thank you!

  14. NAD*'s gravatar

    @with script to close all sub-levels

    var rAccordion = new Class({
     
    	initialize: function(container, toggleClass, elementClass, options){
    		this.container = container;
    		this.tClass = toggleClass;
    		this.eClass = elementClass;
    		this.options = options;
    		this.selector = '#' + this.container + ' &gt; .';
    		this.list_acc = new Array();
    		this.acc_index = 0;
    		this.h = (window.ie6) ? "100%" : '';
    		this.makeAccordion();
     
    	},
     
    	makeAccordion: function(){
    		this.list_acc[this.acc_index] = new Accordion(
    			$$(this.selector+this.tClass),
    			$$(this.selector+this.eClass),
    			this.options 
    		)
     
    		this.list_acc[this.acc_index].list_acc = this.list_acc;
    		this.list_acc[this.acc_index].acc_index = this.acc_index;
    		this.list_acc[this.acc_index++].addEvents({
    			// The onActive and onComplete events added to the stack here to
    			// attempt to address some of the css issues.
    			'onActive': function(toggle){
    				for(i=this.acc_index+1; i  .';
    		if($defined($$(this.selector)[0]))
    			this.makeAccordion();
    	}
     
    });
  15. NAD*'s gravatar

    @sorry…

    - this.h = (window.ie6) ?100%:;
    + this.h = (window.ie6) ?100%: "";
  16. NAD*'s gravatar

    @v1.0.545 – lol

    ok… the code are not completed.

    the difference are:

    /* on initialize and before this.makeAccordion */
    this.list_acc = new Array(); /* list of accordion levels */
    this.acc_index = 0; /* accordion level index */
    this.h = (window.ie6)?"100%":""  /* bug ie6 */
     
     
    /* at makeAccordion, put list_acc and acc_index into accordion scope */
    this.list_acc[this.acc_index] = new Accordion(...);
    this.list_acc[this.acc_index].list_acc = this.list_acc;
    this.list_acc[this.acc_index].acc_index = this.acc_index;
    this.list_acc[this.acc_index++].addEvent(
       onActive: (...)
       onComplete: function(a){
          (...)
          for(i=this.acc_index+1; i &lt; this.list_acc.length; i++)
             this.list_acc[i].display(-1,true);
       }
    });

    Good work!

  17. TMG's gravatar

    Very slick looking. Is it possible to have more than one element per toggle? It’s breaking it when I try.

  18. 济南二手房's gravatar

    济南二手房(esf.jnol.cn)网来博客参观过了,呵呵,有空多多交流哈。

  19. 小区's gravatar

    很不错的博客哦,来过踩踩,欢迎回访~

Leave a Reply

ok to use:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

bonus!

If you want to post code, you can use:

<pre lang="[language]">[code]</pre>

Where [language] is a valid geshi language type, and where [code] is your code.

Queuing ajax requests with MooTools 1.2

UPDATE: This might be sorta useless. Please see this comment.

There have been a variety of occasions where I only want one instance of the Request object, but want to make sure that every request I attempt gets run without canceling another, or screwing around with onCompletes.  The following is a rather simple implement that takes care of this problem:

Request.implement({
    queue: function(sendArg){
        if(!$defined(this.queued))
            this.queued = [];
        this.queued.push(sendArg);
        this.processQueue();
    },
    processQueue: function(){
		if(this.timer)
			$clear(this.timer);
		if (!this.check())
			this.timer = this.processQueue.delay(250, this);
		else {
			if ($defined(this.queued[0])) {
				this.send(this.queued.shift());
				this.processQueue();
			}
			else
				this.fireEvent('onQueueEmpty');
		}
    }
});

This will basically stack requests and send them in the order received. If there is no stack, the request will be sent immediately.

The usage is the same as the normal Request send method, however there is now an onQueueEmpty event to tell when all requests in the queue have been sent.

example

download w/the example

trackback

Tags: , , , , , 7 responses »
  1. keif's gravatar

    Very, very useful, I was working on something similar.

  2. atom's gravatar

    @keif: i agree =)

    I am pretty surprised that something like this hasn’t made its way into the core yet.

  3. adamnfish's gravatar
    adamnfish Says:

    The request class in mootools 1.2 already includes chaining!

    The check method allows you to queue, cancel or ignore requests while there is already a request running (identical to the Fx classes) depending on the option you provide. (look at the source!)

    So to do this, you don’t need to add any code (ie @atom, it is already in the core…)

    Simply provide {link: ‘ignore’ | ‘chain’ | ‘cancel’} as required. The default is ignore, so you won’t have seen it and I’ve no doubt it’s not documented yet…
    *rolls eyes

    Honestly, since the forums were shut this sort of thing seems to be happening a lot.

    To implement ‘onChainComplete’ (like you did for the queue), just add an event to onSuccess that checks the length of the chain ;)

    ps. I *Adore* your design…

  4. atom's gravatar

    @adamnfish you are absolutely correct =)

    My implement is indeed useless. It is not in the documentation, but setting ‘link’:'chain’ does work to chain/queue requests.

    After testing I think I have either discovered a MooTools bug, or a Firebug bug, or some other manner of oddity. When using ‘link’:'chain’, I am not seeing a response logged in Firebug, however the response does exist, as I can still use it when passing to the onSuccess function.

    So, uh, someone look into that or something.

  5. paddo's gravatar

    “When using ‘link’:’chain’, I am not seeing a response logged in Firebug, however the response does exist, as I can still use it when passing to the onSuccess function.”

    Same here, firebug doesn’t show the request until it’s already done. And when it’s done, it tells me that it only took 1ms (which can’t be true, I’ve put a sleep(2) in my php). Odd, odd, odd… link: ‘chain’ however works like a charm! I hope they’ll update the docs soon.

  6. atom's gravatar

    it looks like someone else thought thinks queueing needs a little help, however his is mroe useful and doesn’t just stack, which you can already apparently do:

    http://www.clientcide.com/code-snippets/ajax/new-plugin-requestqueue/

  7. diancitie's gravatar

    Great article.Thanks.

Leave a Reply

ok to use:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

bonus!

If you want to post code, you can use:

<pre lang="[language]">[code]</pre>

Where [language] is a valid geshi language type, and where [code] is your code.

Sortable Slideable Saveable – a Mootools 1.2 class

Sortable Slideable Saveable (sss) is a class I wrote up that allows you to have a list of elements that can be sorted, toggled, and the state of each will be saved each time a change is made, either using a cookie or a couple of ajax / json calls.

It can be seen in action in my sidebar to the right. You can drag / sort them by dragging the icons, and you can toggle them by clicking on the title of each. Any changes you make will be stored in a cookie, you can reload the page and they should be in the state you left them in.

I will probably update this and provide some detailed documentation shortly. If anyone has any questions, let me know. Also if anyone has any input on how to make it better, let me know.

another example

download w/the example

trackback

Tags: , , , , 13 responses »
  1. keif's gravatar

    Your side bar isn’t working for me (OS X, FF3.0.1) but your other example works flawlessly.

    Very cool script, and I love that it’s default state works with JS off.

  2. atom's gravatar

    hmm, i guess someone is going to have to let me borrow a mac :p

  3. links for 2008-07-30 | iKeif – mootools, jquery, social media and a ton of links's gravatar

    [...] Guide to Earning Six Figures: Changing Your Mind 13 hours agoInformation about going free lance.trickeries! » Blog Archive » Sortable Slideable Saveable – a Mootools 1.2 class 14 hours agoVery cool mootools 1.2 class for slideable sortables that are savable via cookies!The [...]

  4. keif's gravatar

    WEEELLL I could play around with it a bit and see if I can figure it out (or if it’s just FF# acting buggy).

  5. atom's gravatar

    It is a little odd that there is a difference in FF between systems, I would like to assume the engines in use would be exactly the same, however I have already seen stupid differences in the rendering of styles between the two. My assumption is that it is just a goofy issue with CSS.

  6. Tyler's gravatar

    brilliantly executed, as usual.

  7. atom's gravatar

    ^ _ ^

  8. electronbender's gravatar
    electronbender Says:

    Chief,
    Can you add a nested ability to this thing? That would realyyyyy be nice…

  9. Rob C's gravatar

    Hi,

    The ’savable’ side of things doesn’t seem to work on your example (the one linked here, and the one downloaded).

    I can see the PHP code at the top, but how does one implement the save?

    Thanks!

  10. atom's gravatar

    @Rob, What I have there in the example is just a quick and dirty example using sessions. In order to have this saved in any meaningful sense you are going to need to write / read the state to and from somewhere.

  11. dakota's gravatar

    Could this be modified to support dragging to multiple columns?

  12. dakota's gravatar

    How can I style the drop areas to have a dotted border? by this I mean when dragging one, how can I get the areas I can release it to to have a border… I’ve been trying to have it add a class, but can’t figure out where in the sss code to add it.

  13. Guillem's gravatar

    Hi,

    I there a way to use your amazing script with multiple list in order to mix them together?
    I tried to do this that way:
    window.addEvent(‘domready’, function(){
    new sss(‘#list, #list2′, ‘.toggle’, ‘.box-content’);
    });

    But mootools return an error at line 115 in sss.js.
    Do you think you can fix that? If you want I can give you some bucks for it (using paypal)

    Thanks a lot.

Leave a Reply

ok to use:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

bonus!

If you want to post code, you can use:

<pre lang="[language]">[code]</pre>

Where [language] is a valid geshi language type, and where [code] is your code.