How to extend JavaScript in Agile Toolkit

Saturday, May 1st, 2010|Beginner tips, Version 3|by Romans

This post continues to explain how to use JavaScript (JS) most efficiently in Agile Toolkit. Read first part first.

Extending UNIV chain

In the first part I was explaining how can you use a lot of PHP logic and how does it transition into JS. However not everything is possible with PHP and you would certainly need to have native JS code.

One good way to quickly add your own routines is to extends “univ” chain. You will need to start with simple file:

(function($){
$.each({
newWindow: function(url){
window.open(url);
}
},$.univ._import);
})($);

Save it into templates/js/my_univ_ext.js. Next you will need to include it (after original univ), so have something like this in your API init:

$this->js(true)->_load(‘atk4_univ’)->_load(‘my_univ_ext’);

This will extend univ() by adding new function: “newWindow”;

Returning values

Each function in univ chain is wrapped. This is done to ensure that all your functions will return reference to univ again. This makes chaining possible such as univ().newWindow().alert(123) and so on.

However if you will explicitly return defined value from the function, it will be used instead.

Relevant element

When you call $(‘#div’).univ().myFunct() you would probably want to know what selected it used with. You can access a jQuery object from inside your function through:

this.jquery;

If you change this JQuery, it will affect further chained functions. So consider making a clone.

Arguments

If you are passing arguments to your function it will be properly converted into javascript types. This is fairly intuitive with primitive types. However you should know some things about passing complex types:

  • array(‘foo’=>’bar’) will be passed as {‘foo’:'bar’}. This also applies to nested elements.
  • array(1,2,3) will be passed as [1,2,3].
  • mixed arrays, array(1,2,’foo’=>’bar’); will be passed as {0:1, 1:2, ‘foo’:'bar’}
  • AbstractView objects will be passed as jQuery selectors, such as “#MyApp_index_button1″
  • other javascript chains will be passed as javascript: $field1->js(true)->val($field2->js()->val()) will become $(‘#MyApp_field1′).val($(‘#MyApp_field2′));
  • The only way you can specify custom JS code would be: $field1->js(true)->val($field2->js(null,’myvariable+12′));

Changing chain behaviour

So far you know that when you create chain, you specify event, when chain will be executed. Also selector of a current object will be used. However chain have couple of interesting functions you should know about:

  • first – $f->js()->hide() will produce $(‘#id’).hide();
  • $f->js()->_selector(‘.otherid’)->hide() will override selector: $(‘.otherid’).hide(). You should be aware however that $f presence on the page is still going to control whether JS will be included or not, if you are using event.
  • $f->js()->_enclose()->hide(). This will wrap chain into a function. Through _enclose() you can easily specify call-backs. For instance univ().page() takes 2 arguments – first is URL, second is function. $b->js(‘click’)->univ()->page($urlfield->js()->val(), $f->_selector(‘.newdata’)->fadeIn(‘slow’)->_enclose()); – when button $b is clicked, it will open new page through ajax. Field $urlfield value will be used as URL. When page is loaded, it will execute $(‘.newdata’).fadeIn(‘slow’);
  • _selectorThis() – similar to selector, but will use $(this). Try this:  $p->_selector(‘a’)->click( $p->_selectorThis()->_enclose(null,true)->hide()  ); – This will place a click handler on all the <a> tags. The handler will prevent default action (second argument to _enclose) and will hide the link if clicked.
  • _load(‘myjsfile’) – Loads javascript file. This file will be noted BEFORE any execution of javascript code, so you don’t have to worry about it.
  • _css(‘mycssfile’) – Dynamically loads CSS file. This CSS will be loaded relative to base location. If your css file have url(myimage.png) – normally this would load file relative to CSS itself. In case of _css however it will be looking for the file in base location.
  • getLink($text) – will return a HTML link with specified text. If clicked, chain will be executed.
  • reload() – will intelligently attempt to reload element from PHP. Chain calls atk4_reload but it also passes current full URL, cut_object variable and sticky arguments.

Finally – you can use chain as string. $this->template->trySet(‘mytag’,$this->js()->alert(123));

Using yours or 3rd party plugins and widgets

Let’s say you found really good widget or plugin and want to use it. First make sure it’s based on jQuery. Typically any jQuery plugin will require 2 things:

  • load js file, lets say tiptip.js
  • initialise plugin by calling $.tiptip()

In Agile Toolkit you can do both in one line of PHP code:

$field->js(true)->_load(‘tiptip’)->tiptip();

That’s how easy it is.

4 Comments

romaninsh
Posted May 4, 20102:24 pm

zak, as you asked – here is continuation of my JS post.

Svetlozar Kondakov
Posted May 5, 20104:41 pm

Thanks Romans! It seems pretty interesting … tha last part I was able to figure out from previous post :) … everythign seems very native to use.

Still it would be good if all components are rewritten to use new JS functionalities as forms and grids.

romaninsh
Posted May 5, 20107:00 pm

Send me a fixed format_delete inside grid. You said you would contribute something back. Try it. I will review include it into library.

Svetlozar Kondakov
Posted July 14, 201010:03 pm

Sorry for the late reply :(

here is the code I used … but I doubt this is ok :)

// Override this in order to make it work js()
->univ()
->dialogConfirm(‘Изтриване на елемент’, ‘Наистина ли желаете да изтриете този елемент?’,
$this->js()
->_enclose()
->closest(‘.atk4_loader’)
->atk4_loader(‘reload’, $this->name . ‘_delete_id=’ . $this->getCurrentIndex()))
->getString();

// Replace ” with ‘ <
$js_onclick = str_replace('"', "'", $js_onclick);

// Output code current_row[$field] = “Изтрий“;
}

and I also have deleting in submitted() method, when there is the deletign argument. However I can think of somethign really good and will write a good delete formatter when I get some free time for it and will sent via email.