jQuery Library

revIgniter's jQuery Library lets you write jQuery code for event handling, animation and Ajax interactions using LiveCode. If you intend to build complex jQuery driven sites you may prefer to stick to JavaSript and the jQuery syntax. But if you just need simple Ajax functionality this library provides a convenient way to, even dynamically, build jQuery code without dirtying your hands with JavaScript, though you still have to make yourself familiar with jQuery to some degree. The Jquery version currently supported is 1.4.2.

 

Overview

Before explaining revIgniter's approach to jQuery, let's describe how to embed jQuery code in your view file and how this code is built.

  1. First, you need to define, where jQuery is located. You may include the framework remotely without storing any copy on your host.
  2. Then you tell the library to start writing the jQuery script.
  3. Now you can choose from a variety of functions to build all sorts of Ajax interaction.
  4. Finally you tell the library to return the complete script, so that you can store it in the gData variable to be merged with the view.

Initializing the Library

Like most other libraries in revIgniter, the Jquery library is initialized in your controller using the rigLoaderLoadLibrary handler:

rigLoaderLoadLibrary "Jquery"

Setting preferences

There are three preferences you can set by passing an array in the second parameter of the loading handler. The example below tells the library to use a copy of the jQuery framework called "jquery.js" located at assets/js/:

put FALSE into tJquerySettings["useJQremotely"]
rigLoaderLoadLibrary "Jquery", tJquerySettings

To specify a different path to jQuery your code should look like this:

put "your/path/to/jquery/jquery.js" into tJquerySettings["jqueryPath"]
rigLoaderLoadLibrary "Jquery", tJquerySettings

If you specify a jQuery version number like in the following example, the framework will be loaded from googleapis.com. For speed reasons this is the preferred method:

put "1.4.2" into tJquerySettings["jqueryCurrentVersion"]
rigLoaderLoadLibrary "Jquery", tJquerySettings

Note: If you don't set any preferences the latest version of jQuery, located at jquery.com, will be used.

 

Tutorial: revIgniter's Approach to jQuery

What follows is a tutorial based on the "Ajax Integration" example published by Runtime Revolution Ltd. at the on-rev samples site. It demonstrates how to filter data using text the user types into a form field. Contrary to the on-rev sample you won't write any jQuery / JavaScript code. Now let's see, what you will need:

  1. A database table named "people".
  2. A controller to receive and process the data submitted by the jQuery script, which processes the user's keystrokes.
  3. A view file containing an input form field and a table.
  4. A view file, which is used to dynamically replace the table data in the view file, mentioned above.
  5. A very simple model, which gets data from your database table.

To begin, build the table using the table structure below and insert the corresponding data. We use MySQL here as database platform.

CREATE TABLE IF NOT EXISTS `people` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `name` varchar(64) default NULL,
  `age` int(2) default NULL,
  `email` varchar(64) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

INSERT INTO `people` (`id`, `name`, `age`, `email`) VALUES
(1, 'Ben Montini', 27, 'ben@montini.com'),
(2, 'James Johnson', 31, 'james@thejohnsons.com'),
(3, 'Michael Jordan', 52, 'michael@basketballstars.com'),
(4, 'Theresa May', 57, 'ex-priminister@theuk.com'),
(5, 'Jonathan Edwards', 44, 'triple@jump.com'),
(6, 'Tim Cook', 52, 'tim@apple.com'),
(7, 'Bill Gates', 55, 'bill@microsoft.com'),
(8, 'Big Bird', 34, 'bigbird@thestreet.com'),
(9, 'Ben Saim', 22, 'ben.saim@saim.com'),
(10, 'Donald Trump', 49, 'trump@theusa.com'),
(11, 'David Brent', 54, 'david@funny.com'),
(12, 'Graeme Gooch', 66, 'bat@thecricketball.com'),
(13, 'Steven Spielberg', 64, 'me@moviemaking.com'),
(14, 'Ralf Bitter', 99, 'rabit@revigniter.com');

Now let's create the irev files.

Controller

