ASYNergy Library
ASYNergy is a complement to revIgniter. It is a JavaScript application inspired by and adopted from Livewire. It is a framework for making network requests and changing things on the page. Its name is a compound of the words "asynchronous" (Asynchronous JavaScript and XML) and "synergy", which means the synergy between the two frameworks ASYNergy and revIgniter.
Note: If the server engine used is not LC Create, this library requires the LiveCode Builder (library) extension com.livecode.library.json which needs to be stored in application/extensions. So, the path to the extension is application/extensions/com.livecode.library.json/module.lcm. Please read about how to include the LiveCode JSON extension in chapter "Extensions". The library loads the JSON extension automatically.
Note: ASYNergy's current state is pre-release/beta-release, it is not ready for production use. Serious bugs and unexpected behavior cannot be ruled out.
Table of Contents
Overview
Before outlining each library handlers, let's describe revIgniter's relationship with ASYNergy and how to embed ASYNergy code in your view file.
- Load the ASYNergy library in your controller like other libraries.
- To include the ASYNergy script in your view you just need to add the following line before the closing body tag: [[gData["asynergyScript"] ]]
- The whole interaction of ASYNergy and revIgniter is based on ASYNergy element attributes/name-value pairs called directives. All directives have an asyn: prefix. The common format for all of them is: asyn:[dispatched browser event]="[controller handler to call]"
- In its simplest form, there is at least one HTML element defined as "mutable" by an asyn:mutable attribute and an element defined as "model" by an asyn:model attribute that acts as trigger for AJAX requests. "model" elements and "mutable" elements are related if their ASYNergy attribute values are equal. Such a value serves as the name of the revIgniter controller handler that will be called on request. The innerText, innerHtml, value etc. of the "model" element is added to the payload of the request sent to the server.
- The "mutable" element can be any HTML element like a span element, a paragraph, a div, section, article element or any other element. All HTML enclosed by the "mutable" element's tags is replaced when an interaction occurs and the server responds with the new HTML generated by revIgniter.
- asyn:model attributes can be added to any element that dispatches an input event. There are other directives that can trigger an AJAX request like asyn:click, asyn:keydown and asyn:submit.
- The ASYNergy library processes requests that the ASYNergy JavaScript framework sends to the server in the form of JSON data.
- Then the library sends the response back to ASYNergy as JSON data.
Note: Please read about the ASYNergy JavaScript framework and get detailed information on the ASYNergy wiki page.
Tutorials
To learn how ASYNergy works, there are 3 tutorials available:
Initializing the Library
Like most other libraries in revIgniter, the ASYNergy library is initialized in your controller using the rigLoaderLoadLibrary handler:
rigLoaderLoadLibrary "ASYNergy"
Please note that there is no need to load the asset helper in your controller. The ASYNergy library loads it automatically.
Handler Reference
The following ASYNergy library handlers are intended for use in your controller handlers.
rigAsynElemData(pAttrVal)
This function returns the value, innerText, innerHtml etc. of an HTML element specified by the elements's ASYNergy directive (attribute) value. If dealing with select elements this function returns an array.
Parameters
- pAttrVal: The value of an element's ASYNergy directive (attribute).
In the following example, this function returns the value of an input field that triggers an AJAX request and calls the "name" handler when the user enters something in the field:
command name
local tMutableVal
# SET THE LETTERS OF THE VALUE OF THE asyn:model ELEMENT
# WHOSE ATTRIBUTE VALUE IS "name" TO UPPERCASE
put toUpper(rigAsynElemData("name")) into tMutableVal
# SEND THE RESPONSE INCLUDING THE MODIFIED INPUT DATA
rigAsynRespond tMutableVal
end name
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div style="float: left;margin-right: 20px;">
<input asyn:model="name" type="text">
</div>
<div>
<p>Hello <span asyn:mutable="name"></span></p>
</div>
[[gData["asynergyScript"] ]]
</body>
</html>
rigAsynRespond pRespData, pSyncModelID, pMutableID, pMutableAttrVal
This handler prepares the ASYNergy response and sends it to the client in the form of JSON data.
Parameters
- pRespData: The string or HTML which replaces the HTML enclosed by the "mutable" element's tags. If you like you can pass this parameter as an array including all optional parameters. The array keys are named: "mutableVal" (pRespData), "syncModelID" (pSyncModelID), "mutableID" (pMutableID) and "mutableAttrVal" (pMutableAttrVal).
- pSyncModelID: The model(s) identified by it's id(s) to be synced with the mutable element. Pass this parameter as a string, multiple ids need to be passed as a numbered array. This parameter is optional.
- pMutableID: The mutable element(s) identified by it's id(s) to be updated, needed in case there are multiple mutable elements having the same mutable attribute value. This parameter is optional and can be a string or an array consisting of "mutable" element IDs.
- pMutableAttrVal: The mutable element(s) identified by it's mutable attribute value. This parameter is optional and can be a string or a numbered array consisting of attribute values of "mutable" elements.
Examples:
In its simplest form this function takes the value of "model" elements and adds it to the response if you enclose the asyn:model value in double curly braces:
command name
rigAsynRespond "{{name}}"
end name
<input asyn:model="name" type="text">
<p>Hello <span asyn:mutable="name"></span></p>
If you like to keep the "model" in sync with the "mutable" element, add an id attribute to the "model" and pass the value of the id attribute as second parameter of the rigAsynRespond handler:
command name
put toUpper(rigAsynElemData("name")) into tMutableVal
rigAsynRespond tMutableVal, "theName"
end name
<input asyn:model="name" type="text" id="theName">
<p>Hello <span asyn:mutable="name"></span></p>
This example shows how to address particular "mutable" elements that have the same asyn:mutable value, in this case "foo":
command foo
# THIS WILL UPDATE THE MUTABLE ELEMENTS WITH ID "bar" AND "baz"
# BECAUSE THE PARAMETERS OF THE BUTTON DIRECTIVE asyn:click="foo('bar','baz')"
# ARE "bar" AND "baz"
put rigAsynParams() into tParamsA
rigAsynRespond "-" & the secs & "-", , tParamsA
end foo
<p asyn:mutable="foo" id="bar">[[gData["secs"] ]]</p>
<p asyn:mutable="foo" id="baz">[[gData["secs"] ]]</p>
<p asyn:mutable="foo" id="test">[[gData["secs"] ]]</p>
<button asyn:click="foo('bar','baz')">Update two</button>
This example shows how to address particular "mutable" elements identified by their mutable attribute values, in this case "foo" and "test":
command updateAll
# THIS WILL UPDATE THE MUTABLE ELEMENTS WITH asyn:mutable VALUES
# "foo" AND "test" BECAUSE THE PARAMETERS OF THE BUTTON DIRECTIVE
# asyn:click="updateAll('foo','test')" ARE "foo" AND "test"
local tParamsA
put rigAsynParams() into tParamsA
rigAsynRespond "-" & the secs & "-", , , tParamsA
end updateAll
<p asyn:mutable="foo" id="bar">[[gData["secs"] ]]</p>
<p asyn:mutable="foo" id="baz">[[gData["secs"] ]]</p>
<p asyn:mutable="foo" id="bla">[[gData["secs"] ]]</p>
<p asyn:mutable="test">[[gData["secs"] ]]</p>
<button asyn:click="updateAll('foo','test')">Update all</button>
rigAsynParams(pParamKeys)
This function returns parameters of asyn:model, asyn:click, asyn:keydown and asyn:submit directives as a numbered array.
Parameters
- pParamKeys: Optional comma-separated list of parameter keys (integers) of parameter values to apply an LC function to when specified in the value of an asyn:mutable directive using dot notation. If no parameter is passed, this function returns just the element's directive parameters as a numbered array without applying any LC function.
In this example, clicking the "Reset name" button replaces the value of the input field with the second parameter of the asyn:click directive, set in uppercase.
# REQUEST FROM INPUT FIELD
command name
rigAsynRespond "{{name}}"
end name
# REQUEST FROM BUTTON "Reset Name"
command resetName
local tParamsA
# GET PARAMETERS OF THE asyn:click DIRECTIVE
# OF THE "Reset Name" BUTTON AND SPECIFY
# TO WHICH PARAMETER(S) AN LC FUNCTION SHOULD
# BE APPLIED ACCORDING TO THE VALUE OF THE
# asyn:mutable DIRECTIVE USING DOT NOTATION,
# IN THIS CASE THE FUNCTION IS toUpper()
put rigAsynParams(2) into tParamsA
rigAsynRespond tParamsA[2], "name"
end resetName
<div style="float: left;margin-right: 20px;">
<input asyn:model="name" type="text">
</div>
<div>
<p>Hello <span asyn:mutable="name.toUpper"></span></p>
<button asyn:click="resetName('Bingo','Chico')">Reset Name</button>
</div>
rigAsynPayload(param1, param2)
This function allows access to all values of the ASYNergy payload sent to the server. Returned values are strings or arrays.
Parameters
- param1: Optional string parameter representing a payload array key.
- param2: Optional string parameter representing a payload array key used in addition to the first parameter to retrieve values from nested arrays.
Example:
# GET THE INNER HTML OF A "mutable" ELEMENT
# THAT IT HAD BEFORE THE AJAX REQUEST
put rigAsynPayload("mutablesData", "0") into tMutableElementA
put tMutableElementA["mutableInnerHTML"] into tPreviousHTML
Note: The names of the payload array keys can be found in the ASYNergy request data in your browser using the developer tools.
rigAsynValidateInput(pModelAttrVal, pTransmittedElA, pRuleGroup)
Validate user input data using the form validation library.
Parameters
- pModelAttrVal: Pass the values of the respective asyn:model attribute of the input elements to be validated to the first parameter of this function. This parameter can be a string, a comma separated list of strings or an array.
- pTransmittedElA: This optional parameter specifies the input data to be validated from elements with an asyn:transmit directive. It is an array of attribute names and values included in the "transmissionElsData" JavaScript object of the request JSON data. Please read about the asyn:transmit directive in Transmission Data.
- pRuleGroup: This optional parameter is the name of the validation group to be used. If this parameter is empty, the name of the validation group is automatically set to the name of the respective controller.
This example shows how an input field is validated when it has lost focus. This is done by using the "blur" modifier. The asyn:transmit directive of the input field is needed when the user clicks the submit button.
If the validation fails an error message will be added to the response which is sent by the rigAsynRespond handler. This message replaces the current HTML enclosed by the tags of a "mutable" element whose asyn:mutable attribute has the same value as the asyn:model attribute and the asyn:transmit attribute.
command email
local tError
put rigAsynValidateInput("email") into tError
rigAsynRespond tError
end email
<form action="https://mysite.com/asynRegister" method="post" asyn:submit.prevent="signup">
<label for="email">Email Address</label>
<input type="text" name="email" asyn:model.blur="email" asyn:transmit="email" value="[[gData["email"] ]]">
<p class="errorMessage" asyn:mutable="email"></p>
<input name="register" value="Register" type="submit" />
</form>
Note: This function needs the Formvalidation library.
To get a better understanding of form validation with ASYNergy, please read the ASYNergy Form Validation tutorial.
rigAsynNavigate pSegments
Use this handler to navigate to another page.
Parameters
- pSegments: The URI segments that define the page to navigate to. You may need to add a handler to your controller according to the second segment.
Example:
command signup
local tErrorA, tSegments
put rigAsynValidateInput("email,password,passwordConfirm") into tErrorA
if tErrorA is empty then
# DISPLAY SUCCESS PAGE
put "asynRegister/success" into tSegments
rigAsynNavigate tSegments
else
rigAsynRespond tErrorA
end if
end signup
command success
get rigLoadView("registerSuccessView")
end success
rigAsynAddResponseData(pRespData, pSyncModelID, pMutableID, pMutableAttrVal)
This function accumulates response data. Use this function if there are multiple "mutable" ASYNergy HTML elements and you want the HTML data enclosed by the tags of the individual elements to be updated with different data.
Parameters
- pRespData: The string or HTML which replaces the HTML enclosed by the "mutable" element's tags.
- pSyncModelID: The model(s) identified by it's id(s) to be synced with the mutable element. Pass this parameter as a string, multiple ids need to be passed as a numbered array. This parameter is optional.
- pMutableID: The mutable element(s) identified by it's id(s) to be updated, needed in case there are multiple mutable elements having the same mutable attribute value. This parameter is optional and can be a string or an array consisting of "mutable" element IDs.
- pMutableAttrVal: The mutable element(s) identified by it's mutable attribute value. This parameter is optional and can be a string or a numbered array consisting of attribute values of "mutable" elements.
Example:
put getMsgData() into tMsgList
# IF YOU DON'T INTEND TO CLEAR THE USER INPUT FIELD
# CALL rigAsynRespond tMsgList AND YOU ARE DONE
# OTHERWISE...
put rigAsynAddResponseData(tMsgList, , , "addMsg") into tResponseA
put rigAsynAddResponseData("", , , "userinput") into tResponseA
rigAsynRespond tResponseA
You can find a use case for this function in the Simple Chat Application tutorial.
rigIsAsynRequest()
This function returns true or false depending on whether the request was an ASYNergy request.