Ajax framework

The Ajax framework is used to dynamically update parts of a page's HTML based on data from the server. Upon a specified event, such as a button click, a callback function is triggered which performs server-side logic and may return updated markup, which is then replaced on-the-fly with no page refresh necessary.

This framework consists a client side javascript library and a server side PHP function toolkit that allows the server to instruct the client side JavaScript to perform actions on the client browser's currently load page.
Generally when using links, it can be used with the #use-ajax class. The #use-ajax class can be used to bind a standard link to the ajax framework. It means that:

The route pointed by this link is the ajax handler which uses the framework's standard php functions to build the instruction set to the client side of framework to update the HTML of the client's browser.

Start ajax requests

There are more ways in CodKep to start ajax calls and use ajax framework.

  1. Place an user (click) triggered ajax link in html code
  2. Set HTML form action to ajax
  3. Place a delayed ajax call to the page (Automatic fired after the specified time)
  4. Fill page parts/block by simply call fill_through_ajax() function

1. Place an user (click) triggered ajax link in html code

1/a. HTML link with use-ajax class

The standard way to place an ajax call to the page is put a simple html link with the class use-ajax. The use-ajax marker will indicate to the ajax framework to handle link as CodKep ajax request. When the user click on this link an ajax request will be send to the server and the response will be processed by the CodKep's ajax framework.

  print l('Click me',"ajax_url/somefunction/$param",['class' => 'use-ajax']);

See definition of l() function.

There is a codkep ajax link generate function which adds the "use-ajax" marker to the link (if not exists). It's easier to use this function to generate ajax links.

  print lx('Click me',"ajax_url/somefunction/$param");

See definition of lx() function.

The target url have to be associated with an ajax typed callback function ("type" => "ajax" in route definition), and the interaction with the existing page elements can achieved by the "ajax_" prefixed handler functions described below.


1/b. Auto routed "easy" ajax callback function

The codkep has an auto routing mechanism to create an ajax callback function simply, without define an individual route for the ajax call:

The lxc() function creates an ajax link which routed directly to a callback function added in parameter.
See definition of lxc() function.

The callback function have to start with "extcallable_" prefix by security considerations:

  1. The callback caller system code won't execute any callback which not start with this prefix.
  2. This prefix help you to keep in mind that this callback are freely callable by malicious users by simple hit on a link.

Sample code using lxc() function:

function mypage()
{
    ob_start();
    print "<h1>Testpage with an ajax link</h1>";
    print lxc("Click me","extcallable_mytest");
    return ob_get_clean();
}

function extcallable_mytest()
{
    ajax_add_alert("Hi, the link is alive!");
}

2. Set HTML form action to ajax

In case you generate a html form with CodKep's HtmlForm class, you can specify the submit action to ajax. The HtmlForm class has an action_ajax($ajaxurl) and a action_ajaxcallback($callbackfunction) method which sets the form type to ajax and set a submit url or a callback. The response of the specified ajax handler will be processed by CodKep's ajax framework.

Sample code when the target is an ajax typed url:

  $myform = new HtmlForm('myform');
  $myform->input('text','name','');
  $myform->input('submit','ok','ok');
  $myform->action_ajax('myform_submit_ajax');
  print $myform->get();

Sample code when the target is an autorouted ajax callback function:

  $myform = new HtmlForm('myform');
  $myform->input('text','name','');
  $myform->input('submit','ok','ok');
  $myform->action_ajaxcallback('extcallable_myformsubmit');
  print $myform->get();

3. Place a delayed ajax call to the page

You can place a delayed ajax call to the generated page by calling this function:

place_delayed_ajax_call($ajax_url,$msec)
Returns a html code which submits an ajax call after a specified time.

Let's see and example how it's work:

function mypage()
{
    ob_start();
    print "<h1>My page<h2>";
    ...
    //This will start an ajax call to the "ajaxhandler_mypage" internal url after 1 second:
    print place_delayed_ajax_call('ajaxhandler_mypage',1000);
    return ob_get_clean();
}

4. Fill page parts/block by simply call fill_through_ajax() function

