Tobiasz Cudnik

Posts Tagged ‘jquery’

QueryTemplates development progress

In QueryTemplates on 01.03.2009 at 1:06

QueryTemplates 1.0 Beta3 is out since a week or so and next release is around the corner, so i decided to do some wrap-up of latest facts in library development:

  • Extended data targets are no supported by all methods. This means each method can be re-targeted with jQuery insert methods like for example varsToSelectorBefore or even varsToSelectorAttr.
  • New codeTo method type. It simply injects code groups. Idea evolved from methodTo approach, which would inject method calls. I find codeTo amuch more flexible and useful, but it can be less readable.
  • New valuesToLoop method. In opposite to varsToLoop aka loop(), it will iterate existing data over DOM structure and commit it right away. This has less purpose on server side (but can be useful), but it’s essential on the client-side when you don’t want to make a server request.
  • New conditional chains methods – onlyJS() and onlyPHP(). They allow to highly customize template for certain language. For example, everything between onlyPHP() and endOnly() will be applied only to PHP template, even when the same chain is used to create JS template.
  • Light version for JavaScript is available. It contains all valuesTo methods which includes valuesToSelector, valuesToStack and valuesToLoop. Form methods and mutation events support will be next. It’s a jQuery plugin and demo is available.
  • formFromVars will generate full form templates from structure and variable informations. Such form supports error messages and default values. Of course input-wrapper template is customizable. As for today there are couple of things to be done in this area and formFromValues will also be available soon.
  • Syntax reference is complete. Each method has it’s own wiki page with 6-part example: markup, data, formula aka code, template, tree dump before and tree dump after. Also, new JavaScript Light version is included in this reference. User comment are allowed. Personally i think it’s the best part of project’s page ;)
  • Some API refactorings had taken place. Old names are still accessible, but marked as deprecated.
    • varsFrom type was created from such methods as saveTextAsVar, saveAsVar, valuesToVars.
    • loop, loopOne and loopSeparate now becomes varsToLoop, varsToLoopFirst and varsToLoopSeparate and are grouped in ToLoop type.
  • dumpTree is now more verbose and can be used both via HTML and plain text. Just do ->dumpTree() anywhere in the chain to see readable representation of selected structure. It’s used for syntax reference examples.

As you can see project is quite close to 1.0 final. Code seems stable and each method has pseudo-unit-test in form of example available in Syntax reference, which is generated as a real template. I just can’t wait to start implementing CSS interface i wrote before. Additionaly, as JavaScript version is out, there can be some use for jQueryServer.

Can CSS stylesheets be applied on the server-side ?

In Ideas, QueryTemplates, Workflow on 27.01.2009 at 3:23

The question is: can CSS stylesheet be applied in the server-side ? And if yes, would would be the purpose ? I should say yes, they can and i would explain how and why. So what for are stylesheets ? “Applying cascading styles onto the DOM” may be the answer. But i would focus more on that why actually stylesheets are used for such purpose?

  • Because they are clean ?
  • Because CSS selectors do so much job, that besides them only really needed things are simple properties with obligatory number of arguments ?
  • Because cascading inheritance is just right for the DOM ?
  • CSS selector are simply benefiting from DOM structure’s nature

So first thing which needs to be implemented on the server is the DOM. When we already got it, so we can query it thou selector, that’s the first half. Now the properties. What could be the property on the server ? border-color ? Rather not. Do we need to style the DOM on the server ? Is it shown anywhere ? Not right now. On the server, page’s DOM is being build. Typically by various ways of string concatenation.

So if we need to build a DOM and same time we can query it with selectors, then the style’s properties should build / modify it’s structure. For example, show some articles or blog posts on the page. So here is pure CSS parser-validable code with some proposed server properties.

.section.articles ul > li {
  /* loop "articles" variable as "article" using "num" as index
  after that remove all other-than-first LIs */
  loop-one: articles num article;

  /* apply filter method on next variable output */
  vars-filter: htmlentities;

  /* use "article" fields and populate them inside nodes
  matched by ".a-%k" where %k is field name, eg .a-title */
  vars-to-selector: articles var(articleFields) null ".a-%k";

  /* example custom method to adding class for 1st loop node using index "num" */
  add-class-to-first: num custom-class;
}
/* show .comments node if variable articleComments is true */
.comments {
  if-var: articleComments;
}
/* bubbled event */
.section.articles:inserted {
  /* another custom method */
  /* null means 0 arguments */
  strip-tables: null;
}

