Skip to content

Instantly share code, notes, and snippets.

@muzfr7
Last active April 23, 2017 12:46
Show Gist options
  • Save muzfr7/3738f11369324ac674cc185111ba1faf to your computer and use it in GitHub Desktop.
Save muzfr7/3738f11369324ac674cc185111ba1faf to your computer and use it in GitHub Desktop.
Symfony Prototype Rendering Macro
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class SkillType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('skill', EntityType::class, array(
'label'=>'',
'class'=>'ModelBundle:Skill',
'choice_label'=>'title',
'multiple'=>false,
'attr'=>array()
)
);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ModelBundle\Entity\Skill'
));
}
}
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class ApplicationType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('firstname', TextType::class, array(
'label'=>'',
'attr'=>array(
'class'=>'gui-input',
'placeholder'=>'',
'dir'=>'ltr'
)
)
)
->add('lastname', TextType::class, array(
'label'=>'',
'attr'=>array(
'class'=>'gui-input',
'placeholder'=>'',
'dir'=>'ltr'
)
)
)
->add('skills', CollectionType::class, array(
'entry_type' => SkillType::class,
'allow_add' => true, // to allow adding items dynamically
'allow_delete' => true,
'by_reference' => false,
'prototype' => true,
'prototype_name'=> 'skill__name__',
)
);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ModelBundle\Entity\Application'
));
}
}
{% macro widget_prototype(widget, remove_text) %}
{% if widget.vars.prototype %}
{% set form = widget.vars.prototype %}
{% set name = widget.vars.name %}
{% else %}
{% set form = widget %}
{% set name = widget.vars.full_name %}
{% endif %}
<div data-content="{{ name }}" class="prototypeWrapper">
<a class="btn-remove" data-related="{{ name }}">{{ remove_text }}</a>
<div class="section row">
<div class="col-md-12">
<label class="field-label fontArabic">Skill <span class="text-danger">*</span></label>
<label class="field select fontArabic">
{{ form_widget(form.skill) }}
<i class="arrow double"></i>
</label>
</div>
</div>
</div>
{% endmacro %}
{{ form_start(form) }}
<div class="section row">
<div class="col-md-12">
<label class="field-label">First Name <span class="text-danger">*</span></label>
<label for="firstname" class="field">
{{ form_widget(form.firstname) }}
</label>
</div>
<div class="col-md-12">
<label class="field-label">Last Name <span class="text-danger">*</span></label>
<label for="firstname" class="field">
{{ form_widget(form.lastname) }}
</label>
</div>
</div>
<div id="application_skills" data-prototype="{{ _self.widget_prototype(form.skills, 'X')|escape }}">
{% for widget in form.skills.children %}
{{ _self.widget_prototype(widget, 'X') }}
{% endfor %}
</div>
<h5 class="micro-header mt40 text-right">
<button type="button" class="btn btn-xs btn-success dark btn-add" data-target="application_skills"><i class="fa fa-plus"></i> Add Skill</button>
</h5>
{{ form_end(form) }}
$(function(){
$('.btn-add').click(function(event) {
var collectionHolder = $('#' + $(this).attr('data-target'));
var prototype = collectionHolder.attr('data-prototype');
var form = prototype.replace(/__name__/g, collectionHolder.children().length);
collectionHolder.append(form);
return false;
});
$(document).on('click', ".btn-remove", function(event) {
var name = $(this).attr('data-related');
$(this).parent('*[data-content="'+name+'"]').remove();
return false;
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment