Commit c271395e authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge remote-tracking branch 'origin/raos_work' into crose_work

parents f677f3f3 d457306b
API: Client / Server
====================
Form initial call
-----------------
Request: index.php (QuickFormQuery.php, included by Typo3 extension)
Response:
Form attributes:
data-hidden: 'yes'|'no' - yes: The element is not visible yet, maybe later.
data-disabled: 'yes'|'no' - yes: The element is visible, but the user can't interact with it.
data-required: 'yes'|'no' - yes: The element is required. The form can't be submitted if any required element is empty.
## General
Asynchronous request (read AJAX) initiated by the client receive a JSON Response from the server containing at least:
{
"status": "success"|"error",
"message": "<message>"
}
`status` indicates whether or not the request has been fullfiled by the server (`"success"`) or encountered an error (`"error"`).
On `"error"` the client must display `"<message>"` to the user. On `"success"`, the client may display `"<message>"` to the user.
### Form Group Configuration
As part of the server response, the JSON stream may contain a key
`form-update`. It contains an array of objects having following
structure
{
...
"form-update" : [
{
"form-element": "<element_name>",
"hidden": true | false,
"disabled": true | false,
"required": true | false,
"value": <value>
},
...
],
...
}
`"form-element"`
: the name of the HTML Form Element as it appears in the `name`
attribute.
`"hidden"`
: whether the Form Group is visible (value: `false`) or
invisible (value: `true`).
`"disabled"`
: whether or not the Form Element is disabled HTML-wise.
`"required"`
: whether or not the Form Element receives the HTML5 `required`
attribute.
`"value"`
: For textual HTML Form Input elements, it is supposed to be a
scalar value, which is set on the element.
When `"form-element"` references a `<select>` element, a scalar value
selects the corresponding value from the option list. In order to replace
the option list, use an array of objects, having this format
[
{
"value": 100,
"text": "a",
"selected": true
},
{
"value": 200,
"text": "b",
"selected": false
}
]
`"select"` is optional, as is `"text"`. If `"text"` is omitted, it
will be derived from value.
Form load (update)
------------------
### Trigger
Form Element with attribute `data-load="data-load"`.
The client side JavaScript installs on change handlers for all HTML Form Elements having the `data-load` attribute.
### Request: api/load.php
#### Type
POST
#### Parameters
##### URL
none
##### POST
HTML Form without `<input>` elements of type `file`. The HTML Form is
required to have a HTML Form Element named `s`, which must contain the
SIP.
### Response
JSON Stream
{
"status": "success"|"error",
"message": "<message>",
"redirect": "client"|"url"|"no",
"field-name": "<field name>",
"field-message": "<message>",
"form-update": [
{
"form-element": "<element_name>",
"hidden": true | false,
"disabled": true | false,
"required": true | false,
"value": <value>
}
]
}
status
: see [General]
message
: see [General]
redirect
: not used
field-name
: HTML Form Element Name which raised error on server side. Requires
status to be `"error"`
field-message
: reason of error. Requires status to be `"error"`.
form-update
: Array of Objects. Each object describes the state and value of a
HTML Form Element identfied by its `name` attribute.
Form save
---------
### Trigger
none
### Request: api/save.php
#### Type
POST
#### Parameters
##### URL
none
##### POST
HTML Form without `<input>` elements of type `file`. The HTML Form is required to have a HTML Form Element named `s`, which must contain the SIP.
### Response
JSON Stream
{
"status": "success"|"error",
"message": "<message>",
"redirect": "client"|"url"|"no",
"field-name": "<field name>",
"field-message": "<message>",
"form-update": [
{
"form-element": "<element_name>",
"hidden": true | false,
"disabled": true | false,
"required": true | false,
"value": <value>
}
]
}
Name | Description
------- | -----------
status | see General
message | see General
redirect | not used
field-name | HTML Form Element Name which raised error on server side. Requires status to be `"error"`
field-message | reason of error. Requires status to be `"error"`.
form-update | Array of Objects. Each object describes the state and value of a HTML Form Element identfied by its `name` attribute.
File (upload)
-------------
### Trigger
none
### Request: api/file.php
#### Type
POST
#### Parameters
##### URL
`action=upload`
##### POST
Multi part form with file content, parameter `s` containing SIP, and parameter `name` containing the name of the HTML Form Element.
### Response
JSON Stream
{
"status": "success"|"error",
"message": "<message>"
}
Name | Description
------- | -----------
status | see General
message | see General
Record delete
-------------
Request: api/delete.php
Return JSON encoded answer
status: success|error
message: <message>
redirect: client|url|no
redirect-url: <url>
field-name:<field name>
field-message: <message>
Description:
Delete successfull.
status = 'success'
message = <message>
redirect = 'client'
Delete successfull.
status = 'success'
message = <message>
redirect = 'url'
redirect-url = <URL>
Delete failed: Show message.
status = 'error'
message = <message>
redirect = 'no'
## Glossary
SIP
: tbd
HTML Form Element
: Any `<input>` or `<select>` HTML tag. Synonymous to *Form Element*.
Form Group
: The sourrounding `<div>` containing the `.control-label`,
`.form-control` `<div>`s, and `.help-block` `<p>`.
......@@ -315,8 +315,8 @@ module.exports = function (grunt) {
}
},
jasmine: {
frontend: {
src: ['tests/jasmine/spec/*Spec.js'],
unit: {
src: ['tests/jasmine/unit/spec/*Spec.js'],
options: {
vendor: [
'js/jquery.min.js',
......@@ -326,7 +326,7 @@ module.exports = function (grunt) {
'js/qfq.debug.js'
],
helpers: ['tests/jasmine/helper/mock-ajax.js'],
template: 'tests/jasmine/SpecRunner.tmpl'
template: 'tests/jasmine/unit/SpecRunner.tmpl'
}
}
},
......
<!-- -*- markdown -*- -->
# Client/Server Protocol
## General Protocol
The Client may asynchronously send requests to the Server. The Server
is expected to return responses as outlined below.
The response must contain at least a [Minimal Response]. Depending on
the request, it may provide additional responses as outlined in this
section.
### Minimal Response
Asynchronous request (read AJAX) initiated by the Client receive a
JSON Response from the server containing at least:
{
"status": "success"|"error",
"message": "<message>"
}
`status` indicates whether or not the request has been fullfiled by
the server (`"success"`) or encountered an error (`"error"`). On
`"error"` the Client must display `"<message>"` to the user. On
`"success"`, the Client may display `"<message>"` to the user.
Depending on the request, the server may provide additional
information in the response, as outlined below.
### HTML Form Element Validation Response
The Server may perform a serverside validation of values submitted as
part of a HTML Form submission. If the validation fails, it may notify
the Client by adding following name/value pairs to the response JSON
Stream
{
"status": "error",
...
"field-name": "<field name>",
"field-message": "<message>",
...
}
Only one validation failure per request can be reported to Client.
The Server is expected to set the status `"status"` to `"error"`, and
the Client is expected to treat the error as explained in [Minimal Response]
and must obey the rules of redirection as explained in [Redirection Response].
The Client must visibly highlight the HTML Form Element that caused the
validation failure.
`"field-name"`
: The value of the `name` attribute of the HTML Form Element that
caused the validation failure.
`"field-message"`
: Message to the User, indicating the nature of the failure.
### Form Group Configuration Response
As part of the server response, the JSON stream may contain a key
`form-update`. This response is used to reconfigure HTML Form Elements
and Form Groups on the clientside, based on conditions evaluated on
the serverside. It contains an array of objects
having the following structure
{
...
"form-update" : [
{
"form-element": "<element_name>",
"hidden": true | false,
"disabled": true | false,
"required": true | false,
"value": <value>
},
...
],
...
}
`"form-element"`
: the name of the HTML Form Element as it appears in the `name` attribute.
`"hidden"`
: whether the Form Group is visible (value: `false`) or invisible (value: `true`).
`"disabled"`
: whether or not the Form Element is disabled HTML-wise.
`"required"`
: whether or not the Form Element receives the HTML5 `required` attribute.
`"value"`
: For textual HTML Form Input elements, it is supposed to be a scalar
value, which is set on the element.
When `"form-element"` references a `<select>` element, a scalar
value selects the corresponding value from the option list. In
order to replace the entire option list, use an array of objects
as value to `"value"`, having this format
[
...
{
"value": 100,
"text": "a",
"selected": true
},
{
"value": 200,
"text": "b",
"selected": false
}
...
]
`"select"` is optional, as is `"text"`. If `"text"` is omitted, it
will be derived from value.
HTML checkboxes are ticked with a `"value"` of `true`. They are
unchecked with `false`.
HTML radio buttons are activated by providing the value of the
radio button `value`-attribute to be activated in `"value"`.
### Redirection Response
Depending on the request, the server may return redirection
information to the Client. It is up to the Client to respect the
redirection information.
The Client must not perform a redirect in case the status in
`"status"` is `"error"`.
The format of redirect information is outlined below
{
...
"redirect": "no" | "url" | "client"
"redirect-url": "<url>"
...
}
`"redirect"`
: type of redirection. `"no"` advises the Client to stay on the
Current Page. `"client"` advises the Client to decide where to
redirect to. `"url"` advices the Client to redirect to the URL
provided in `"redirect-url"`.
`"redirect-url"`
: Used to provide an URL when `"redirect"` is set to `"url"`. It
should be disregarded unless `"redirect"` is set to `"url"`.
## API Endpoints
### Form Update
The Client may request an updated set of Form Group Configuration and
HTLM Element states. In order for the Server to compile the set of
Form Group Configuration and HTML Element states, it requires the
entire HTML Form in the POST body, without any HTML Input Elements of
type `file`.
The Client must include the SIP using an HTML Input Element (most
likely of `type` `hidden`).
Request URL
: api/load.php
Request Method
: POST
URL Parameters
: none
Server Response
: The response contains at least a [Minimal Response]. In addition,
a [Form Group Configuration Response] may be included.
### Form Save
The Client submits the HTML Form for persitent storage to the
Server. The submission should not contain `<input>` HTML Elements of
type `file`.
The Client must include the SIP using an HTML Input Element (most
likely of `type` `hidden`).
Request URL
: api/save.php
Request Method
: POST
URL Parameters
: none
Server Response
: The response contains at least a [Minimal Response]. In addition, a
[Form Group Configuration Response],
[HTML Form Element Validation Response] and/or
[Redirection Response] may be included.
### File Upload
Files are uploaded asynchronously. Each file to be uploaded requires
one request to the Server, using a Multi part form with file content,
parameter `s` containing SIP, and parameter `name` containing the name
of the HTML Form Element.
Request
: api/file.php
Request Method
: POST
URL Parameters
: `action=upload`
Server Response
: The response contains a [Minimal Response].
### File Delete
Files are delete asynchronously. Each file to be delete on the
serverside requires on request to the Server. The parameters
identifying the file to be deleted are sent as part of the POST
body. The SIP of the request is included in the parameter name
`s`. The value of the `name` attribute of the HTML Form Element is
provided in `name`.
Request
: api/file.php
Request Method
: POST
URL Parameters
: `action=delete`
Server Response
: The response contains a [Minimal Response].
### Record delete
Request the deletion of the record identified by the SIP.
Request
: api/delete.php
Request Method
: POST
URL Parameters
: `s=<SIP>`
Server Response
: The response contains a [Minimal Response].
## Glossary
SIP
: tbd
HTML Form Element
: Any `<input>` or `<select>` HTML tag. Synonymous to *Form Element*.
Form Group
: The sourrounding `<div>` containing the `.control-label`,
`.form-control` `<div>`s, and `.help-block` `<p>`.
Client
: Application that enables a user to interact with QFQ, i.e. a Web Browser.
Current Page
: The currently displayed page in the Client.
Redirect
: Issued by the Server. It is a command prompting the Client to
navigate away from the Current Page.
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
var QfqNS = QfqNS || {};
QfqNS.Helper = QfqNS.Helper || {};
(function (n) {
'use strict';
/**
* @deprecated
* @constructor
*/
n.FunctionList = function () {
this.functions = [];
};
n.FunctionList.prototype.addFunction = function (func, thisObj) {
if (typeof func !== "function") {
throw new TypeError("Expected function");
}
if (thisObj) {
this.functions.push([func, thisObj]);
} else {
this.functions.push(func);
}
};
n.FunctionList.prototype.call = function () {
var _arguments = arguments;
this.functions.forEach(function (func) {
if (typeof func === "function") {
func.apply(undefined, _arguments);
} else {
// func is an array [ Function, thisObj ]
func[0].apply(func[1], _arguments);
}
});
};
})(QfqNS.Helper);
\ No newline at end of file
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global describe */
/* global it */
/* global expect */