From 3822768f4a07a621a910dfbc640a9b1d6c6f881f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 13 Apr 2017 14:42:18 -0600 Subject: [PATCH 01/18] Add proper form process for dynamicly added pages --- form.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/form.php b/form.php index 103b92b9..4b084b6e 100644 --- a/form.php +++ b/form.php @@ -165,7 +165,7 @@ public function onPagesInitialized() $this->enable([ 'onTwigPageVariables' => ['onTwigVariables', 0], 'onTwigSiteVariables' => ['onTwigVariables', 0], - 'onFormFieldTypes' => ['onFormFieldTypes', 0] + 'onFormFieldTypes' => ['onFormFieldTypes', 0], ]); // Regenerate list of flat_forms if not already populated @@ -253,6 +253,8 @@ public function onTwigVariables(Event $event = null) $page = $this->grav['page']; } + $header = $page->header(); + // get route to calculated page $page_route = $page->route(); // get route to current page @@ -266,6 +268,8 @@ public function onTwigVariables(Event $event = null) $found_forms = $this->forms[$page_route]; } elseif (isset($this->forms[$current_page_route])) { $found_forms = $this->forms[$current_page_route]; + } elseif (isset($header->form)) { + $found_forms = [new Form($page)]; } $this->grav['twig']->twig_vars['form'] = array_shift($found_forms); From 980bc035bcf9ed3329f3575f39e07a9b90983464 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 13 Apr 2017 14:42:44 -0600 Subject: [PATCH 02/18] Properly initialize front-end forms to support advanced functionality --- classes/form.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/classes/form.php b/classes/form.php index 997b7a9a..0a7fd643 100644 --- a/classes/form.php +++ b/classes/form.php @@ -155,7 +155,8 @@ public function unserialize($data) $rules = $this->rules; $blueprint = function() use ($name, $items, $rules) { - return new Blueprint($name, ['form' => $items, 'rules' => $rules]); + $blueprint = new Blueprint($name, ['form' => $items, 'rules' => $rules]); + return $blueprint->load()->init(); }; $this->data = new Data($data['data'], $blueprint); @@ -225,20 +226,16 @@ public function reset() $items = $this->items; $rules = $this->rules; + $blueprint = function() use ($name, $items, $rules) { - return new Blueprint($name, ['form' => $items, 'rules' => $rules]); + $blueprint = new Blueprint($name, ['form' => $items, 'rules' => $rules]); + return $blueprint->load()->init(); }; - if (method_exists($blueprint, 'load')) { - // init the form to process directives - $blueprint->load()->init(); - - // fields set to processed blueprint fields - $this->fields = $blueprint->fields(); - } - $this->data = new Data($this->header_data, $blueprint); $this->values = new Data(); + $this->fields = null; + $this->fields = $this->fields(); // Fire event $grav->fireEvent('onFormInitialized', new Event(['form' => $this])); From 1901ba0d3551f2328afe817771ea7e07dce51b09 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 13 Apr 2017 14:44:43 -0600 Subject: [PATCH 03/18] Updated changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a42217ca..1f21eeb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v2.4.0 +## 04/13/2017 + +1. [](#new) + * Added the ability for front-end forms to use advanced blueprint features such as `data-*@` and `config-*@` + * Added support for dynamically added pages to process forms properly + # v2.3.1 ## 03/23/2017 From ef4a70b1431ca3d7f9555789d815816da515afb7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 13 Apr 2017 20:24:53 -0600 Subject: [PATCH 04/18] Always enable form events if `$_POST` is not empty https://github.com/getgrav/grav-plugin-login/issues/101 --- CHANGELOG.md | 2 ++ form.php | 17 ++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f21eeb7..45a614ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ 1. [](#new) * Added the ability for front-end forms to use advanced blueprint features such as `data-*@` and `config-*@` * Added support for dynamically added pages to process forms properly +1. [](#bugfix) + * Always process form events as long as a `$_POST` exists [login #101](https://github.com/getgrav/grav-plugin-login/issues/101) # v2.3.1 ## 03/23/2017 diff --git a/form.php b/form.php index 4b084b6e..1398c316 100644 --- a/form.php +++ b/form.php @@ -141,6 +141,14 @@ public function onPagesInitialized() $this->flat_forms = $flat_forms; } + // Enable form events if there's a POST + if (!empty($_POST)) { + $this->enable([ + 'onFormProcessed' => ['onFormProcessed', 0], + 'onFormValidationError' => ['onFormValidationError', 0] + ]); + } + if ($this->isAdmin() && !empty($_POST)) { $page = $this->grav['page']; @@ -153,10 +161,6 @@ public function onPagesInitialized() if (isset($header->form) && is_array($header->form)) { // Create form $this->form = new Form($page); - $this->enable([ - 'onFormProcessed' => ['onFormProcessed', 0], - 'onFormValidationError' => ['onFormValidationError', 0] - ]); $this->form->post(); } @@ -181,11 +185,6 @@ public function onPagesInitialized() // Handle posting if needed. if (!empty($_POST)) { - $this->enable([ - 'onFormProcessed' => ['onFormProcessed', 0], - 'onFormValidationError' => ['onFormValidationError', 0] - ]); - $current_form_name = $this->getFormName($this->grav['page']); $this->json_response = []; From 18decb463ab9efb6319fc3e118aed771f7d127ff Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 13 Apr 2017 20:25:10 -0600 Subject: [PATCH 05/18] Updated blueprints --- blueprints.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints.yaml b/blueprints.yaml index fb247b6f..659a9f73 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -12,7 +12,7 @@ bugs: https://github.com/getgrav/grav-plugin-form/issues license: MIT dependencies: - - { name: grav, version: '>=1.1.16' } + - { name: grav, version: '>=1.2.3' } form: validation: strict From cb8404f7cbb6ecff89e8cd1b884150c8b5a4fb79 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:17:19 -0600 Subject: [PATCH 06/18] various fixes for file field --- templates/forms/fields/file/file.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/forms/fields/file/file.html.twig b/templates/forms/fields/file/file.html.twig index 29dd5a59..d237f72b 100644 --- a/templates/forms/fields/file/file.html.twig +++ b/templates/forms/fields/file/file.html.twig @@ -36,7 +36,7 @@ {% set blueprint_name = type ~ '/' ~ blueprint_name %} {% endif %} {% set blueprint = base64_encode(blueprint_name) %} - {% set real_path = global.admin.getPagePathFromToken(path) %} + {% set real_path = global.form.getPagePathFromToken(path) %} {% set remove = uri.addNonce(global.base_url_relative ~ '/media.json' ~ '/route' ~ config.system.param_sep ~ base64_encode(global.base_path ~ '/' ~ real_path) ~ @@ -72,7 +72,7 @@ {% for path, file in value %} {{ _self.preview(path, file, _context) }} {% endfor %} - {% include 'forms/fields/hidden/hidden.html.twig' with {field: {name: '_json.' ~ field.name}, value:value|raw|json_encode} %} + {% include 'forms/fields/hidden/hidden.html.twig' with {field: {name: '_json.' ~ field.name}, value:value|json_encode|e('html_attr')} %} {% do assets.addJs('jquery', 101) %} From f56384c29c2ca57857cea46dbcf1487c84dec5d7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:23:59 -0600 Subject: [PATCH 07/18] Added a default ajax handler --- templates/form.json.twig | 6 +----- templates/forms/ajax.json.twig | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 templates/forms/ajax.json.twig diff --git a/templates/form.json.twig b/templates/form.json.twig index 28498895..f6ba33fc 100644 --- a/templates/form.json.twig +++ b/templates/form.json.twig @@ -1,5 +1 @@ -{% if form_json_response %} -{{ form_json_response|json_encode|raw }} -{% else %} -{} -{% endif %} +{% extends 'forms/ajax.json.twig' %} diff --git a/templates/forms/ajax.json.twig b/templates/forms/ajax.json.twig new file mode 100644 index 00000000..ccec0390 --- /dev/null +++ b/templates/forms/ajax.json.twig @@ -0,0 +1,5 @@ +{% if form_json_response %} +{{ form_json_response|json_encode|raw }} +{% else %} +{} +{% endif %} \ No newline at end of file From 95a822f682076d5df8898474b5b2cd67872e40c6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:24:11 -0600 Subject: [PATCH 08/18] Added new 'avatar' display field --- templates/forms/fields/avatar/avatar.html.twig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 templates/forms/fields/avatar/avatar.html.twig diff --git a/templates/forms/fields/avatar/avatar.html.twig b/templates/forms/fields/avatar/avatar.html.twig new file mode 100644 index 00000000..33862880 --- /dev/null +++ b/templates/forms/fields/avatar/avatar.html.twig @@ -0,0 +1,5 @@ +{% if form.data.avatar %} + +{% else %} + +{% endif %} \ No newline at end of file From 935948017fa7aa971b2f737cd53e7a975f9ad2ea Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:24:50 -0600 Subject: [PATCH 09/18] Moved twig events to always process --- form.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/form.php b/form.php index 1398c316..a2f6c430 100644 --- a/form.php +++ b/form.php @@ -54,8 +54,6 @@ public function onPluginsInitialized() { require_once(__DIR__ . '/classes/form.php'); - - if ($this->isAdmin()) { $this->enable([ 'onPagesInitialized' => ['onPagesInitialized', 0] @@ -67,6 +65,8 @@ public function onPluginsInitialized() 'onPageProcessed' => ['onPageProcessed', 0], 'onPagesInitialized' => ['onPagesInitialized', 0], 'onTwigInitialized' => ['onTwigInitialized', 0], + 'onTwigPageVariables' => ['onTwigVariables', 0], + 'onTwigSiteVariables' => ['onTwigVariables', 0], 'onFormValidationProcessed' => ['onFormValidationProcessed', 0], ]); } @@ -167,8 +167,6 @@ public function onPagesInitialized() } elseif ($this->forms) { $this->enable([ - 'onTwigPageVariables' => ['onTwigVariables', 0], - 'onTwigSiteVariables' => ['onTwigVariables', 0], 'onFormFieldTypes' => ['onFormFieldTypes', 0], ]); From 2269af55e6b1983bf9e7e6952099cf46049275a0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:25:17 -0600 Subject: [PATCH 10/18] Allow manually processing forms to upload files --- form.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/form.php b/form.php index a2f6c430..ddf871a2 100644 --- a/form.php +++ b/form.php @@ -185,16 +185,15 @@ public function onPagesInitialized() $current_form_name = $this->getFormName($this->grav['page']); $this->json_response = []; + $this->form = $this->getFormByName($current_form_name); - if ($this->form = $this->getFormByName($current_form_name)) { - if ($this->grav['uri']->extension() === 'json' && isset($_POST['__form-file-uploader__'])) { - $this->json_response = $this->form->uploadFiles(); - } else { - $this->form->post(); - $submitted = true; - } - } elseif (isset($this->grav['page']->header()->form)) { + if (!$this->form && isset($this->grav['page']->header()->form)) { $this->form = new Form($this->grav['page']); + } + + if ($this->grav['uri']->extension() === 'json' && isset($_POST['__form-file-uploader__'])) { + $this->json_response = $this->form->uploadFiles(); + } else { $this->form->post(); $submitted = true; } From 7bc562b61eca4f7b0d12bee5ceb28703d47ff791 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:25:33 -0600 Subject: [PATCH 11/18] Method to get all data --- classes/form.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/classes/form.php b/classes/form.php index 0a7fd643..f2f732dc 100644 --- a/classes/form.php +++ b/classes/form.php @@ -321,6 +321,16 @@ public function getValue($name) return $this->values->get($name); } + /** + * Get all data + * + * @return Data + */ + public function getData() + { + return $this->data; + } + /** * Set value of given variable in the data array * From 97e0dcfddb6a74a312ad690b3f99ded58fa566b0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:25:51 -0600 Subject: [PATCH 12/18] Code cleanup --- classes/form.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/form.php b/classes/form.php index f2f732dc..4607df0b 100644 --- a/classes/form.php +++ b/classes/form.php @@ -397,7 +397,7 @@ public function uploadFiles() // we need to move the file at this stage or else // it won't be available upon save later on // since php removes it from the upload location - $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); + $tmp_dir = $grav['locator']->findResource('tmp://', true, true); $tmp_file = $upload->file->tmp_name; $tmp = $tmp_dir . '/uploaded-files/' . basename($tmp_file); @@ -619,6 +619,7 @@ public function post() public function getPagePathFromToken($path) { $grav = Grav::instance(); + $path_parts = pathinfo($path); $basename = ''; From a000853a53dd982a0bf5a62481ba3601d1665603 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:26:18 -0600 Subject: [PATCH 13/18] Handle null with session-based form --- templates/forms/default/form.html.twig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/forms/default/form.html.twig b/templates/forms/default/form.html.twig index 00068f1d..ee3c93dd 100644 --- a/templates/forms/default/form.html.twig +++ b/templates/forms/default/form.html.twig @@ -1,3 +1,7 @@ +{% if form is null %} + {% set form = grav.session.getFlashObject('form') %} +{% endif %} + {% if form.message %} {% if form.inline_errors and form.messages %}

