Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
typo3
qfq
Commits
89618c91
Commit
89618c91
authored
Feb 02, 2017
by
Elias Villiger
Browse files
Merge remote-tracking branch 'origin/crose_work' into elvill_work
parents
9faafc01
bb48638a
Changes
132
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
89618c91
/.plantuml_install
/doc/*.pdf
/.doc_plantuml
/.doc_plantuml
/.support
/.support
/.support_plantuml
/.support_plantuml
/.plantuml
/.plantuml
/doc/plantuml
/doc/plantuml
/extension/Documentation/_make/build
/extension/Documentation/_make/build
/qfq.ini
/doc/phpdoc
/doc/phpdoc
/.idea
/.idea
/node_modules
/node_modules
...
@@ -18,7 +19,7 @@
...
@@ -18,7 +19,7 @@
/css
/css
/fonts
/fonts
/qfq.flowchart.dia.autosave
/qfq.flowchart.dia.autosave
/
extension/config.ini
/
qfq*.zip
/support
/support
/extension/Resources/Public/fonts
/extension/Resources/Public/fonts
/extension/Resources/Public/JavaScript
/extension/Resources/Public/JavaScript
...
...
API.md
deleted
100644 → 0
View file @
9faafc01
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 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>
}
]
}
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.
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'
Gruntfile.js
View file @
89618c91
var
path
=
require
(
'
path
'
);
var
path
=
require
(
'
path
'
);
module
.
exports
=
function
(
grunt
)
{
module
.
exports
=
function
(
grunt
)
{
'
use strict
'
;
var
typo3_css
=
'
extension/Resources/Public/Css/
'
;
var
typo3_css
=
'
extension/Resources/Public/Css/
'
;
var
typo3_js
=
'
extension/Resources/Public/JavaScript/
'
;
var
typo3_js
=
'
extension/Resources/Public/JavaScript/
'
;
var
typo3_fonts
=
'
extension/Resources/Public/fonts/
'
;
var
typo3_fonts
=
'
extension/Resources/Public/fonts/
'
;
...
@@ -147,12 +149,35 @@ module.exports = function (grunt) {
...
@@ -147,12 +149,35 @@ module.exports = function (grunt) {
}
}
]
]
},
},
ChartJS
:
{
files
:
[
{
cwd
:
'
bower_components/Chart.js/dist/
'
,
src
:
[
'
Chart.min.js
'
],
expand
:
true
,
dest
:
typo3_js
,
flatten
:
true
},
{
cwd
:
'
bower_components/Chart.js/dist/
'
,
src
:
[
'
Chart.min.js
'
],
expand
:
true
,
dest
:
"
js/
"
,
flatten
:
true
}
]
},
jqwidgets
:
{
jqwidgets
:
{
files
:
[
files
:
[
{
{
cwd
:
'
bower_components/jqwidgets/jqwidgets/
'
,
cwd
:
'
bower_components/jqwidgets/jqwidgets/
'
,
src
:
[
src
:
[
'
jqx-all.js
'
'
jqx-all.js
'
,
'
globalization/globalize.js
'
],
],
expand
:
true
,
expand
:
true
,
dest
:
typo3_js
,
dest
:
typo3_js
,
...
@@ -162,7 +187,7 @@ module.exports = function (grunt) {
...
@@ -162,7 +187,7 @@ module.exports = function (grunt) {
cwd
:
'
bower_components/jqwidgets/jqwidgets/styles/
'
,
cwd
:
'
bower_components/jqwidgets/jqwidgets/styles/
'
,
src
:
[
src
:
[
'
jqx.base.css
'
,
'
jqx.base.css
'
,
'
jqx.
darkblue
.css
'
'
jqx.
bootstrap
.css
'
],
],
expand
:
true
,
expand
:
true
,
dest
:
typo3_css
,
dest
:
typo3_css
,
...
@@ -183,7 +208,8 @@ module.exports = function (grunt) {
...
@@ -183,7 +208,8 @@ module.exports = function (grunt) {
{
{
cwd
:
'
bower_components/jqwidgets/jqwidgets/
'
,
cwd
:
'
bower_components/jqwidgets/jqwidgets/
'
,
src
:
[
src
:
[
'
jqx-all.js
'
'
jqx-all.js
'
,
'
globalization/globalize.js
'
],
],
expand
:
true
,
expand
:
true
,
dest
:
'
js/
'
,
dest
:
'
js/
'
,
...
@@ -193,7 +219,7 @@ module.exports = function (grunt) {
...
@@ -193,7 +219,7 @@ module.exports = function (grunt) {
cwd
:
'
bower_components/jqwidgets/jqwidgets/styles/
'
,
cwd
:
'
bower_components/jqwidgets/jqwidgets/styles/
'
,
src
:
[
src
:
[
'
jqx.base.css
'
,
'
jqx.base.css
'
,
'
jqx.
darkblue
.css
'
'
jqx.
bootstrap
.css
'
],
],
expand
:
true
,
expand
:
true
,
dest
:
'
css/
'
,
dest
:
'
css/
'
,
...
@@ -209,6 +235,54 @@ module.exports = function (grunt) {
...
@@ -209,6 +235,54 @@ module.exports = function (grunt) {
}
}
]
]
},
},
tinymce
:
{
files
:
[
{
cwd
:
'
bower_components/tinymce/
'
,
src
:
[
'
tinymce.min.js
'
],
expand
:
true
,
dest
:
typo3_js
,
flatten
:
true
},
{
cwd
:
'
bower_components/tinymce/
'
,
src
:
[
'
themes/*/theme.min.js
'
,
'
plugins/*/plugin.min.js
'
,
'
skins/**
'
],
dest
:
typo3_js
,
expand
:
true
,
flatten
:
false
}
]
},
tinymce_devel
:
{
files
:
[
{
cwd
:
'
bower_components/tinymce/
'
,
src
:
[
'
tinymce.min.js
'
],
expand
:
true
,
dest
:
'
js/
'
,
flatten
:
true
},
{
cwd
:
'
bower_components/tinymce/
'
,
src
:
[
'
themes/*/theme.min.js
'
,
'
plugins/*/plugin.min.js
'
,
'
skins/**
'
],
dest
:
'
js/
'
,
expand
:
true
,
flatten
:
false
}
]
},
eventEmitter
:
{
eventEmitter
:
{
files
:
[
files
:
[
{
{
...
@@ -242,9 +316,7 @@ module.exports = function (grunt) {
...
@@ -242,9 +316,7 @@ module.exports = function (grunt) {
}
}
},
},
jshint
:
{
jshint
:
{
all
:
[
all
:
js_sources
'
javascript/src/*.js
'
]
},
},
concat_in_order
:
{
concat_in_order
:
{
debug_standalone
:
{
debug_standalone
:
{
...
@@ -315,8 +387,8 @@ module.exports = function (grunt) {
...
@@ -315,8 +387,8 @@ module.exports = function (grunt) {
}
}
},
},
jasmine
:
{
jasmine
:
{
frontend
:
{
unit
:
{
src
:
[
'
tests/jasmine/spec/*Spec.js
'
],
src
:
[
'
tests/jasmine/
unit/
spec/*Spec.js
'
],
options
:
{
options
:
{
vendor
:
[
vendor
:
[
'
js/jquery.min.js
'
,
'
js/jquery.min.js
'
,
...
@@ -326,18 +398,13 @@ module.exports = function (grunt) {
...
@@ -326,18 +398,13 @@ module.exports = function (grunt) {
'
js/qfq.debug.js
'
'
js/qfq.debug.js
'
],
],
helpers
:
[
'
tests/jasmine/helper/mock-ajax.js
'
],
helpers
:
[
'
tests/jasmine/helper/mock-ajax.js
'
],
template
:
'
tests/jasmine/SpecRunner.tmpl
'
template
:
'
tests/jasmine/
unit/
SpecRunner.tmpl
'
}
}
}
}
},
},
watch
:
{
watch
:
{
scripts
:
{
scripts
:
{
files
:
[
files
:
js_sources
.
concat
([
'
less/*.less
'
]),
'
javascript/src/*.js
'
,
'
javascript/src/Helper/*.js
'
,
'
javascript/src/Element/*.js
'
,
'
less/*.less
'
],
tasks
:
[
'
default
'
],
tasks
:
[
'
default
'
],
options
:
{
options
:
{
spawn
:
true
spawn
:
true
...
...
Makefile
View file @
89618c91
...
@@ -2,7 +2,7 @@ PHPDOC ?= support/pear/phpdoc
...
@@ -2,7 +2,7 @@ PHPDOC ?= support/pear/phpdoc
JSDOC
?=
jsdoc
JSDOC
?=
jsdoc
PKG_VERSION
=
$(
shell
awk
'/version/ { print $$3
}
'
extension/ext_emconf.php |
sed
"s/'//g"
)
PKG_VERSION
=
$(
shell
awk
'/version/ { print $$3
}
'
extension/ext_emconf.php |
sed
"s/'//g"
)
NIGHTLY_DATE
=
$(
shell
date
'+%Y%m%d'
)
NIGHTLY_DATE
=
$(
shell
date
'+%Y%m%d'
)
EXTENSION_CONTENT
=
Classes Configuration Documentation qfq Resources ext_emconf.php ext_localconf.php ext_tables.php config.example.ini
EXTENSION_CONTENT
=
Classes Configuration Documentation qfq Resources ext_emconf.php ext_localconf.php ext_tables.php
ext_icon.png
config.example.ini
all
:
archive t3sphinx
all
:
archive t3sphinx
...
@@ -12,10 +12,10 @@ maintainer-clean:
...
@@ -12,10 +12,10 @@ maintainer-clean:
rm
-f
.bowerpackages .doc_plantuml .npmpackages .phpdocinstall .plantuml_install .support .support_plantuml
rm
-f
.bowerpackages .doc_plantuml .npmpackages .phpdocinstall .plantuml_install .support .support_plantuml
rm
-rf
doc support
rm
-rf
doc support
archive
:
clean qfq
_$(PKG_VERSION)
.zip
archive
:
clean qfq.zip
qfq
_$(PKG_VERSION)
.zip
:
qfq.zip
:
cd
extension
;
zip
-r
../
$@
$(EXTENSION_CONTENT)
-x
config.ini
cd
extension
;
zip
-r
../
$@
$(EXTENSION_CONTENT)
clean
:
clean
:
rm
-f
qfq_
$(PKG_VERSION)
.zip
rm
-f
qfq_
$(PKG_VERSION)
.zip
...
...
README.md
View file @
89618c91
...
@@ -5,18 +5,23 @@ Version: see `extension/ext_emconf.php`
...
@@ -5,18 +5,23 @@ Version: see `extension/ext_emconf.php`
Installation
Installation
------------
------------
*
Take care that the
`php5-mysqlnd`
driver is installed:
*
Ubuntu < 16.04: Take care that the
`php5-mysqlnd`
driver is installed:
*
The following functions are used and are only available with the native driver:
*
See also: http://dev.mysql.com/downloads/connector/php-mysqlnd/
*
If there is a error message "Call to undefined method mysqli_stmt::get_result()",
`php5-mysqlnd`
is not installed or not active.
*
The following functions are used and are only available with the native driver:
```bash
mysqli::get_result (important),
mysqli::get_result (important),
mysqli::fetch_all (nice to have)
mysqli::fetch_all (nice to have)
*
See also: http://dev.mysql.com/downloads/connector/php-mysqlnd/
```
*
If there is a error message "Call to undefined method mysqli_stmt::get_result()",
`php5-mysqlnd`
is not installed or not active.
*
Ubuntu:
*
Ubuntu:
sudo apt-get install php5-mysqlnd
```bash
sudo php5enmod mysqlnd
sudo apt-get install php5-mysqlnd
sudo service apache2 restart
sudo php5enmod mysqlnd
sudo service apache2 restart
```
*
Install extension as regular.
*
Install extension as regular.
*
In
`typo3conf/ext/qfq`
rename
`config.examle.ini`
to
`config.ini`
.
*
In
`typo3conf/ext/qfq`
rename
`config.examle.ini`
to
`config.ini`
.
...
@@ -26,23 +31,28 @@ Installation
...
@@ -26,23 +31,28 @@ Installation
Bootstrap: include by TypoScript
Bootstrap: include by TypoScript
---------
---------
```
script
page.includeCSS {
page.includeCSS {
file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css
file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css
file2 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap-theme.min.css
file2 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap-theme.min.css
file3 = typo3conf/ext/qfq/Resources/Public/Css/jqx.base.css
file3 = typo3conf/ext/qfq/Resources/Public/Css/jqx.base.css
file4 = typo3conf/ext/qfq/Resources/Public/Css/jqx.
darkblue
.css
file4 = typo3conf/ext/qfq/Resources/Public/Css/jqx.
bootstrap
.css
file5 = typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css
file5 = typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css
}
}
page.includeJS {
page.includeJS {
file1 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.min.js
file1 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.min.js
file2 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js
file2 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js
file3 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js
file3 = typo3conf/ext/qfq/Resources/Public/JavaScript/validator.min.js
file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq-min.js
file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js
file4 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js
file5 = typo3conf/ext/qfq/Resources/Public/JavaScript/EventEmitter.min.js
file6 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.min.js
}
}
```
Usage
Usage
-----
-----
...
...
bower.json
View file @
89618c91
...
@@ -18,9 +18,11 @@
...
@@ -18,9 +18,11 @@
],
],
"dependencies"
:
{
"dependencies"
:
{
"bootstrap"
:
"~3.3.6"
,
"bootstrap"
:
"~3.3.6"
,
"jqwidgets"
:
"
*
"
,
"jqwidgets"
:
"
4.2.1
"
,
"tablesorter"
:
"jquery.tablesorter#^2.25.6"
,
"tablesorter"
:
"jquery.tablesorter#^2.25.6"
,
"eventEmitter"
:
"^4.3.0"
,
"eventEmitter"
:
"^4.3.0"
,
"bootstrap-validator"
:
"^0.10.2"
"bootstrap-validator"
:
"^0.11.5"
,
"Chart.js"
:
"^2.1.2"
,
"tinymce"
:
"tinymce-dist#^4.4.3"
}
}
}
}
CODING.md
→
doc/
CODING.md
View file @
89618c91
...
@@ -23,7 +23,7 @@ LOAD
...
@@ -23,7 +23,7 @@ LOAD
*
When qfq starts,
*
When qfq starts,
*
(Form) Looking for a formname at:
*
(Form) Looking for a formname at:
1.
Typo3 Bodytext Element,
1.
Typo3 Bodytext Element,
2.
For the 'SIP' ($_GET['s'])
2.
For the 'SIP' ($_GET
[
's']
=> $S_SESSION['qfq'
][
$_GET['s'
]
]="form=person&r=123"
)
3.
$_GET variables 'form' and 'r' (=recordId) - the parameter 'form' has to be allowed in 'Permit URL Parameter' of
3.
$_GET variables 'form' and 'r' (=recordId) - the parameter 'form' has to be allowed in 'Permit URL Parameter' of
the specified form. This means: load the form to check, if it is allowed to load the form!?
the specified form. This means: load the form to check, if it is allowed to load the form!?
*
If a formname is found, the search stops and the specified form will be processed.
*
If a formname is found, the search stops and the specified form will be processed.
...
@@ -36,12 +36,20 @@ LOAD
...
@@ -36,12 +36,20 @@ LOAD
*
All parameters from active SIP: [$this->store->getStore(STORE_SIP)]
*
All parameters from active SIP: [$this->store->getStore(STORE_SIP)]
*
Check Contstants.php for known Store members
*
Check Contstants.php for known Store members
*
In QuickFormQuery.php the whole Form will be copied to $this->formSpec and depending on further processing, the
elements are
*
In QuickFormQuery.php the whole Form will be copied to
`
$this->formSpec
`
and depending on further processing, the
available in $this->feNative and $this->feAction.
elements are
available in
`
$this->feNative
`
and
`
$this->feAction
`
.
*
The Form specificaton (table form) will be evaluated direct after loading.
*
The Form specificaton (table form) will be evaluated direct after loading.
*
The FormElement specification will be evaluated later on in BuildForm
*
.php
*
The FormElement specification will be evaluated later on in BuildForm
*
.php
*
If a form is called without a SIP (form.permitNew='always'), than a SIP is created on the fly (as a
parameter in the form).
*
Depending on
`r=0`
or
`r>0`
a form submit will do an MySQL
`insert`
or
`update`
later during save.
*
For new records (r=0), clicking on 'save' without closing the form is a tricky situation. Additionally the user might have open multiple
tabs (same form, all r=0) and after saving the record (wihtout closing the form) the user expects that it's ok to edit
the record again and again. Unfortunately, the initial created SIP (before 'form load') is not uniqe anymore (multiple
tabs might contain a saved 'new record'). To guarantee correct saving of r=0 records, a unique on the fly generated SIP
is creatd during form load - individually per browser tab.
SAVE
SAVE
----
----
*
Via wrapper api/save.php
*
Via wrapper api/save.php
...
@@ -51,6 +59,18 @@ SAVE
...
@@ -51,6 +59,18 @@ SAVE
*
Client will handle the response of save.php.
*
Client will handle the response of save.php.
*
Optional redirection initiated by client.
*
Optional redirection initiated by client.
New records
...........
*
r=0 (missing 'r' means r=0)
*
After saving the SIP content will be updated with the new record.
Remember that the SIP in the URL is
*not*
the SIP used in the form to identify the form/record. The form use a
individual 'new record' SIP.
Existing records
................
*
r>0 ('r' have to exist)
DELETE
DELETE
------