We start with the basic prototype for a controller script. Create a controller called ajax.lc. In it, place the code below and save it to your application/controllers/ folder. Of course, you may remove the comments.

<?lc

# PUT YOUR HANDLER NAMES  INTO THE GLOBAL gControllerHandlers AS A COMMA SEPARATED LIST
put "ajax,index" into gControllerHandlers


# THE CONTROLLER HANDLER
command ajax
  # LOAD REQUIRED LIBRAIES, MODELS, HELPERS ETC.
end ajax

# THE DEFAULT HANDLER
command index
  -- do something here
end index



--| END OF ajax.lc
--| Location: ./application/controllers/ajax.lc
----------------------------------------------------------------------

Now, to load required libraries, helpers and models, insert this code into the ajax handler.
First, we load the "Jquery" library. If you don't change the default setting using the second parameter, your code will link to the latest version of jQuery on jquery.com and you don't need to store a copy of jQuery on your host, though, as mentioned above, this is not recommended in a runtime environment.
We load the Table library as we want to display the data in the form of a table.
Then we load the Form helper which is needed in case CSRF protection is enabled.
Of course, we load the database and we need a model, which we call "ajaxmodel".

rigLoaderLoadLibrary "Jquery"
rigLoaderLoadLibrary "Table"
rigLoadHelper "form"
get rigLoadDatabase()
rigLoadModel "ajaxmodel"

 

Let's build the index handler. Insert the following statement, which stores the page title in gData.

put "revIgniter Ajax Tutorial" into gData["pageTitle"]

Add the following statements to get the CSRF token name which is needed in case CSRF protection is enabled.

if rigFetchConfigItem("csrf_protection") is TRUE then
  # CROSS SITE REQUEST FORGERY PROTECTION ON, GET TOKEN NAME
  put TRUE into tCSRFprotected
  put rigFetchConfigItem("csrf_token_name") into tCSRFtoken
end if

Now to the important part, the statements, which build the jQuery script. We want the script to handle key-up events in the input field. It should post the text, the user has typed, as well as the CSRF token (in case the CSRF protection is enabled), and replace HTML code with data returned by the controller.
Add this statement to tell the jQuery library to start writing the jQuery script:

rigJQopen

Add this statement to tell the library to start writing an event function, which is triggered by key-up events in an input field with the id named "filter".

rigJQeventOpen "'#filter'", "'keyup'"

Add the following statements, which post the text (value) of the input field as "search_term" to the controller and it's datafilter handler, and replace the HTML code inside the "#results" div with the returned data. In case CSRF protection is enabled we post the CSRF token too. Note: Here we use a getter, which returns the jQuery syntax to get the value of the input field and the value of the hidden CSRF token field.

if tCSRFprotected is TRUE then
  rigJQxhRequest "load", "ajax/datafilter", "search_term:" && \
  rigJQgetR("'#filter'", "attr", "'value'") & "," & tCSRFtoken & ":" && \
  rigJQgetR("'[name=" & tCSRFtoken & "]'", "attr", "'value'"), , , "'#results'"
else
  rigJQxhRequest "load", "ajax/datafilter", "search_term:" && \
  rigJQgetR("'#filter'", "attr", "'value'"), , , "'#results'"
end if

Tell the library to end writing the event function by adding this statement:

rigJQeventClose

Add this statement to close the jQuery script:

rigJQclose

To store the script in the gData variable add the following line:

put the result into gData["JQscript"]

The next statement calls the model function to retrieve the data from the database:

put peopleData() into tQuery

To build the HTML table add this statement:

buildTable tQuery

Add the following statement which is needed if CSRF protection is enabled. It adds an opening form tag and a hidden field containing the CSRF token:

put rigFormOpen("ajax/datafilter") into gData["formOpen"]

Finally load the view file, which we call "ajaxView":

get rigLoadView("ajaxView")

We need two handlers more. One, which retrieves the filtered data from the model, and one which stores the corresponding HTML table in the gData variable.

