Adding native JavaScript code

The purpose of JS chains in Agile Toolkit is to provide a glue between JavaScript and PHP. It is NOT to completely replace native JavaScript.

The Bad JavaScript code

<script>
  function 
myfunc(arg){
    var 
x=...;
    
// do something here..
  
}
</script>

You might wonder, why is this bad? This might have been how you wrote your JavaScript code before. Perhaps it's the missing $(function(){ ?

There is another fundamental problem with the code: its scope.

In Agile Toolkit objects can be loaded dynamically, through AJAX. In the best tradition of Agile Toolkit, they will be loaded with the proper javascript bindings. Functions with the same name will clash. Placing them incorrectly might stop them from loading. It's a mess.

Agile Toolkit offers a better way to organise your JavaScript code. It is by putting it inside a jQuery namespace. The way you call your function will be slightly different:

// Before
myfunc(123);

// After
$.univ().myfunc(123);

// From PHP
$view->js(true)->univ()->myfunc(123);

Extending The Universal library

The way this scope is implemented is quite similar to how jQuery plugins work. The purpose of univ() is to 'absorb' new functions through this syntax:

$.each({
    
myfunc: function(a){
        
alert('myfunc: '+a);
    },
    
mysum: function(foo,bar){
        return 
foo+bar+1;
    },
},$.
univ._import);

All you need to do now is to include this JS file

Including JS files

Agile Toolkit has 3 different ways to include your files. Open atk4/templates/shared/shared.html and find the "js_include" tag. When Agile Toolkit is rendering your page, it will place some includes in there.

Having said that, Agile Toolkit is capable of dynamically including JavaScript code after your document has loaded. This makes sense for content which will be loaded through AJAX

Dynamic Includes

Those includes will be loaded through AJAX and evaluated after they are loaded. Using them is extremely simple:

Result

 

Code

$page->add('Button')->set('Click Me')
    ->
js('click')->_load('secret')
    ->
univ()->myfunc('hello world');

Agile Toolkit will search for "secret.js" file in your JavaScript folders (such as templates/js) and include it when found. The framework will also ensure that your function is called after the libraries are properly loaded and evaluated.

If you happen to move this code into an AJAX-loaded pop-up window, it will continue to work flawlessly. You must note that you do not need to wrap code inside dynamic includes. Also, you shouldn't execute any of the JavaScript directly, because the file will be loaded only once, even if you do _load it several times.

Again, thanks to Agile Toolkit, your code is portable, compact and works great.

Static Includes

If you are including some 3rd party code, they sometimes might not like dynamic loading. Third party code might assume that the on-ready is not yet triggered or do some other kind of magic. Google Maps code, for example, wants to be loaded along with your page.

If this happens, you can specifically instruct Agile Toolkit to put the include inside the HTML.

$this->api->jui->addStaticInclude('myfile');
// or
$this->api->jui->addStaticInclude('http://pathto/cdn/file.js');

You must be mindful to include this on the page, which is loaded directly, and can potentially open other pages through AJAX, requiring this include. If unsure, add this code to your API's init() method.

If you want to go even more 'hardcore' with the include you can do this:

$this->api->template->append('js_include',
    
'<script type="text/javascript" src="http://..."></script>'."\n");

or even add include into shared.html file once you place it local template directory.

Executing any JS code

One of the goals of JS Chains is security. JavaScript injection is a common problem and by having a nice interface between your JavaScript and server backend you become immune to it.

If you think that you know better, you can execute a string of JavaScript code from anywhere like this:

// DANGER: Contains JavaScript injection vulnerability
$view->js(true,"alert('$my_message')");

// SAFE: $my_message is escaped
$view->js(true)->univ()->alert($my_message);

I must note, that by default univ() chain has functions for showing alerts, sending debug through the Firebug console and implements many other amusing things. It is further described under the JavaScript API section.