Use before_up
, before_down
, before_add
, before-duplicate
and before_remove
options to set a callback before applying an action to the collection.
Use after_up
, after_down
, after_add
, after-duplicate
and after_remove
options to set a callback after applying an action to the collection.
Callback takes 2 arguments: collection
contains the collection's root node and element
the element in the
collection that have been added, moved or deleted.
Note: element
may be undefined
on before_add
event when add_at_the_end
is set to true
or when collection has no elements yet.
Your callback should return true
or undefined
to apply the action else it is cancelled or rollbacked.
Value :a
Value :b
Value :c
Value :a
Value :b
Value :c
Code used:
<script type="text/javascript"> $('.eventsBefore-collection').collection({ before_up: function(collection, element) { return confirm("Do you really want to move the element up?"); }, before_down: function(collection, element) { return confirm("Do you really want to move the element down?"); }, before_add: function(collection, element) { return confirm("Do you really want to add the element?"); }, before_remove: function(collection, element) { return confirm("Do you really want to delete the element?"); }, before_duplicate: function(collection, element) { return confirm("Do you really want to duplicate the element?"); }, allow_duplicate: true }); $('.eventsAfter-collection').collection({ after_up: function(collection, element) { return confirm("Do you really want to move the element up?"); }, after_down: function(collection, element) { return confirm("Do you really want to move the element down?"); }, after_add: function(collection, element) { return confirm("Do you really want to add the element?"); }, after_remove: function(collection, element) { return confirm("Do you really want to delete the element?"); }, after_duplicate: function(collection, element) { return confirm("Do you really want to duplicate the element?"); }, allow_duplicate: true }); </script>
<?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);
}
}
{% extends 'FuzAppBundle::layout.html.twig' %}
{% block extra_js %}
<script src="{{ asset('js/jquery.collection.js') }}"></script>
{% endblock %}
{% block title %}JavaScript options : events on buttons{% endblock %}
{% block body %}
<h2>{{ block('title') }}</h2>
<p>
Use <code>before_up</code>, <code>before_down</code>, <code>before_add</code>, <code>before-duplicate</code> and <code>before_remove</code>
options to set a callback <strong>before</strong> applying an action to the collection.
</p>
<p>
Use <code>after_up</code>, <code>after_down</code>, <code>after_add</code>, <code>after-duplicate</code> and <code>after_remove</code>
options to set a callback <strong>after</strong> applying an action to the collection.
</p>
<p>
Callback takes 2 arguments: <code>collection</code> contains the collection's root node and <code>element</code> the element in the
collection that have been added, moved or deleted.
</p>
<p>
Note: <code>element</code> may be <code>undefined</code> on <code>before_add</code> event when <code>add_at_the_end</code>
is set to <code>true</code> or when collection has no elements yet.
</p>
<p>Your callback should return <code>true</code> or <code>undefined</code> to apply the action else it is cancelled or rollbacked.</p>
<div class="row">
<div class="col-md-6">
<h3>Events before updating the collection</h3>
{% form_theme eventsBefore 'jquery.collection.html.twig' %}
{{ form(eventsBefore) }}
{% for value in eventsBeforeData.values %}
<p>Value : {{ value }}</p>
{% endfor %}
</div>
<div class="col-md-6">
<h3>Events after updating the collection</h3>
{% form_theme eventsAfter 'jquery.collection.html.twig' %}
{{ form(eventsAfter) }}
{% for value in eventsAfterData.values %}
<p>Value : {{ value }}</p>
{% endfor %}
</div>
</div>
<hr/>
<p>Code used:</p>
<pre>{{ block('script') | e }}</pre>
{{
tabs([
'Base/BaseController.php',
'Controller/OptionsController.php',
'Resources/views/Options/eventCallbacks.html.twig',
])
}}
{% endblock %}
{% block script %}
<script type="text/javascript">
$('.eventsBefore-collection').collection({
before_up: function(collection, element) { return confirm("Do you really want to move the element up?"); },
before_down: function(collection, element) { return confirm("Do you really want to move the element down?"); },
before_add: function(collection, element) { return confirm("Do you really want to add the element?"); },
before_remove: function(collection, element) { return confirm("Do you really want to delete the element?"); },
before_duplicate: function(collection, element) { return confirm("Do you really want to duplicate the element?"); },
allow_duplicate: true
});
$('.eventsAfter-collection').collection({
after_up: function(collection, element) { return confirm("Do you really want to move the element up?"); },
after_down: function(collection, element) { return confirm("Do you really want to move the element down?"); },
after_add: function(collection, element) { return confirm("Do you really want to add the element?"); },
after_remove: function(collection, element) { return confirm("Do you really want to delete the element?"); },
after_duplicate: function(collection, element) { return confirm("Do you really want to duplicate the element?"); },
allow_duplicate: true
});
</script>
{% endblock %}