Insert the code below right after the index handler.This handler is called by the jQuery script. It checks if there is POST data, that is to say if key "search_term" has a value. Then it gets the filtered data from the model, calls the buildTable controller handler if the query returned data, and finally loads the view "filteredView".

command datafilter
  put rigVarPost("search_term", TRUE) into tSearchTerm
  if (tSearchTerm <> FALSE) then
    put peopleData(tSearchTerm) into tQueryResult
  end if
  if tQueryResult <> FALSE then
    buildTable tQueryResult
  else
    put "No match!" into gData["peopleTable"]
  end if
	
  # IN CASE CSRF PROTECTION IS ENABLED YOU NEED TO OUTPUT SOMETHING PRIOR
  # TO LOADING THE VIEW, OTHERWISE THE CSRF COOKIE WILL BE RENEWED AT THE
  # FIRST KEYUP EVENT IN THE #filter FIELD. THIS MEANS, AS THE TOKEN KEEPS
  # UNCHANGED, THE COOKIE AND THE TOKEN DO NOT MATCH WHICH YIELDS AN ERROR.
  if rigFetchConfigItem("csrf_protection") is TRUE then
    put ""
  end if
	
  get rigLoadView("filteredView")
end datafilter

Note: revIgniter comes with a Cross Site Scripting Hack prevention filter which can either run automatically to filter all POST and COOKIE data that is encountered, or you can run it on a per item basis. In this case the filter is called by setting the second parameter of rigVarPost() to "TRUE".

Note: Don't forget to add the handler name "datafilter" to the global variable gControllerHandlers at the top of the page.

Insert the handler, which stores the HTML table code in the gData variable by processing the database data, after the datafilter handler to complete the controller.

command buildTable pQueryResult
  put pQueryResult["resultarray"] into tResult
  rigSetTableHeading pQueryResult["fieldnames"], TRUE
  put rigGenerateTable(tResult) into gData["peopleTable"]
end buildTable

Note: Don't forget to add the handler name "buildTable" to the global variable gControllerHandlers at the top of the page.

The code of your controller should now look like this:

<?lc

put "ajax,index,datafilter,buildTable" into gControllerHandlers

command ajax
  rigLoaderLoadLibrary "Jquery"
  rigLoaderLoadLibrary "Table"
  rigLoadHelper "form"
  get rigLoadDatabase()
  rigLoadModel "ajaxmodel"
end ajax

command index
  put "revIgniter Ajax Tutorial" into gData["pageTitle"]
  if rigFetchConfigItem("csrf_protection") is TRUE then
    put TRUE into tCSRFprotected
    put rigFetchConfigItem("csrf_token_name") into tCSRFtoken
  end if
  rigJQopen
    rigJQeventOpen "'#filter'", "'keyup'"
      if tCSRFprotected is TRUE then
        rigJQxhRequest "load", "ajax/datafilter", "search_term:" && \
        rigJQgetR("'#filter'", "attr", "'value'") & "," & tCSRFtoken & ":" && \
        rigJQgetR("'[name=" & tCSRFtoken & "]'", "attr", "'value'"), , , "'#results'"
      else
        rigJQxhRequest "load", "ajax/datafilter", "search_term:" && \
        rigJQgetR("'#filter'", "attr", "'value'"), , , "'#results'"
      end if
    rigJQeventClose
  rigJQclose
  put the result into gData["JQscript"]
  put peopleData() into tQuery
  buildTable tQuery
  put rigFormOpen("ajax/datafilter") into gData["formOpen"]
  get rigLoadView("ajaxView")
end index

command datafilter
  put rigVarPost("search_term", TRUE) into tSearchTerm
  if (tSearchTerm <> FALSE) then
    put peopleData(tSearchTerm) into tQueryResult
  end if
  if tQueryResult <> FALSE then
    buildTable tQueryResult
  else
    put "No match!" into gData["peopleTable"]
  end if
  if rigFetchConfigItem("csrf_protection") is TRUE then
    put ""
  end if
  get rigLoadView("filteredView")
end datafilter