If your generated html page has parts which need lots of time to load, you can separate the generation of the parts and load the contents later by an ajax call. However this operation can be done with standard javascript codes and existing ajax codes, the codkep has a function to make this whole operation more simple to use:

fill_through_ajax($target,$queryparams = [],$bypass = false)
This function returns a simple html div, which will be filled by the codkep through an ajax call when the page loaded.

function mypage()
{
    ob_start();
    print "<h2>The page title</h2>";
    print "Lorem ipsum...<br/>";
    print fill_through_ajax("extcallable_laterload_test");
    return ob_get_clean();
}

function extcallable_laterload_test()
{
    ob_start();
    print "This is a text which loaded later by an ajax call";
    return ob_get_clean();
}

Note: Keep in mind that the callback function runs in different context than the original page generation codes!

The ajax handler

Every ajax call which made by CodKep's ajax framework have to be targeted to an ajax handler. A CodKep ajax handler is a callback function which:

  1. A function associated with an internal location which has "type"=>"ajax"
  2. An autorouted function which start with the "extcallable_" prefix.

The ajax callback functions can take effects by the following functions:

Ajax commands

The following functions can be used in ajax handlers to direct the ajax framework to do what we want. They affects/modify the page loaded in the client's browser without reloading.

Note: The commands of this functions is buffered and the buffer is only send when the callback is finished.

Note2: You can put more commands to the buffer. (by calling functions below) The commands will be executed that order they added.

ajax_reset()
Clears the ajax command buffer. All previous passed commands will erased.

ajax_add_html($selector,$content)
Invokes the jQuery.html method which replace the html content of the element specified by $selector parameter to the content of $content parameter.

ajax_add_append($selector,$content)
Invokes the jQuery.append method which append the content to the end of the element specified by $selector parameter to the content of $content parameter.

ajax_add_remove($selector)
Invokes the jQuery.remove method which remove the content specified by $selector parameter.

ajax_add_val($selector,$value)
Invokes the jQuery.val method which set the value of the element specified by $selector parameter to the content of $value parameter.

ajax_add_prop($selector,$propname,$value)
Invokes the jQuery.prop method which set the $selector element's $propname property to the $value.

ajax_add_appendval($selector,$value,$linebreak_if_nonempty = false)
Invokes the jQuery.val method to append the textual value of the $value parameter to the element specified by $selector.

ajax_add_css($selector,$css)
Invokes the jQuery.css method which sets the css of the element specified by $selector parameter to the content of $css parameter.

ajax_add_addclass($selector,$class)
Invokes the jQuery.addClass method which adds the $class class to the element specified by $selector parameter.

ajax_add_removeclass($selector,$class)
Invokes the jQuery.removeClass method which remove the $class class from the element specified by $selector parameter.

ajax_add_show($selector,$showparam)
Invokes the jQuery.show method which display the element specified by $selector parameter. The $showparam parameter passed to the jQuery show(). (This is a string or number determining how long the animation will run. Tipically "fast" or "slow" or a millisecond value)

ajax_add_hide($selector,$hideparam)
Invokes the jQuery.hide method which hide the element specified by $selector parameter. The $hideparam parameter passed to the jQuery hide(). (This is a string or number determining how long the animation will run. Typically "fast" or "slow" or a millisecond value)

ajax_add_toggle($selector,$param)
Invokes the jQuery.toggle method which hide or show the element specified by $selector parameter. The $param parameter passed to the jQuery toggle(). (This is a string or number determining how long the animation will run. Typically "fast" or "slow" or a millisecond value)

ajax_add_alert($message)
Invokes the javascript alert() function to show the $message message.

ajax_add_log($message)
Invokes the javascript console.log() function to place the $message log message to the browsers log area.

ajax_add_run($command,$arg = [])
Invokes the client side ajax framework to immediately run the $command named javascript function with $arg arguments.

ajax_add_delayed_ajaxcall($ajax_url,$msec)
Invokes the client side ajax framework to wait $msec millisecond then start a new ajax call to the $ajax_url url.

ajax_add_refresh()
Invokes the client browser to do a full page refresh. (On the current location: location.refresh() )

ajax_add_showol($content,$timeout = 0)
Invokes the ajax framework to show the $content html fragment as overlay popup until $timeout second.