{{ "FORM.VALIDATION_FAIL"|t|raw }}

From 46ee5cad23f301d6d6e8d7e538c399bdcbbd5c49 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 17 Apr 2017 16:26:34 -0600 Subject: [PATCH 14/18] Support task in button types --- templates/forms/default/form.html.twig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/forms/default/form.html.twig b/templates/forms/default/form.html.twig index ee3c93dd..a2ab0eb7 100644 --- a/templates/forms/default/form.html.twig +++ b/templates/forms/default/form.html.twig @@ -63,7 +63,12 @@ class="{{ button.classes|default('button') }}" {% endblock %} {% if button.disabled %}disabled="disabled"{% endif %} + type="{{ button.type|default('submit') }}" + + {% if button.task %} + name="task" value="{{ button.task }}" + {% endif %} > {{ button.value|t|default('Submit') }} From c5902ed81845fdf80720d4273c5bbeeed1e484eb Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 18 Apr 2017 10:46:49 -0600 Subject: [PATCH 15/18] Fixed issue with nested fileds not showing up in `data.*.twig` templates --- templates/forms/default/data.html.twig | 62 +++++++++++++++----------- templates/forms/default/data.txt.twig | 27 ++++++----- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/templates/forms/default/data.html.twig b/templates/forms/default/data.html.twig index e5186082..9f54f282 100644 --- a/templates/forms/default/data.html.twig +++ b/templates/forms/default/data.html.twig @@ -1,29 +1,39 @@ -{% for index, field in form.fields %} - {% set input = attribute(field, "input@") %} - {% if input is null or input == true %} - {% block field %} -
- {% block field_label %} - {{ field.label|t|e }}: - {% endblock %} +{% macro render_field(form, fields) %} + {% for index, field in fields %} + {% set input = attribute(field, "input@") %} + {% if input is null or input == true %} + {% if form.value(field.name) %} + {% block field %} +
+ {% block field_label %} + {{ field.label|t|e }}: + {% endblock %} - {% block field_value %} - {% if field.type == 'checkboxes' %} -
    - {% for value in form.value(field.name) %} -
  • {{ field.options[value]|e }}
  • - {% endfor %} -
