From 4f7e350945a59eab53b07d4225b5a0bbb5fad376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 18 May 2018 17:54:12 +0200 Subject: [PATCH] adding a collection type for chill --- Form/Type/ChillCollectionType.php | 53 ++++++++++++ Resources/public/js/collection/collections.js | 81 +++++++++++++++++++ Resources/views/Form/fields.html.twig | 16 ++++ chill.webpack.config.js | 1 + 4 files changed, 151 insertions(+) create mode 100644 Form/Type/ChillCollectionType.php create mode 100644 Resources/public/js/collection/collections.js diff --git a/Form/Type/ChillCollectionType.php b/Form/Type/ChillCollectionType.php new file mode 100644 index 000000000..d653794c7 --- /dev/null +++ b/Form/Type/ChillCollectionType.php @@ -0,0 +1,53 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +namespace Chill\MainBundle\Form\Type; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormView; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Form\FormInterface; + +/** + * + * + * @author Julien Fastré + */ +class ChillCollectionType extends AbstractType +{ + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefaults([ + 'button_add_label' => 'Add an entry', + 'button_remove_label' => 'Remove entry' + ]); + } + + public function buildView(FormView $view, FormInterface $form, array $options) + { + $view->vars['button_add_label'] = $options['button_add_label']; + $view->vars['button_remove_label'] = $options['button_remove_label']; + $view->vars['allow_delete'] = (int) $options['allow_delete']; + $view->vars['allow_add'] = (int) $options['allow_add']; + } + + public function getParent() + { + return \Symfony\Component\Form\Extension\Core\Type\CollectionType::class; + } +} diff --git a/Resources/public/js/collection/collections.js b/Resources/public/js/collection/collections.js new file mode 100644 index 000000000..820df1efd --- /dev/null +++ b/Resources/public/js/collection/collections.js @@ -0,0 +1,81 @@ +/** + * Exemple d'utilisation + * + * ```html + *
    + * {% for formation in form.formations %} + *
  • + *
    + * {{ form_row(formation) }} + *
    + *
  • + * {% endfor %} + *
+ * + * + * ``` + * + * Le javascript est initialisé dans `forms.js` + * + */ +var handleAdd = function(button) { + var + form_name = button.dataset.collectionAddTarget, + prototype = button.dataset.formPrototype, + collection = document.querySelector('ul[data-collection-name="'+form_name+'"]'), + entry = document.createElement('li'), + counter = collection.childNodes.length, + content + ; + content = prototype.replace(new RegExp('__name__', 'g'), counter); + entry.innerHTML = content; + initializeRemove(collection, entry); + collection.appendChild(entry); +}; + +var initializeRemove = function(collection, entry) { + var + button = document.createElement('button'), + content = collection.dataset.collectionButtonRemoveLabel, + allowDelete = collection.dataset.collectionAllowDelete + ; + + if (allowDelete == '0') { + return; + } + + button.textContent = content; + + button.addEventListener('click', function(e) { + e.preventDefault(); + entry.remove(); + console.log('click remove'); + }); + + entry.appendChild(button); +}; + +window.addEventListener('load', function() { + var + addButtons = document.querySelectorAll("button[data-collection-add-target]"), + collections = document.querySelectorAll("ul[data-collection-name]") + ; + + for (let i = 0; i < addButtons.length; i ++) { + let addButton = addButtons[i]; + addButton.addEventListener('click', function(e) { + e.preventDefault(); + console.log('click'); + handleAdd(e.target); + }); + } + + for (let i = 0; i < collections.length; i ++) { + let entries = collections[i].querySelectorAll('li'), entry; + + for (let j = 0; j < entries.length; j ++) { + initializeRemove(collections[i], entries[j]); + } + } +}); + diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig index c7efe69ff..324aa41bd 100644 --- a/Resources/views/Form/fields.html.twig +++ b/Resources/views/Form/fields.html.twig @@ -158,3 +158,19 @@ {{ form_row(form.order) }} {% endblock %} + +{% block chill_collection_widget %} +
    +
  • +
    + {% for entry in form %} + {{ form_widget(entry) }} + {% endfor %} +
    +
  • +
+ + {% if form.vars.allow_add == 1 %} + + {% endif %} +{% endblock %} \ No newline at end of file diff --git a/chill.webpack.config.js b/chill.webpack.config.js index e6f4c8be8..8481e4011 100644 --- a/chill.webpack.config.js +++ b/chill.webpack.config.js @@ -21,6 +21,7 @@ global.chill = chill; require('./Resources/public/sass/scratch.scss'); require('./Resources/public/css/chillmain.css'); require('./Resources/public/css/pikaday.css'); +require('./Resources/public/js/collection/collections.js'); //require('./Resources/public/css/scratch.css'); //require('./Resources/public/css/select2/select2.css'); require('select2/dist/css/select2.css');