ajax
Syntax
ajax: "(url)" [method] [return type] [get-pars(parameters)] [post-pars(parameters)] [csrf] [header("name", "value")] [cache] [nocache] [await] [every (time)] [after (time)][, ...];
We have tried to make the ajax command as simple to use as possible, but you need to read all this to get the full picture on how to use it.
The value syntax used for the ajax action command is exactly the same syntax for when you are loading content from the @component statement.
url = The url that you want to call using ajax. Supports external URLs, and also relative pathnames with "../", which follow the same rules as CSS, ie. it follows from the location of the ACSS config file where this command is run. Use "/" at the beginning of the URL to go from the root of the public path.
method = post or get (defaults to post)
return type = json or html (defaults to json)
The browser will expect either a json string as a return value from the server that will be translated into Active CSS variables, or an html (text) string (which is accessible using {$STRING}).
get-pars = any variables that you want to send with the ajax call on the url, separated by "&", enclosed in parentheses.
post-pars = any variables that you want to send with the ajax call as additional POST variables, separated by "&", enclosed in parentheses.
csrf = If this option is specified, the header X-CSRF-TOKEN will be sent with the ajax request, containing the value of whatever is in the content attribute of the following tag: <meta name="csrf-token" content="value">. If you are using Laravel on the back-end, you would put "{{ csrf_token() }}" in the content attribute of this tag in your blade template. If you need any other headers with the ajax request, see the header option for this command.
header = Use this to add headers to your ajax request. You can use ACSS variables in the value. Example: header("X-BLAH", "something"). It can be used multiple times in the same ajax call, like this:
@component clockComponent
html("/examples/clock-component.html" get
header("X-BLAHBLAH-1", "{myString}")
header("X-BLAHBLAH-2", "value2")
header("X-BLAHBLAH-3", "value3")
)
css(/examples/clock-component.css get)
{
...
}
/* or */
ajax: "/examples/clock-component.html" get
header("X-BLAHBLAH-1", "{myString}")
header("X-BLAHBLAH-2", "value2")
header("X-BLAHBLAH-3", "value3");
await = using this option will make the ajax command wait until it is complete before moving onto the next action command. If the ajax command fails it will break out of the current event flow and run the appropriate "after" failure event. See the after (callback) events docs for a full description of those.
The following variables will always be found on the server (in GET or POST form depending on the method of the ajax call) when the form is submitted:
- _ACSS = 1
- _ACSSTYPE = JSON or HTML
This tells the server that an ajax call has been made. If you are building an SPA, you would check for this variable, and if it is present, then you would not send over the HTML, BODY, HEAD, FOOTER, or wrapping page stuff as part of the return content. You would only back to the browser the minimal text string that you need to insert into an area of the page. See the SPA tutorial (part 2) if you want more details on how you do that. There are some PHP files in there which tell you want to do. You don't have to be a PHP person to understand the concepts.
When the server has returned a response, the "afterAjax" event is checked for in the config and ran if present. Or if you've used the await option in the ajax command, the next command inside your event declaration will run.
On failure, other events will run. See the after (callback) events docs for a full description of those.
The afterAjax event happens on the same event selector. (Side note: you can use conditionals on all event selectors if you want to have different ajax calls depending on circumstances, and have different afterAjax events depending on results gotten back from the server. See the "after events" documentation for an example of that. Also, you can inspect our search field at the top of the page in the DevTools extension (if you have that) to see the conditionals attached to our search result handler - all the code attached to elements can be inspected through the DevTools extension, because we are using the dev version of the core live - don't use the dev version on your live website unless you want others to read your code!)
The returned ajax string is always in the variable {$STRING} - this is automatic - you don't need to declare {$STRING} as a variable or anything else. All returned strings get put into {$STRING} always, unless you've asked for the result in JSON, in which case you set up the variable name(s) for the return data in the JSON string itself. You can play around with JSON return variables in the console to see what you get back, and it will all become clear. Eg. if you set a variable of "success = yes" to return in JSON, then the variable is available as {success} in Active CSS. But always refer to an HTML (not JSON) return string by using ${STRING} - you won't see ${STRING} mentioned in the console.
#aboutMenuItem:click {
url-change: "/about.html" "About Bob";
ajax: "/about.html" html post;
}
#aboutMenuItem:afterAjax {
#contentArea {
render: "{$STRING}";
}
}
That is the same as writing this below, but here we use the await option on the ajax command to turn it synchronous (it's not really synchronous in reality, but in terms of coding it, it acts like it is synchronous - it runs the next command only when the ajax is complete and has been successful. If the ajax call is not successful, the after events kick in, so you would use those events to handle errors.):
#aboutMenuItem:click {
url-change: "/about.html" "About Bob";
ajax: "/about.html" html post await;
#contentArea {
render: "{$STRING}";
}
}
The following example will send a POST ajax call to about.html with additional get parameters, so it ends up as "about.html?myVar=1&myVar2=test". You don't put in a "?" as this is done internally:
ajax: "/about.html" html post get-pars(myVar=1&myVar2=test);
Note the example above could also be written like this:
ajax: "/about.html?myVar=1&myVar2=test" html post;
Using get-pars can be useful if you are using variable substitution, like 'ajax: "{@data-href}" html post;' which contains a regular URL you want to ajax, and do not know whether to use a "?" before the variables, as the url may or may not have parameters attached already, but you still need to send extra get variables.
The following example will send an GET ajax call to "about.html", and there will be myVar=1 and myVar2=test post parameters sent also. Whether or not to use a "?" is handled internally:
ajax: "/about.html" get post-pars(myVar=1&myVar2=test);
If you want to see what is actually happening with your ajax command, use the console in your default browser inspector to see what is actually being sent and how. This is the best way to debug if variables are being sent or not, and whether or not they should be being received on the server as GET or POST variables.
The cache parameter = This is an internal feature that is cross-browser compatible and doesn't require browser storage permissions, as it is not persistent. What it means is: Store this exact page and its return values so it will not be retrieved from the server again for the duration of this page. The cache is only for the duration of the loaded page. Ie. if the browser is refreshed, there will no pages stored in memory. There is no attachment of the page to internal storage. We use this to store search results, so if you type in the same thing more than once, it gets the results from memory and doesn't needlessly call the server again. This is a bit different to the ajax-pre-get functionality, but is the same kind of idea. You don't need to use both for the same ajax call.
The following example will cache an about.html page that references specific variables. If another about.html page is loaded later on with different variables, it will not clash with the cached page, instead it will load an additional about page. Cached pages are unique per filename and variables combined. In other words, if you have two different pages with the same filename, you can cache both of them if you are sending different variables.
Note that we are not caching all the resources. We are only storing the HTML in memory for later use again if we need it. Caching resources, like images, etc., is handled internally by the browser automatically, so you don't have to think about that.
ajax: "/about.html" get post-pars(myVar=1&myVar2=test) cache
nocache = This is an internal feature that is cross-browser compatible, and can get around troubles with caching pages. It appends "_={timestamp}" to the GET or POST parameters, thereby making the page unique enough that it shouldn't get cached. It is not the opposite of the "cache" parameter exactly. You would use it if you absolutely needed a fresh copy of the page each time in the user session and wanted to make sure you did.
See the SPA tutorial for a real config use of the ajax command.
Important note: Ajax calls should mostly always be called directly under the event selector, and rarely under a target selector. If you include them under targets, then you run the risk of the ajax call being run multiple times. For instance, this could happen if the target is ".menuItem", and you've got lots of menu items. You might want to do this though if you are updating multiple areas at once with ajax results. But this isn't a tutorial on how to do that...
Iterating JSON results when there is no top-level object
When you include the json property in your ajax commands, the properties of the JSON object are automatically converted into scoped variables. This can often be enough to iterate a collection of JSON properties. If you need to iterate the JSON results but there is no top-level object to iterate, you can still iterate by looping via a general $JSON variable.
For example:
@each $item in $JSON {
render: "{$item.name}";
}
Rendering JSON HTML content from an un-managed server
Occasionally you may need to render HTML that is stored in a JSON property from a third-party API that you have no control over. To render the variable as HTML and not text, reference the specific property with a dollar. This will treat the content as HTML even if the original JSON property does not start with a dollar.
For example
$someHTML: $JSON.$htmlIsInHere;
render: "{$someHTML}";