So what have we done here ?

  1. We simply build articles loop which prints it’s contents into proper child nodes automagically. It could have 3 fields or 345, but line in CSS is only one.
  2. We’ve also used a custom method do add class basing on the loop position.
  3. Comments presentance is conditional.
  4. One Mutation Event is used. Hidden in :insert pseudoclass, really named DOMNodeInserted will apply on all new nodes which matches prior selector and were just inserted into the DOM structure.
  5. Each unspecified event defaults to :load.

All properties should be simply methods which applies something on all matched nodes. Sound familiar ? That’s exactly what many of jQuery methods are doing. Take a look:

.section.articles {
  remove-class: section;
  attr: rel section;
  /* all css properties can be used
  but will result in inline "style" attributes */
  css: padding 2px;
}
/* this rule applies to all load-time nodes
and the new one too */
.change-me,
.change-me:inserted {
  text: "changed innerText";
  prepend: "
<div>changed</div>
";
  remove-class: change-me;
  /* reallocation, interesting... */
  insert-into: ".content";
  /* passing some data to forward ? */
  data: some-flag "some value for developer";
}

All from above properties are jQuery methods. Possibilities are huge. But let’s stick with simple things right now. How would it benefit ? Who will write those server-css-sheets ? I should say…

Read the rest of this entry »

Utilizing Mutation Events for automatic and persistent event attaching

In Ideas, Snippets on 19.01.2009 at 19:43

Most of you probably heard about Event Delegation, a technique where you bind to event of interest on parent node and when triggered event bubbles from child node, action in taken inside the parent. This pattern is widely popularized by reglib and Live Query (plugin for jQuery). Newly released jQuery 1.3 has it’s own implementation thou $.live() method.

This patten has couple of advantages over classic attaching model. First, it’s faster for BIG number of (same) nodes. Secondly, which is most important i think, it allows easy content exchange via AJAX. But with all that it has also disadvantages and main is that you doesn’t really attach to a node, only to it’s parent. That means when you relocate node in the DOM it looses it’s behavior.

That’s why i’ve came with the idea of using Mutation Events to take best parts from both patterns. Mutation Events aren’t supported in IE, but i’ve rolled out some compatibility layer to target this problem. Works also with document fragment appends introduced in jQuery 1.3.

You can go straight to the demo, which was tested and works with:

  • Firefox 3 and 2 linux
  • IE6 SP2 win32
  • Opera 9.63 linux
  • Safari 3.6 win32
  • Chrome 1.0 win32

First lets see main code:

function attachEvents(node) {
	// node is an optional callback for filter()
	// that applies rules only for new nodes
	node = node || '*';
	$('.container1 .trigger1').filter(node).click(function(e) {
		alert('mutation events work');
		e.preventDefault();
	});
}

This is simple, common function that applies behaviors to the document. The only major difference from other such functions is node parameter, used as callback for filter() method, which limits found nodes to interesting ones. Now the actual event bindings:

// node inserted into DOM
$(document).bind('DOMNodeInserted', function(e) {
	attachEvents(function(node){
		return !e.target.skipEventAttaching &&
			this == e.target
	});
});
// node removed from DOM
$(document).bind('DOMNodeRemoved', function(e) {
	// add information property, that node has been detached
	e.target.skipEventAttaching = true;
});

Here the magic happens ;) First handler fires up our event attaching function with callback for filter as a parameter. Callback will check if found node is target of the mutation event or is it reinserted. Second handler adds flag about reinserting.

You can see demo which compares this technique with jQuery 1.3 and reglib. It consists of 3 different implementation:

  • jQuery 1.3 using Mutation Events
  • jQuery 1.3 using $.live
  • reglib

Test it like this: click add node (couple of times), click .trigger (first one, last one) then do move node and again click moved node. Each time when clicking on .trigger, one (and only one) alert should pop out saying that certain technique works.

Additionally there’s a IE compatibility for mutation events in conditional comment. Great help writing it was from ieproto example.

Of course this is proof-of-concept and souldn’t be used in production until fully tested and fixed.

Having fun using PHP 5.3 closures with phpQuery

In phpQuery on 08.01.2009 at 16:34

Some time ago i’ve wrote about new PHP 5.3 closures feature. Today i would like to show you it in action with phpQuery. If you’re using jQuery you will feel like in home :)

First example illustrates classic inline function, which is used to iterate over li nodes, incrementing each one’s content.

$markup = '
<ul>
	<li>1</li>
	<li>2</li>
	<li>3</li>