ajax_add_goto($url)
Invokes the client browser to go to the $url url. (The $url parameter is passed to url() before processing)

ajax_add_scrolltop($selector)
Invokes the client browser to call jQuery scrollTop function on a selector.

ajax_add_popupdialog($title,$content)
Popups a dialog styled html block with a $title title and $content html content. The dialog works as modal dialog and will be visible until the user close it with the 'X' button in the right-up corner. You can trigger closing of the dialog with the close_ckdialog() javascript function.

function extcallable_simpleajaxtest()
{
    $t = new HtmlTable();
    $t->opts(['border' => '1','style' => 'margin:5px; border-collapse: collapse;']);
    $t->cellss([['One','Two','Three'],
                ['Red','Green','Blue'],
                ['Up','Down','Left']]);
    ajax_add_popupdialog('Triggered from ajax call','<div>'.$t->get().'</div>');
}

The code above generates the following dialog:

ckdialog.png

A complex ajax example (Version 1 - standard)

First we create a simple page where the ajax modification will work, and an ajax handler which will do the modifications:

function hook_ajaxexample_defineroute()
{
    $r = array();

    $r[] = ['path' => 'example/ajax',
            'callback' => 'page_ajaxexample', //the callback of the original page,
                                              //we will modify the content generated by
                                              //this function
        ];

    $r[] = ['path' => 'ajaxhandle/{direction}/{value}',
            'callback' => 'ajax_handler', //the callback of the ajax handler
            'type' => 'ajax', // tells the system to handle this as an ajax handler
        ];

    return $r;
}

The following codes generates the html content we can modify, and place the ajax links. The code will insert a div with change_this id. The ajax handler will change the content of this div.

function page_ajaxexample()
{
    ob_start();
    print "<h2>Simple ajax exmaple</h2>";
    print '<div id="change_this">'.counter_inner(55).'</div>';
    return ob_get_clean();
}

function counter_inner($value)
{
    ob_start();
    print lx('Up',"ajaxhandle/up/$value");
    print '<br/>';
    print "The value is $value";
    print '<br/>';
    print lx('Down',"ajaxhandle/down/$value");
    return ob_get_clean();
}

The code of the ajax handler. It is receive two url parameter which tells what to do. The ajax_add_html function is used to tell the ajax framework to replace the content of #change_this element's to the result of counter_inner($value).

function ajax_handler()
{
    par_def('direction','text4'  ,'url');
    par_def('value'    ,'number0','url');

    $value = par('value');
    if(par_is('direction','up'))
        ++$value;
    if(par_is('direction','down'))
        --$value;

    ajax_add_html('#change_this',counter_inner($value));
}

A complex ajax example (Version 2 - autorouted)

First we create a simple page where the ajax modification will work (Do not need to create route for ajax handler):

function hook_ajaxexample_defineroute()
{
    $r = array();

    $r[] = ['path' => 'example/ajax',
            'callback' => 'page_ajaxexample', //the callback of the original page,
                                              //we will modify the content generated by
                                              //this function
    ];
    return $r;
}

The following codes generates the html content we can modify, and place the ajax links. The code will insert a div with change_this id. The ajax handler will change the content of this div.

function page_ajaxexample()
{
    ob_start();
    print "<h2>Simple ajax exmaple</h2>";
    print '<div id="change_this">'.counter_inner(55).'</div>';
    return ob_get_clean();
}

function counter_inner($value)
{
    ob_start();
    print lxc('Up',"extcallable_increment",[],['value' => $value]);
    print '<br/>';
    print "The value is $value";
    print '<br/>';
    print lxc('Down',"extcallable_decrement",[],['value' => $value]);
    return ob_get_clean();
}

The ajax_add_html function is used to tell the ajax framework to replace the content of #change_this element's to the result of counter_inner($value).

//The following two functions are callable from client side with a prepared url
// (generated by lxc() function)
function extcallable_increment()
{
    modvalue(1);
}

function extcallable_decrement()
{
    modvalue(-1);
}

function modvalue($modby)
{
    par_def('value','number0');
    $value = par('value');
    $value += $modby;
    ajax_add_html('#change_this',counter_inner($value));
}