JavaScript options: overview

This page let you try many of the available Javascript options on the fly.

Other options depends on your markup, they are available in the "Javascript Options" menu.

Choose your options
Should be a link
Should be a link
Should be a link
Should be a link
Should be a link
Should be a number
Should be a number
Should be a number
<?php

namespace Fuz\AppBundle\Base;

use Fuz\AppBundle\Entity\Value;
use Fuz\AppBundle\Form\ValueType;
use Fuz\QuickStartBundle\Base\BaseController as QuickStartBase;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\HttpFoundation\Request;

class BaseController extends QuickStartBase
{
    protected function createContextSample(Request $request, $name = 'form', $values = ['a', 'b', 'c'])
    {
        $data = ['values' => $values];

        $form = $this
           ->get('form.factory')
           ->createNamedBuilder($name, Type\FormType::class, $data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'    => Type\TextType::class,
               'label'         => 'Add, move, remove values and press Submit.',
               'entry_options' => [
                   'label' => 'Value',
               ],
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'attr'         => [
                   'class' => "{$name}-collection",
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            $name         => $form->createView(),
            "{$name}Data" => $data,
        ];
    }

    protected function createAdvancedContextSample(Request $request, $name = 'advancedForm')
    {
        $a = new Value('a');
        $b = new Value('b');
        $c = new Value('c');

        $data = ['values' => [$a, $b, $c]];

        $form = $this
           ->get('form.factory')
           ->createNamedBuilder($name, Type\FormType::class, $data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'   => ValueType::class,
               'label'        => 'Add, move, remove values and press Submit.',
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'required'     => false,
               'attr'         => [
                   'class' => "{$name}-collection",
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            $name         => $form->createView(),
            "{$name}Data" => $data,
        ];
    }
}
<?php

namespace Fuz\AppBundle\Controller;

use Fuz\AppBundle\Base\BaseController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/options")
 */
class OptionsController extends BaseController
{

    /**
     * JavaScript options
     *
     * An overview of almost all options that you
     * can enable/disable/customize on the fly.
     *
     * @Route("/overview", name="overview")
     * @Template()
     */
    public function overviewAction(Request $request)
    {
        return $this->createContextSample($request);
    }

    /**
     * JavaScript options
     *
     * Customized buttons
     *
     * @Route("/customButtons", name="customButtons")
     * @Template()
     */
    public function customButtonsAction(Request $request)
    {
        return $this->createContextSample($request);
    }

    /**
     * JavaScript options
     *
     * Disable buttons you don't want
     *
     * @Route("/enableButtons", name="enableButtons")
     * @Template()
     */
    public function enableButtonsAction(Request $request)
    {
        return array_merge(
           $this->createContextSample($request), $this->createAdvancedContextSample($request)
        );
    }

    /**
     * JavaScript options
     *
     * Control the minimum and maximum of allowed number of elements
     *
     * @Route("/numberCollectionElements", name="numberCollectionElements")
     * @Template()
     */
    public function numberCollectionElementsAction(Request $request)
    {
        return array_merge(
           $this->createContextSample($request), $this->createAdvancedContextSample($request)
        );
    }

    /**
     * JavaScript options
     *
     * Add the button close to each collection elements or only at the bottom
     *
     * @Route("/addButtonAtTheBottom", name="addButtonAtTheBottom")
     * @Template()
     */
    public function addButtonAtTheBottomAction(Request $request)
    {
        return array_merge(
           $this->createContextSample($request, 'enabled'), $this->createContextSample($request, 'disabled')
        );
    }

    /**
     * JavaScript options
     *
     * Run a callback before or after adding, deleting and moving elements
     *
     * @Route("/eventCallbacks", name="eventCallbacks")
     * @Template()
     */
    public function eventCallbacksAction(Request $request)
    {
        return array_merge(
           $this->createContextSample($request, 'eventsBefore'), $this->createContextSample($request, 'eventsAfter')
        );
    }

    /**
     * JavaScript options
     *
     * Use this plugin without the attached form-theme
     *
     * @Route("/withoutFormTheme", name="withoutFormTheme")
     * @Template()
     */
    public function withoutFormThemeAction(Request $request)
    {
        return $this->createContextSample($request);
    }

    /**
     * JavaScript options
     *
     * Initialize a collection with a given minimum number of elements
     *
     * @Route("/givenMinimumElements", name="givenMinimumElements")
     * @Template()
     */
    public function givenMinimumElementsAction(Request $request)
    {
        return $this->createContextSample($request, 'form', []);
    }

    /**
     * JavaScript options
     *
     * Hide move-up on the first item and move-down on the last one
     *
     * @Route("/hideMoveUpDown", name="hideMoveUpDown")
     * @Template()
     */
    public function hideMoveUpDownAction(Request $request)
    {
        return $this->createContextSample($request, 'form');
    }

    /**
     * JavaScript options
     *
     * Drag & Drop allow to get rid of "move up" and "move down" buttons
     *
     * @Route("/dragAndDrop", name="dragAndDrop")
     * @Template()
     */
    public function dragAndDropAction(Request $request)
    {
        return [
            'disabled'    => $this->createAdvancedContextSample($request, 'disabled'),
            'nobuttons'   => $this->createAdvancedContextSample($request, 'nobuttons'),
            'moreoptions' => $this->createAdvancedContextSample($request, 'moreoptions'),
            'startupdate' => $this->createAdvancedContextSample($request, 'startupdate'),
        ];
    }

    /**
     * JavaScript options
     *
     * Run a callback before and after collection initialization
     *
     * @Route("/initCallbacks", name="initCallbacks")
     * @Template()
     */
    public function initCallbacksAction(Request $request)
    {
        return $this->createContextSample($request);
    }

    /**
     * JavaScript options
     *
     * Put buttons to custom locations in your page.
     *
     * @Route(
     *      "/buttons-custom-location",
     *      name = "buttonsCustomLocation"
     * )
     * @Template()
     */
    public function buttonsCustomLocationAction(Request $request)
    {
        return array_merge(
           $this->createContextSample($request, 'collectionA'), $this->createContextSample($request, 'collectionB'), $this->createContextSample($request, 'collectionC')
        );
    }

    /**
     * JavaScript options
     *
     * Enable / disable fade animation when adding / removing
     * collection elements.
     *
     * @Route("/fadeInFadeOut", name="fadeInFadeOut")
     * @Template()
     */
    public function fadeInFadeOutAction(Request $request)
    {
        return $this->createContextSample($request);
    }
}

{% block ValueType_label %}{% endblock %}
{% block ValueType_errors %}{% endblock %}

{% block ValueType_widget %}

    <div class="row">
        <div class="col-md-5">
            {{ form_widget(form.value) }}
        </div>
        <div class="col-md-3">
            <a href="#" class="collection-up btn btn-default" title="Move element up"><span class="glyphicon glyphicon-arrow-up"></span></a>
            <a href="#" class="collection-down btn btn-default" title="Move element down"><span class="glyphicon glyphicon-arrow-down"></span></a>
        </div>
        <div class="col-md-3">
            <a href="#" class="collection-remove btn btn-default" title="Delete element"><span class="glyphicon glyphicon-trash"></span></a>
            <a href="#" class="collection-add btn btn-default" title="Add element"><span class="glyphicon glyphicon-plus-sign"></span></a>
        </div>
        <div class="col-md-1">
            <a href="#" class="collection-duplicate btn btn-default" title="Duplicate element"><span class="glyphicon glyphicon-th-large"></span></a>
        </div>
    </div>

{% endblock %}
{% extends 'FuzAppBundle::layout.html.twig' %}

{% block extra_js %}
    <script src="{{ asset('js/jquery.collection.js') }}"></script>
{% endblock %}

{% block title %}JavaScript options: overview{% endblock %}

{% block body %}

    <h2>{{ block('title') }}</h2>

    <p>This page let you try many of the available Javascript options on the fly.</p>

    <p>Other options depends on your markup, they are available in the "Javascript Options" menu.</p>

    <div class="row">

        <div class="col-md-8">

            <form class="form-horizontal" onsubmit="return false;">
                <fieldset>

                    <legend>Choose your options</legend>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="enable-buttons">Tickable options</label>
                        <div class="col-md-4">
                            <div class="checkbox">
                                <label for="enable-up">
                                    <input name="enable-up" id="enable-up" class="reload-collection" type="checkbox" checked>
                                    Enable Move Up button
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="enable-down">
                                    <input name="enable-buttons" id="enable-down" class="reload-collection" type="checkbox" checked>
                                    Enable Move Down button
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="enable-add">
                                    <input name="enable-buttons" id="enable-add" class="reload-collection" type="checkbox" checked>
                                    Enable Add button
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="enable-remove">
                                    <input name="enable-buttons" id="enable-remove" class="reload-collection" type="checkbox" checked>
                                    Enable Remove button
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="enable-duplicate">
                                    <input name="enable-buttons" id="enable-duplicate" class="reload-collection" type="checkbox" checked>
                                    Enable Duplicate button
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="add-at-the-end">
                                    <input name="add-at-the-end" id="add-at-the-end" class="reload-collection" type="checkbox">
                                    Move Add button at the bottom
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="drag-drop">
                                    <input name="drag-drop" id="drag-drop" class="reload-collection" type="checkbox" checked>
                                    Enable Drag & Drop
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="fade-in">
                                    <input name="fade-in" id="fade-in" class="reload-collection" type="checkbox" checked>
                                    Enable Fade In animation
                                </label>
                            </div>
                            <div class="checkbox">
                                <label for="fade-out">
                                    <input name="fade-out" id="fade-out" class="reload-collection" type="checkbox" checked>
                                    Enable Fade Out animation
                                </label>
                            </div>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="up-layout">Change Up layout</label>
                        <div class="col-md-4">
                            <input
                                id="up-layout"
                                value='<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-arrow-up"></a>'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a link</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="down-layout">Change Down layout</label>
                        <div class="col-md-4">
                            <input
                                id="down-layout"
                                value='<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-arrow-down"></a>'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a link</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="add-layout">Change Add layout</label>
                        <div class="col-md-4">
                            <input
                                id="add-layout"
                                value='<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-plus-sign"></a>'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a link</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="remove-layout">Change Remove layout</label>
                        <div class="col-md-4">
                            <input
                                id="remove-layout"
                                value='<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-trash"></a>'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a link</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="duplicate-layout">Change Duplicate layout</label>
                        <div class="col-md-4">
                            <input
                                id="duplicate-layout"
                                value='<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-th-large"></a>'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a link</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="min-elements">Minimum of elements</label>
                        <div class="col-md-4">
                            <input
                                id="min-elements"
                                value='0'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a number</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="max-elements">Maximum of elements</label>
                        <div class="col-md-4">
                            <input
                                id="max-elements"
                                value='5'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a number</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label" for="init-witn-n-elements">Initialize with N elements</label>
                        <div class="col-md-4">
                            <input
                                id="init-witn-n-elements"
                                value='0'
                                class="form-control input-md reload-collection"
                                type="text">
                            <span class="help-block">Should be a number</span>
                        </div>
                    </div>

                </fieldset>
            </form>

            {{
                tabs([
                    'Base/BaseController.php',
                    'Controller/OptionsController.php',
                    'Resources/views/Options/overview.html.twig',
                    'Resources/views/Options/options-theme.html.twig',
                ])
            }}

        </div>

        <div class="col-md-4 follow-scroll">
            <fieldset>
                <legend>Result</legend>

                {{ form(form) }}

                {% for value in formData.values %}
                    <p>Value : {{ value }}</p>
                {% endfor %}
            </fieldset>
        </div>
    </div>

{% endblock %}

{% block script %}

    <!-- The name_prefix option is generated, please read at -->

    <script type="text/javascript">

        // follow-scroll
        // credits: https://stackoverflow.com/a/2178569/731138
        (function($) {
            var element = $('.follow-scroll'), originalY = element.offset().top;
            var topMargin = 20;
            element.css('position', 'relative');
            $(window).on('scroll', function(event) {
                var scrollTop = $(window).scrollTop();
                element.stop(false, false).animate({
                    top: scrollTop < originalY ? 0 : scrollTop - originalY + topMargin
                }, 300);
            });
        })(jQuery);

        var backup = $('.form-collection').html();

        function reloadCollectionButtons() {
            $('.form-collection').html(backup);

            $('.form-collection').collection({
                name_prefix: '{{ form.values.vars.full_name }}',
                allow_up: $('#enable-up').is(':checked'),
                allow_down: $('#enable-down').is(':checked'),
                allow_add: $('#enable-add').is(':checked'),
                allow_remove: $('#enable-remove').is(':checked'),
                allow_duplicate: $('#enable-duplicate').is(':checked'),
                up: $('#up-layout').val(),
                down: $('#down-layout').val(),
                add: $('#add-layout').val(),
                remove: $('#remove-layout').val(),
                duplicate: $('#duplicate-layout').val(),
                min: $('#min-elements').val(),
                max: $('#max-elements').val(),
                add_at_the_end: $('#add-at-the-end').is(':checked'),
                init_with_n_elements: $('#init-witn-n-elements').val(),
                drag_drop: $('#drag-drop').is(':checked'),
                fade_in: $('#fade-in').is(':checked'),
                fade_out: $('#fade-out').is(':checked'),
            });
        }

        reloadCollectionButtons();

        $('.reload-collection').click(function () {
            reloadCollectionButtons();
        }).keyup(function () {
            reloadCollectionButtons();
        });

    </script>

{% endblock %}

Value :a

Value :b

Value :c