</ul>
';
$doc = phpQuery::newDocument($markup);
$doc['li']->each(function($node){
	pq($node)->text(
		pq($node)->text()+1
	);
});
print $doc;

Result will be someting like this (something because i’ve corrected indentation manually).

<ul>
	<li>2</li>
	<li>3</li>
	<li>4</li>
</ul>

Now more complicated stuff – scope inheritance. Scope inheritance means nothing else than ability to use variables declared outside code block (inline function in this case) inside this particular block. In JavaScript we have full inheritance right away. In PHP 5.3 we have to explicitly declare which variable we would like to inherit. It’s done by use keyword.

$markup = '
<div>
	<span>1</span>
	<span>2</span>
	<span>3</span></div>
<div>
	<span>1</span>
	<span>2</span>
	<span>3</span></div>
';
$doc = phpQuery::newDocument($markup);
$doc['div']->each(function($div){
	$div = pq($div);
	$div['span']->each(function($span) use ($div){
		pq($span)->insertBefore($div);
	});
});
print $doc;

We’ve nested one closure inside another. The inner one inherits $div variable from the outer. Lack of such feature for create_function was really problematic. Below you can see the result. Both divs are now empty.

<span>1</span>
<span>2</span>
<span>3</span>
<div></div>
<span>1</span>
<span>2</span>
<span>3</span>
<div></div>

Third example i want to show is about assigning inline function to a variable. It’s handful technique to avoid namespace collisions and of course allow easily pass closure thou the parts of code.

$markup = '
<div>1</div>
<div>2</div>
<div>3</div>
';
$callback = function($node){
	$node = pq($node);
	$node->text(
		'Callbacked: '.$node->text()
	);
};
print phpQuery::newDocument($markup)
	->find('div')->each($callback)->end();

Just how you suspect, every node’s content will be prefixed with “Callbacked: “.

<div>Callbacked: 1</div>
<div>Callbacked: 2</div>
<div>Callbacked: 3</div>

I think that this post clearly illustrates how closures work and that they are important for PHP as web development language.

If you would like to test code from this post and PHP 5.3 in general, download windows build from php.net or compile source yourself for other platform. CLI version will be enough, that means no apache module struggling.

QueryTemplates finally released

In QueryTemplates, plainTemplates on 03.12.2008 at 16:47

I’ve finally managed to release QueryTemplates, a pure HTML templating engine i’ve been working past months. There’re extensive examples which should allow anyone to easily understand the idea. Previously posted Pure HTML templates theory sums up some thoughts about this templating pattern. You can read more about new library on the wiki and there’s also an official blog. Feel free to post feedback.

jQuery Server Side ports

In The Net on 01.11.2008 at 11:03

jQuery besides achieving such successes as being used by Google or Micro$soft also has ports to other major languages. Most of them are designed to be server-side what opens doors for new uses to the library.

jQuery ports to other languages:

Below some snippets showing each implementation in few lines.

PHP

foreach($doc['ul > li'] as $li) {
  pq($li)->addClass('my-new-class');
      ->filter(':last')
        ->addClass('last-li');
}
$doc['ul > li:last']
  ->addClass('last-li');

Ruby

# load the RedHanded home page
doc = Hpricot(open("http://redhanded.hobix.com/index.html"))
# change the CSS class on links
(doc/"span.entryPermalink").set("class", "newLinks")

Perl

pQuery("http://google.com/search?q=pquery")
  ->find("h2")
    ->each(sub {
      my $i = shift;
        print $i + 1, ") ", pQuery($_)->text, "n";
      });

ActionScript

// add enterFrame event handler
$(stage).enterFrame(function(event:Event):void {
  $("RoundRect").attr("color", function(...args):uint {
    return Math.random() * 0xffffff;
  });
});

List comes from phpQuery wiki page. Do you know any other ports ? Share it in comments.

Update 09.12.08
New jQuery port has been released. This time it’s powered by Python and named PyQuery. Here’s the code:

Python

p = d("#hello")
p.addClass("toto")
p.attr.id = "plop"
p.prependTo(d('#test'))

$.include() – script inclusion jQuery plugin

In Snippets on 01.08.2007 at 11:11

Don’t like writing <script> tag for every new JS You need ? Nobody likes. Thats why i wrote $.include.

Use it like this:

$.include('js/my-script.js');

It’s similar plugin to that one written by Petko D. Petkov, but with couple of enhancements :

  • Properly delayes onDomReady event
  • Gives You control over order of loading scripts

Here is extended example:

$.include(
	// URL
	'js/my-script.js',
	// will be loaded after this script
	$.include(baseURL+'js/my-other-script.js')
);
$.include('js/src/behaviors.js',
	// dependencies can also be an array
	[
		$.include('js/src/jquery-metadata.js'),
		$.include('js/src/jquery.form.js')
	]
);

Read the rest of this entry »

Smooth Menu widget for jQuery

In Snippets on 31.07.2007 at 11:08

If You liked Fancy Menu, but not necessarily feel the same to moo.tools (no offence) here You have similar widget for jQuery – Smooth Menu. It works for vertical lists too.

Examples are bare so it’s easier to understand whats needed to implement it to your site. Love to see it in combination with rounder corners (imageless).

phpQuery – a jQuery port to PHP

In phpQuery on 07.07.2007 at 10:56

This post is deprecated and some informations below are outdated.

phpQuery is PHP-port of jQuery – well known and great web2.0 JS library

It’s something different than jQPie, which is form of JS code generator and server-client layer.

For example You can do something like this:

print _('file.htm')
    ->find('body div.cls1.cls2 ul > li:first')
        ->parent()
            ->prepend('
	<li>my new first LI</li>
')
            ->parents('.myClass')
                ->remove()
                ->end()
            ->appendTo('body')
            ->parents('html')
                ->html();

Code above will find first LI inside specific UL, then move pointer into it’s parent (UL),
then prepend (add at the beginning) new LI, then pointer will move to parent element with class .myClass,
which will be removed, and pointer will go back to UL (with end() method), and then UL will be appended to BODY (moved, not copied).
Atfer all this operations parent with tag HTML will be searched and it’s content will be returned to print statement.

phpQuery acts almost like jQuery – it returns new instance on certain methods and allows to revert stack.

It works on DOM Extension and is designed for PHP5 only.

There is almost no docs yet, so please refer to jQuery’s one (DOM section).

Difference against jQuery

phpQuery differs in some cases from jQuery:

  1. Iteration
  2. Callbacks
  3. No DOM nodes
  4. In some method names (PHP reserved words)
  5. PHP specific addons
  6. Other addons

Iteration

phpQuery makes use of PHP’s SPL Iterator interface, so You can do:

foreach(_('ul>*') as $_li) {
	$_li->prepend('new beginning of every LI');
}

Callbacks

PHP doesn’t have closures, but You can still use callbacks – direct or created with create_function() like so:

function imTheCallback($_node){
	$_node->html("i'm changed content");
}
class imTheClass {
	static function imTheStaticCallback($_node){
		$_node->html("i'm changed content v2");
	}
	function imTheCallbackToo($_node){
		$_node->html("i'm changed content v3");
	}
}
$class = new imTheClass;
_('ul>*')
	.each('imTheCallback')
	.each(array('imTheClass', 'imTheStaticCallback'))
	.each(array($class, 'imTheCallbackToo'))
	.each(create_function('$_node', '
		$_node->html("i\'m changed content v4");'
	));
}

No DOM nodes

Every node passed to callback or inside iteration is phpQuery object, not a DOM node. Also there isn’t a get() method.

Method names

There are several methods in jQuery’s interface with names which couldn’t be used as PHP class method or was changed to preserve consistent naming convention.

All those methods have been prefixed with _underscore and here’s the list:

  • _clone
  • _next
  • _prev
  • _empty

PHP specific addons

There are couple of PHP specific addons in phpQuery for easier developement:

  • appendPHP($code) – equals to append(<?php $code ?>)
  • prependPHP($code) – equals to prepend(<?php $code ?>)
  • beforePHP($code) – equals to before(<?php $code ?>)
  • afterPHP($code) – equals to after(<?php $code ?>)
  • attrPHP($attr, $code) – equals to attr($attr, <?php $code ?>)
  • php($code) – equals to html(<?php $code ?>)
  • phpPrint($code) – equals to html(<?php print $code ?>)
  • phpMeta($selector, $code) – equals to find($selector)->php($code)->end()
  • __toString() – equals to htmlWithTag()

Other addons

There is/will be several methods not present in standard jQuery, which i use (with jQuery) in my projects. More about this later.

Development status

Actually phpQuery seems to be quite stable and is main part of plainTemplates lib, which powers this blog.

Although there are couple of things to be done:

  • Dedicated docs (copy jQuery’s one, add PHP specific, generate phpdoc)
  • Missing methods (css, val)

Download and links

Here are the link which could be helpfull when dealing with phpQuery: