Metainformationen zur Seite
Web Forms: Client Server Communication (ajax-generic.php)
The ajax-generic.php interface is a communication helper to transfer config file data from LoxBerry (“server”) to your web interface (“client”) and back.
This feature is available from LoxBerry 3.0. Set your LB Minimum version in your plugin.cfg.
ajax-generic.php
is the backend to request and submit form data to your specific config file. Config files created and readed by ajax-generic.php are json files. It is thought to be used as ajax request to fill your web form with data, and to submit form data to your config file.
ajax-generic.php supports:
- Request a json config file and transmit it to the client as json.
- Write data to a config file.
- Read and write the full config file, or a specified section of the json
- Submit form data as POST in the Form Post method, or as plain json data
- Supports abbreviations for your config file path (LBHOME, LBPCONFIG,…) - this is helpful, as both browser and server script don’t know what folder should be used, but the server knows the base directories.
- Settings are merged (default) or overwritten (option
replace
).
Abstract
Reading data from config file using the Fetch API
var formdata; fetch('/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/myplugin/config.json§ion=Main&read') .then( response => response.json() ) .then( data => formdata = data );
Requests the section Main
of config file /opt/loxberry/config/plugins/myplugin/config.json
. The data are written to the formdata
variable.
LBPCONFIG
is an automatic placeholder for /opt/loxberry/config/plugins (see list below).
Writing form data to config file using the Fetch API
var formData = new FormData(document.querySelector('form')); const requestOptions = { method: "POST", headers: { "Content-Type" : "application/json" }, body: JSON.stringify( formData ) }; fetch('/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/myplugin/myplugin.json§ion=Main&write', requestOptions)
formData
is set to represent alls form data of the first form of the page.
With requestOptions
the request is build for the fetch call. This example sends the form data in json syntax, therefore the request body
is set to be a json by the JSON.stringify(formData)
call.
The request is sent to ajax-generic.php
, with file is the myplugin.json
and section Main
, with option write
.
The response is a json with the newly created data and 200 OK, or 500 ERROR on any error.
Replace a section in the config file
var formData = new FormData(document.querySelector('form')); const requestOptions = { method: "POST", headers: { "Content-Type" : "application/json" }, body: JSON.stringify( formData ) }; fetch('/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/myplugin/myplugin.json§ion=Main&replace', requestOptions)
The preparation of the data is equal to the section before.
In this example, the section Main
is sent with option replace
.
The replace option will completely replace the full section with the new submitted data (instead of the write option that merges settings). Replace has a special meaning on arrays. As arrays usually would be merged, you won’t be able to delete array elements. With the replace parameter, you can completely replace a section instead of merging.
The response is a json with the newly created data and 200 OK, or 500 ERROR on any error.
Feature details
Always use the following url to call the interface:
/admin/system/ajax/ajax-generic.php
Add the following parameters
Parameter | Mandatory | Usage | Example |
file=<filename> | YES | Give the full path and name of your config file. Also relative paths are allowed. Use fixed abbreviations instead of /opt/loxberry in the path (see below) Only files in the CONFIG folders are accepted. | file=LBPCONFIG/myplugin/config.json |
section=<Sectionname> | Optional | If no section is given, reading and writing apply to the full config file. If a section is given, data are read and written from this base section of the json. Only the first level is possible. Be aware to read and write with or without section, but not mixed (that will scramble your config file). | section=Main |
read | (Default) | If read is given (it’s not required to send read=1, but simply read), that’s a read-only query. | read |
write | NO | If write is given, the submitted data are written to the config file, optional to the given section. Write will respond with a json of the new data (HTTP 200 OK), or, on error, with a json with an error string (HTTP 500 INTERNAL SERVER ERROR). write is mutually exclusive to read. | write |
replace | NO | If replace is given, the submitted data will replace the full section instead of merging. This is important with arrays, as you otherwise wouldn’t be able to remove elements from arrays. Without a section, the full file will be replaced by the submitted data. Replace implicitely enables write. | replace |
Filename folder abbreviations
It might be difficult to know the server-side path of your script on the client, and you should avoid to hard-code the /opt/loxberry path. Therefore in the file= query string, the following shortcuts are available. The string is replaced on the server before processing of the request.
String | Default folder | Description |
$lbhomedir, LBHOMEDIR | /opt/loxberry | Home directory of LoxBerry |
LBPCONFIG | /opt/loxberry/config/plugins | Base config directory for all plugins |
$lbsconfigdir, LBSCONFIG | /opt/loxberry/config/system | System configuration directory of LoxBerry |
LEGACY | /opt/loxberry/webfrontend/legacy | The users legacy folder to place custom scripts in. |
Be aware that the $ possibly needs to be encoded, depending on your JavaScript library.
Examples
/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/alexa2lox/alexa.json§ion=Base&read
Reads the section Base of alexa2lox/alexa.json
/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/alexa2lox/alexa.json§ion=Base&write
Writes the section Base of alexa2lox/alexa.json
/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/alexa2lox/alexa.json&read
Reads the full alexa2lox/alexa.json
/admin/system/ajax/ajax-generic.php?file=LBPCONFIG/alexa2lox/alexa.json&write
Writes the full alexa2lox/alexa.json
Updates of general.json
ajax-generic
detects an update to the general.json file, and automatically triggers the auto-generation of the legacy general.cfg (https://loxwiki.atlassian.net/wiki/spaces/LOXBERRY/pages/1246070304/Perl+Modul+LoxBerry+System+General#PerlModulLoxBerry%3A%3ASystem%3A%3AGeneral-Recreationofthelegacygeneral.cfgfromotherlanguages ).
Usage examples
Usage in a simple form
Write data
This is a working html to write the form fields to your test.json config in LoxBerry’s legacy folder.
<html> <body> <h2>HTML Form</h2> <form id="myForm"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="John"><br> <label for="lname">Last name:</label><br> <input type="text" id="lname" name="lname" value="Doe"><br><br> <input type="submit"> </form> <script> myForm.onsubmit = async (e) => { e.preventDefault(); let response = await fetch('/admin/system/ajax/ajax-generic.php?file=LEGACY/test.json&write', { method: 'POST', body: new FormData(myForm) }); let result = await response.json(); alert("Returned: " + result.fname + " " + result.lname); }; </script> </body> </html>
Usage with Vue3
Example read code to fill the $data.Mqtt object
The getData() method is called in the data() function. To prevent JavaScript errors, the received data are evaluated and set to default values if required.
getData() { console.log("Called getData"); fetch('/admin/system/ajax/ajax-generic.php?file=$lbsconfigdir/general.json§ion=Mqtt&read') .then( response => response.json() ) .then( data => { if( !data?.Brokerhost ) data.Brokerhost = 'localhost'; if( !data?.Brokerport ) data.Brokerport = '1883'; if( !data?.Brokeruser ) data.Brokeruser = 'loxberry'; if( !data?.Brokerpass ) data.Brokerpass = ''; if( !data?.Websocketport ) data.Websocketport = '9001'; if( !data?.Uselocalbroker ) data.Uselocalbroker = 'true'; if ( data.Uselocalbroker == 1 ) data.Uselocalbroker = 'true'; this.Mqtt = data } ); }
Example write code of the $data.Mqtt object
The saveApply()
method is called by the v-on:click
binding of the Save button.
saveApply() { console.log("Called Save and Apply"); const requestOptions = { method: "POST", headers: { "Content-Type" : "application/json" }, body: JSON.stringify( this.$data.Mqtt ) }; var self=this; fetch('/admin/system/ajax/ajax-generic.php?file=$lbsconfigdir/general.json§ion=Mqtt&write', requestOptions) .then( function(response) { console.log(response); if( response.ok != true ) { self.data_save_error = true; } else { self.data_save_error = false; self.data_saved = true; self.data_changed = false; } }); }
The callback of the fetch evalutes response.ok to show ok or error messages in the ui. There is the trick var self=this;
before of the fetch, as in the callback this
changes the context to the response, therefore we safe this
in self
to use it inside of the callback.
Testing or using ajax-generic.php from commandline
ajax-generic.php allows to be executed from commandline. Input data can be echo'ed with a pipe to ajax-generic.php. The GET Parameters can be added as parameter string (see example). Take notice of escaping the &
symbol by \&
in Bash.
echo '{ "Main": { "resetAfterSend" : true } }' | php /opt/loxberry/webfrontend/htmlauth/system/ajax/ajax-generic.php file=LBSCONFIG/test.json\&write
Log output is printed to STDERR. The response of the call always is the new config file as json, that is echoed to STDOUT.