command buildTable pQueryResult
  put pQueryResult["resultarray"] into tResult
  rigSetTableHeading pQueryResult["fieldnames"], TRUE
  put rigGenerateTable(tResult) into gData["peopleTable"]
end buildTable



--| END OF ajax.lc
--| Location: ./application/controllers/ajax.lc
----------------------------------------------------------------------

View "ajaxView"

Create a view called ajaxView.lc. In it, place this code and save it to your application/views/ folder:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <title>[[gData["pageTitle"]]]</title>

    <? return rigJQuerySource() ?>

    [[gData["JQscript"]]]

    </head>

    <body>
      <div class="page_margins">
        <div id="content">
          [[gData["formOpen"] ]]
          <div id="input">Name: <input name="name" type="text" id="filter" /></div>
          </form>
          <p>&nbsp;</p>
          <h2>Dynamic Result (pulled from database)</h2>
          <div id="results">[[gData["peopleTable"]]]</div>
        </div>
      </div>
    </body>
</html>

Note: rigJQuerySource() is a Jquery library function, which returns a html string linking to jQuery.

View "filteredView"

Create the view called filteredView.lc, which is loaded by the datafilter handler. In it, place just this expression and save it to your application/views/ folder:

[[gData["peopleTable"]]]

Model

There is only one model function needed. This function retrieves the filtered data from the database. Create this model called ajaxmodel.livecodescript. In it, place the following code and save it to your application/models/ folder:

script "ajaxmodel"

function peopleData pSearchTerm
  if pSearchTerm <> "" then
    rigDbLike "name", pSearchTerm
  end if
  put rigDbGet("people") into tQueryResult
  if tQueryResult["numrows"] > 0 then
    return tQueryResult
  end if
  return FALSE
end peopleData

That's it, filtering the list should work as expected.

 

Basic Principles

There is a set of rules you should keep in mind:

 

Handler Reference

The following handlers are intended for use in your controller handlers. There are some highly specialized handlers like rigJQajaxForm, rigJQeventAlert, rigJQeventEffect, rigJQeventAnim, rigJQconfirm or rigJQprompt, and others like rigJQset, rigJQgetR or rigJQeventOpen, which are more generic ones.

rigJQuerySource()

This function returns the html string linking to jQuery.

rigJQopen nonce

Use this handler to tell the library to start building your jQuery script.

Parameters

rigJQclose

Ends building your script and returns it. Example:

rigJQclose
put the result into gData["JQscript"]

rigJQajaxForm submitBtnSelector, selectorList, postURI, preventDefault, dataToLoadURI, dataContainerSelector

Permits you to process form data using a xmlHTTPrequest and place the returned HTML into the matched element. Example:

rigJQajaxForm "'#submitBtn'", "'#formField'", "'myController/addDataHandler'", TRUE, "'myController/viewHandler'", "'#content'"

Parameters

Note: This handler assumes, that IDs and names of form elements are identical.

rigJQeventAlert selector, event, alert, preventDefault, eventData

Displays an alert on various events. Example:

rigJQeventAlert "a", "click", "'As you can see, this link no longer takes you to revIgniter.com'", TRUE

Parameters

Here is another example showing how to use the optional fifth parameter:

rigJQvar "message,'This is an alert.'"
rigJQeventAlert "'#testObject'", "'click'", "event.data.msg", , "msg: message"

Note: This handler assumes an event object named "event". Mind the syntax of the Key/Value pair, a map (JavaScript object), contained in the fifth parameter.

For more event types see the jQuery documentation.

rigJQalert alert

This handler writes a simple alert statement.

Parameters

rigJQalertR(alert)

This function does the same as it's equivalent handler (JQalert), but instead of adding the statement to the script, it returns it.

rigJQconfirm varName, question, global

Adds a statement, which displays a JavaScript confirmation box and stores the returned value in a variable.

Parameters

rigJQconfirmR(varName, question, global)

This function does the same as it's equivalent handler (JQconfirm), but instead of adding the statement to the script, it returns it.

rigJQprompt varName, prompt, default, global