- {% elseif field.type == 'checkbox' %} - {{ (form.value(field.name) == 1) ? "PLUGIN_FORM.YES"|t|e : "PLUGIN_FORM.NO"|t|e }} - {% elseif field.type == 'select' %} - {{ field.options[form.value(field.name)]|e }} - {% else %} - {{ string(form.value(field.name)|e)|nl2br }} - {% endif %} + {% block field_value %} + {% if field.type == 'checkboxes' %} +
    + {% for value in form.value(field.name) %} +
  • {{ field.options[value]|e }}
  • + {% endfor %} +
+ {% elseif field.type == 'checkbox' %} + {{ (form.value(field.name) == 1) ? "PLUGIN_FORM.YES"|t|e : "PLUGIN_FORM.NO"|t|e }} + {% elseif field.type == 'select' %} + {{ field.options[form.value(field.name)]|e }} + {% else %} + {{ string(form.value(field.name)|e)|nl2br }} + {% endif %} + {% endblock %} +
{% endblock %} -
- {% endblock %} + {% endif %} + {% else %} + {% if field.fields is iterable %} + {{ _self.render_field(form, field.fields) }} + {% endif %} + {% endif %} + {% endfor %} +{% endmacro %} + +{{ _self.render_field(form, form.fields) }} - {% endif %} -{% endfor %} \ No newline at end of file diff --git a/templates/forms/default/data.txt.twig b/templates/forms/default/data.txt.twig index 93c92a57..ff9eb864 100644 --- a/templates/forms/default/data.txt.twig +++ b/templates/forms/default/data.txt.twig @@ -1,11 +1,16 @@ -{% autoescape false %} - -{% for index, field in form.fields %} -{% set input = attribute(field, "input@") %} -{% if input is null or input == true %} -{% set value = form.value(field.name ?? index) %} -{{ field.name ?? index }}: {{ string((value is iterable ? value|json_encode : value)|nl2br)|replace({"\n":' ', "\r":' '}) }} -{% endif %} -{% endfor %} - -{% endautoescape %} \ No newline at end of file +{%- macro render_field(form, fields) %} +{%- for index, field in fields %} + {%- set input = attribute(field, "input@") %} + {%- if input is null or input == true %} + {%- set value = form.value(field.name ?? index) %} + {{- field.name ?? index }}: {{ string((value is iterable ? value|json_encode : value)) ~ "\r\n" }} + {%- else %} + {%- if field.fields is iterable %} + {{- _self.render_field(form, field.fields) }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- endmacro %} +{%- autoescape false %} +{{- _self.render_field(form, form.fields) ~ "\r\n" }} +{%- endautoescape %} \ No newline at end of file From 9d833e85614efba79c63b5477886312ec3fc35e3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 18 Apr 2017 10:51:58 -0600 Subject: [PATCH 16/18] Added support for append/prepend to number field --- templates/forms/fields/number/number.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/forms/fields/number/number.html.twig b/templates/forms/fields/number/number.html.twig index 0a0c14d7..116c7cab 100644 --- a/templates/forms/fields/number/number.html.twig +++ b/templates/forms/fields/number/number.html.twig @@ -1,4 +1,4 @@ -{% extends "forms/field.html.twig" %} +{% extends "forms/fields/text/text.html.twig" %} {% block input_attributes %} type="number" From 4378b2a968dc851513b3866183386e2adf898dfa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 18 Apr 2017 11:07:03 -0600 Subject: [PATCH 17/18] updated changelog --- CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a614ab..71d3282d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,23 @@ # v2.4.0 -## 04/13/2017 +## 04/xx/2017 1. [](#new) * Added the ability for front-end forms to use advanced blueprint features such as `data-*@` and `config-*@` * Added support for dynamically added pages to process forms properly + * Added a new avatar field for displaying account avatar + * Added method to get all `data` from a form + * Support `task` in button types +1. [](#improved) + * Added a new default ajax handler twig template + * Moved twig events to always process even if forms are not defined + * Some code cleanup + * Handle `null` with session-based form + * Added support for append/prepend to number field 1. [](#bugfix) * Always process form events as long as a `$_POST` exists [login #101](https://github.com/getgrav/grav-plugin-login/issues/101) + * Various fixes for `file` field + * Allow manually added pages to process forms and upload files + * Fixed issue with nested fileds not showing up in `data.*.twig` templates # v2.3.1 ## 03/23/2017 From 8b6344ebd2b55ae8c594d2da1ca6f1b151e3745d Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 19 Apr 2017 15:49:15 -0600 Subject: [PATCH 18/18] Prepare for release --- CHANGELOG.md | 2 +- blueprints.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d3282d..6e5cc764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v2.4.0 -## 04/xx/2017 +## 04/19/2017 1. [](#new) * Added the ability for front-end forms to use advanced blueprint features such as `data-*@` and `config-*@` diff --git a/blueprints.yaml b/blueprints.yaml index 659a9f73..c3163811 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,5 @@ name: Form -version: 2.3.1 +version: 2.4.0 description: Enables the forms handling icon: check-square author: