Reloading page with AJAX

Tuesday, June 1st, 2010|Beginner tips, Version 3|by Romans

I receive a lot of questions about how to reload page with Agile Toolkit in certain conditions. There are many approaches and I wanted to write a blog post just about that.

How AJAX works in Agile Toolkit?

To understand how Agile Toolkit works you first need to understand how jQuery works. jQuery have a function $.get() which will send a request towards a server. It then will place a handler which will be called upon success, failure etc.

Additionally there is $.load() function in jQuery which allows certain part of the page to be loaded dynamically.

Agile Toolkit takes this to a new level and here are the goals:

  • Error handling should be handled on framework / application level. Developer is only interested in success.
  • Default behavior of $.load() is not bad, but we want to take it to a new level in terms of control and precise execution.
  • Since we always use jQuery UI, we can rely on it too.

With those goals in mind Agile Toolkit delivers a “widget” for dynamic loading called ui.atk4_loader.

Why a widget?

Firstly – being a widget, we can store some additional data about each instance. We store what was the URL which was loaded, for example and provide method to re-load the same region on the page with the same or different URL. For convenience however widget registers a function in jQuery namespace which mimics how $.load works.

$(‘#page’).atk4_loader(‘/mypage.html’);

Cutting

Agile Toolkit uses a approach of cutting out certain elements from the page. It separates initialization of the objects and their rendering. It will run through the whole initialization but will only render specified object. There are 3 modes for cutting:

  • cut_object=object’s name or short name. This can be helpful if you want to re-render exactly same object. This is used by form widget when it attempts to reload fields.
  • cut_region= region from the template. This is well suited for when you operate with your own custom templates. Let’s say you have a custom page with <?left?> and <?right?> regions. If you need to get request which will show you content only of one region, you can use cut_region argument.
  • cut_page= show complete page, but not shared template. Shared template is attributed to API. Pages usually would contain very humble and small template (could be even empty) which will simply be used for adding objects into it such as grids, frames and forms.

By default atk4_loader will add cut_page, however you can instruct it to use a different cutting technique.

Integration

All the Agile Toolkit widgets and classes already rely on atk4_loader. For example when you use atk4_menu or atk4_expander. Even if you use dialogURL, it will use atk4_loader.

Reality of script execution

jQuery will already look for <script> tag within the loaded piece of code and attempt to execute it. However it’s very basic implementation and there are several advantages in the way how atk4_loader executes <scirpt>s

  • global variable “region” will be defined. It will be equal to $(‘<element used by loader>’). So within your file you can reference this variable. If you are using Agile Toolkit you can write this inside php: $this->js(true)->_selectorRegion()->css(array(‘border’=>’1px solid black’));
  • when HTML is loaded it will appear hidden first until all the JS scripts are executed. Then show() is called. This is done to avoid flickering of HTML which is then manipulated by JS.
  • Agile Toolkit is using refined technique which will properly execute scripts in global context for most browsers.

ID collisions

When we are working with templates, then object template will commonly start with <div id=”<?$_name?>”>. However when you re-loading object it will attempt to load contents into the same div. With normal loading it will attempt to load div inside itself but due to clash with non-unique ID’s it will have side-effects.

To get around this problem we automatically detect if returned content contains a duplicate parent tag in which case child data is copied inside existing tag. There are also some work going on to allow you to re-initialise the widgets.

Error handling

When data is being requested, not always it will be available. Session might expire or other error might happen. Especially in live environment loader have to properly deal with those problems. For instance if session have expired we might want user to re-authenticate then repeat original request without loosing any data (This presently is not implemented). If backend encounters exception, then it outputs a short output which is then interpreted by the loader and error is displayed to user. Again this potentially could implemented as a feedback form asking user what he was doing and then sending additional data to the maintainers.

Content protection

Before we will load data, we verify contents which are to be destroyed for any un-saved data. Some browsers will warn you if you attempt to close window where you have been entering form data, but nothing similar happens for forms. atk4_loader will look for forms with class “form_changed” and if such form present it will display warning message.

Debugging

atk4_loader support debugging. If you specify atk4_loader({debug: true}); then area to be loaded will receive border plus a floating panel with few links such as “remove”, “close”, “reload” and “show url”. Enabling debugging globally sometimes helps to determine problems with reloads.

Multiple requests

Some users have a habit of double-clicking links. Others will impatiently click links if they don’t see instant results. We as developers know what this can only cause unpredictable results and atk4_loader eliminates this on a low level. You can have multiple regions loading data at the same time, but you can’t send new request towards the same element before previous is finished.

$.atk4.get – object-url

Loader relies on another loading method, (which is also used for non-HTML resource loading such as dependencies, css, forms and ajaxec). This method have few more cool features which are also supported:

  • object-url. Instead of string you can specify URL as follows (in php notation): $url=array(‘http://yahoo.com’,'q’=>’search term’); This will be properly assembled into a working URL. You will find this form more convenient if you need to pass arguments which originate from other field values.
  • slow loading timer. When resource takes longer than a minute to load, a global “loading” screen is pulled up to prevent user from panicking and indicate a busy state of the system.
  • on-ready handlers are properly triggered

Ideas for future

We plan to extend this even further in the following ways:

  • Ability to define “hide” and “show” effects.
  • Do you have any ideas for extra features?

My next part of this post will look into a bunch of examples, how you should use loader with frames, grids, pages, menus and so on. If there is anything specific you want me to focus on, please mention in the comments

2 Comments

Svetlozar Kondakov
Posted June 1, 201012:45 pm

Good post as always! I have an idea though … its about all atk framework. I am using this framework for building projects in my native language (Bulgarian :) and I had to change standart messages like “There is unsaved data ….” in ui.atk4_loader in order to transklate them in bulgarian. How about implementing a module for multilanguage?

romaninsh
Posted June 4, 20102:14 am

Thanks. There were some translations. But official support for multi-language will come probably in official v4.