Adds a statement, which displays a JavaScript prompt box and stores the input value in a variable.

Parameters

rigJQpromptR(varName, prompt, default, global)

This function does the same as it's equivalent handler (JQprompt), but instead of adding the statement to the script, it returns it.

rigJQset selector, method, propertyValues, function, toggleClassSwitch

Permits you to write all sorts of jQuery setter statements, which manipulate the DOM in some manner. Example:

rigJQset "'p:last'", "addClass", "'selected'"

Parameters

Here is another example, which shows the use of a function as property value:

put "return 'selected';" into tSetterData
rigJQset "'p:last'", "addClass", tSetterData, TRUE

Note: To reference the function arguments for index positions of elements in a set and for old values, always use the terms "index" and "oldVal".

rigJQsetR(selector, method, propertyValues, function, toggleClassSwitch)

This function does the same as it's equivalent handler (JQset), but instead of adding the statement to the script, it returns it.

rigJQgetR(selector, method, getterProp)

Permits you to retrieve information from DOM elements for later use. Example:

rigJQgetR("'#userinput'", "attr", "'value'")

Parameters

rigJQeventOpen selector, event, preventDefault, eventData, eventObject, functionArguments

This tells the library to start writing statements registering behaviors to take effect when the user interacts with the browser. Example:

rigJQeventOpen "'#logout'", "'click'"
  rigJQvar "logout,confirm('Are you sure you want to end the chat session?');"
  rigJQcondition "logout==true", "window.location = 'logout';"
rigJQeventClose

Parameters

Here is another example demonstrating the use of additional function arguments:

rigJQeventOpen "'#customObject'", "'myCustomEvent'", , , , "myName, myValue"
  rigJQset "this", "text", "myName + ', hi there!'"
rigJQeventClose

rigJQeventOpen "'#clickObject'", "'click'"
  rigJQeventOpen "'#customObject'", "'trigger'", , "'myCustomEvent','John','TestValue'"
  rigJQeventClose
rigJQeventClose

Note: Don't use "bind" as event in a rigJQeventOpen handler. jQuery event objects need to be referenced as "event".

rigJQeventClose

Used to mark the end of the event function.

rigJQeventEffect triggerSelector, targetSelector, event, effect, parameter, preventDefault, callback

Permits you to set special effects on various events. Example:

rigJQeventEffect "'#hideBtn'", "'#hideDiv'", "'click'", "hide", "'slow'", , rigJQeffectR("'a'", "hide")

Parameters

Here is another example:

put rigJQeffectR("'a'", "show") & return & rigJQalertR("'This is an alert!'") into tCallbackShow
rigJQeventEffect "'#showBtn'", "'#showDiv'", "'click'", "slideDown", "'slow'", , tCallbackShow

rigJQeffect selector, effect, duration, callback

Permits you to apply effects to objects. Example:

rigJQeffect "'a'", "hide", "'slow'"

Parameters

Note: Don't use "animate" as effect. There is a special rigJQanimate handler for this type of effect.

rigJQeffectR(selector, effect, effectData, callback)

This function does the same as it's equivalent handler (JQeffect), but instead of adding the statement to the script, it returns it.

rigJQeventAnim triggerSelector, targetSelector, event, properties, duration, easing, callback

Permits you to perform a custom animation of a set of CSS properties on various events. Example:

put "'20%'" into tAnimProps["width"]
put "0.4" into tAnimProps["opacity"]
put "'0.6in'" into tAnimProps["marginLeft"]
put "'3em'" into tAnimProps["fontSize"]
put "'10px'" into tAnimProps["borderWidth"]
rigJQeventAnim "'#go'", "'#block'", "click", tAnimProps, "1500"

Parameters

Note: Use an array for duration if you need to set more properties than the duration only. To provide other easing functions than the default "swing" for animation you need additional Jquery plugins.

rigJQanimate selector, properties, duration, easing, callback

Permits you to perform a custom animation of a set of CSS properties.

Parameters

rigJQanimateR(selector, properties, duration, easing, callback)

This function does the same as it's equivalent handler (JQanimate), but instead of adding the statement to the script, it returns it.

Note: Use an array for duration if you need to set more properties than the duration only. To provide other easing functions than the default "swing" for animation you need additional Jquery plugins.

rigJQajax ajaxOptions, setUpOnly

Permits you to perform an asynchronous HTTP (Ajax) request. Example:

put "ajax/datafilter" into tAjax["url"]
put "search_term:" && rigJQgetR("'#filter'", "attr", "'value'") into tAjax["data"]
put rigJQsetR("'#results'", "html", "data") into tAjax["success"]

rigJQeventOpen "'#filter'", "'keyup'"
  rigJQajax tAjax
rigJQeventClose

Parameters

Note: To reference the "success:" function argument for any data returned, always use the term "data". Reference the second argument using the term "textStatus", and the third argument using the term "XMLHttpRequest".

rigJQajaxR(ajaxOptions, setUpOnly)

This function does the same as it's equivalent handler (JQajax), but instead of adding the statement to the script, it returns it.

rigJQxhRequest type, URI, data, callback, dataType, selector

Permits you to load data from the server and, depending on the request type, place the returned HTML into the matched element without a browser page refresh. Example:

rigJQeventOpen "'#filter'", "'keyup'"
  rigJQxhRequest "load", "ajax/datafilter", "search_term:" && rigJQgetR("'#filter'", "attr", "'value'"), , , "'#results'"
rigJQeventClose

Parameters

Note: Mind the syntax of the Key/Value pair, a map (JavaScript object), contained in the third parameter. Don't use "get" as request type if query strings are not enabled in config.lc.

Here is another example, which demonstrates the use of a callback:

put rigJQsetR("'#msg'", "html", "data") & return into tCallback
put rigJQalertR("'The data has been loaded'") after tCallback
rigJQxhRequest "post", "myController", "limit: 25", tCallback

rigJQxhRequestR(type, URI, data, callback, dataType, Selector)

This function does the same as it's equivalent handler (JQxhRequest), but instead of adding the statement to the script, it returns it.

rigJQcallFunction selector, functionName, funtionArguments

Permits you to write statements to call any jQuery or any custom function.

Parameters

rigJQfunctionOpen name, arguments

Tells the library to start writing a custom function.

Parameters

rigJQfunctionClose

Use this handler to mark the end of a custom function.

rigJQcb

Marks the end of a custom function. This is a synonym for JQfunctionClose.

rigJQcondition condition, ifAction, elseAction

Permits you to write a conditional statement. Example:

rigJQcondition "logout==true", "window.location = 'logout';"

Parameters

rigJQconditionR(condition, ifAction, elseAction)

This function does the same as it's equivalent handler (JQcondition), but instead of adding the statement to the script, it returns it.

rigJQeachOpen selector, collection, callback

Permits you to iterate over a jQuery object or over both, a map (JavaScript object) or an array, executing a function for each matched element or for each member of a collection.

Parameters

If iterating over a jQuery object reference the function arguments using the terms: "index" and "element". If iterating over a collection use the terms: "index" and "value".

Note: Use eather the first parameter or the second.

rigJQeachOpenR(selector, collection, callback)

This function does the same as it's equivalent handler (JQeachOpen), but instead of adding the statement to the script, it returns it.

rigJQeachClose

Use this handler to mark the end of an iteration.

rigJQeachCloseR()

This function does the same as it's equivalent handler (rigJQeachClose), but instead of adding the statement to the script, it returns it.

rigJQvar vars

Permits you to declare variables. Example:

rigJQvar "previousScroll," & rigJQgetR("'#chatbody'", "attr", "'scrollHeight'")

Parameters

Here is another example, which takes the result of a confirmation box as value:

rigJQvar "logout,confirm('Are you sure you want to end the chat session?');"

rigJQvarR(vars)

This function does the same as it's equivalent handler (rigJQvar), but instead of adding the statement to the script, it returns it.

rigJQaddStatement statement

In case your particular needs demand it: Use this handler to add standard jQuery code to your script.