简体   繁体   中英

How to split form_widget in twig

I have a radio button form with 2 inputs

    $builder->add('intakeyear', ChoiceType::class, array(
        'choices' => array(
            '2017' => 2017,
            '2018' => 2018,
        ),
        'expanded' => true,
        'multiple' => false,
        'label' => 'Intake Year',
    ));

and in twig

<div class="col-sm-3">{{ form_widget(form.intakeyear) }}</div>

This renders the form as

<input />
<label>2017</label>
<input />
<label>2018</label>

But I want to split the {{ form_widget(form.intakeyear) }} into individual options like:

{{ form_widget(form.intakeyear/choice_1/) }}

{{ form_widget(form.intakeyear/choice_2/) }}

So that I can add the bootstrap class radio-inline to the label tags and have the final html output as:

<label class="radio-inline"><input />2017</label>

<label class="radio-inline"><input />2018</label>

Any ideas?

EDIT:

Here is a snapshot of the output I am getting:

在此处输入图片说明

For better understanding here is my code: index.html.twig :

{% extends 'base.html.twig' %}

{% block stylesheets %}
    {% stylesheets '@AppBundle/Resources/public/css/bootstrap.min.css' filter='cssrewrite' %}
    <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}

{% block body %}
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span> 
                </button>
                <a class="navbar-brand" href="#">EPITA</a>
            </div>
            <div class="collapse navbar-collapse" id="myNavbar">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="#">Home</a></li>
                    <li><a href="#">Page 1</a></li>
                    <li><a href="#">Page 2</a></li> 
                    <li><a href="#">Page 3</a></li>
                </ul>
                <form class="navbar-form navbar-left">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Search">
                        <div class="input-group-btn">
                            <button class="btn btn-default" type="submit">
                                <i class="glyphicon glyphicon-search"></i>
                            </button>
                        </div>
                    </div>
                </form>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
                    <li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
                </ul>
            </div>
        </div>
    </nav></br></br></br>
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-4">
                <h2>Candidate Application</h2>
            </div>
        </div></br>    
        {{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }}
        <div class="row form-group">
            <div class="col-sm-3">{{ form_label(form.name,'Name' ,{'attr': {'class': 'sr-only'}}) }}</div>
            <div class="col-sm-3">{{ form_widget(form.name, {'attr': {'class': 'form-control'}}) }}</div>
            <div class="col-sm-6">{{ form_errors(form.name) }}</div>
        </div>
        <div class="row form-group">
            <div class="col-sm-3">{{ form_label(form.programtype) }}</div>
            <div class="col-sm-3">{{ form_widget(form.programtype, {'attr': {'class': 'form-control'}}) }}</div>
            <div class="col-sm-6">{{ form_errors(form.programtype) }}</div>
        </div><br/>
        <div class="row form-group">
            <div class="col-sm-3">{{ form_label(form.programofinterest) }}</div>
            <div class="col-sm-3">{{ form_widget(form.programofinterest, {'attr': {'class': 'form-control'}}) }}</div>
            <div class="col-sm-6">{{ form_errors(form.programofinterest) }}</div>
        </div><br/>
        <div class="row form-group">
            <div class="col-sm-3">{{ form_label(form.desiredintake) }}</div>
            <div class="col-sm-3">{{ form_widget(form.desiredintake, {'attr': {'class': 'form-control'}}) }}</div>
            <div class="col-sm-6">{{ form_errors(form.desiredintake) }}</div>
        </div><br/>
        <div class="row form-group">
            <div class="col-sm-3">{{ form_label(form.intakeyear) }}</div>
            <div class="col-sm-3">{{ form_widget(form.intakeyear, {'label_attr': {'class': 'radio-inline'}}) }}</div>
            <div class="col-sm-6">{{ form_errors(form.intakeyear) }}</div>
        </div><br/>
        <div class="row">
            <div class="col-sm-offset-3 col-sm-12">{{ form_row(form.save, {'attr': {'class': 'btn btn-primary'}}) }}</div>
        </div>
        {{ form_end(form) }}
    </div>
{% endblock %}

{% block javascripts %}
    {% javascripts '@AppBundle/Resources/public/js/jquery-3.2.1.min.js' %}
    <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
    {% javascripts '@AppBundle/Resources/public/js/NewCandidate.js' %}
    <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
    <script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
    <script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
    {% javascripts '@AppBundle/Resources/public/js/bootstrap.min.js' %}
    <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

NewCandidate.js :

//on page load do the following
        $(document).ready(function () {
                //when the program type value changes do the following
                $("#candidate_programtype").change(function () {
                    //get the program type element
                    var program_type_element = document.getElementById("candidate_programtype");
                    //get the program type value
                    var program_type = program_type_element.options[program_type_element.selectedIndex].value;
                    //initiate the ajax call
                    $.ajax({
                        type: "POST",
                        url: Routing.generate('homepage'),
                        contentType: 'application/x-www-form-urlencoded',
                        //send the program_type_id and flag to the server
                        data: {program_type_id: program_type, flag: 'program_type'},
                        //on successfull ajax call do the following
                        success: function (result, status, xhr) {
                            //parse the result and save it in pi_arr
                            var pi_arr = JSON.parse(result);
                            //remove all the options from the programofinterest select element
                            $("#candidate_programofinterest").empty();
                        //loop through the array pi_arr['pi'] one by one    
                        for (var i in pi_arr['pi']) {
                                //add the option with value i and text pi_arr['pi'][i]
                                $("#candidate_programofinterest").append($("<option/>", {"value": i, "text": pi_arr['pi'][i]}));
                            }
                            //remove all the options from the desiredintake select element
                            $("#candidate_desiredintake").empty();
                            //loop through array pi_arr['di'] one by one
                            for (var i in pi_arr['di']) {
                                //add the option with value i and text pi_arr['di'][i]
                                $("#candidate_desiredintake").append($("<option/>", {"value": i, "text": pi_arr['di'][i]}));
                            }
                        },
                        //on unsuccessfull ajax call do the following
                        error: function (xhr, status, error) {

                        }
                    });
                });
                //when the program of interest value changes do the following
                $("#candidate_programofinterest").change(function () {
                    //get the program of interest element
                    var program_of_interest_element = document.getElementById("candidate_programofinterest");
                    //get the program of interest value
                    var program_of_interest = program_of_interest_element.options[program_of_interest_element.selectedIndex].value;
                    //initiate the ajax call
                    $.ajax({
                        type: "POST",
                        url: Routing.generate('homepage'),
                        contentType: 'application/x-www-form-urlencoded',
                        //send the program_of_interest_id and flag to the server
                        data: {program_of_interest_id: program_of_interest, flag: 'program_of_interest'},
                        //on successfull ajax call do the following
                        success: function (result, status, xhr) {
                            //parse the result and save it in di_arr
                            var di_arr = JSON.parse(result);
                            //remove all the options from the desiredintake select element
                            $("#candidate_desiredintake").empty();
                            //loop through array di_arr one by one
                            for (var i in di_arr) {
                                //add the option with value i and text di_arr[i]
                                $("#candidate_desiredintake").append($("<option/>", {"value": i, "text": di_arr[i]}));
                            }
                        },
                        //on unsuccessfull ajax call do the following
                        error: function (xhr, status, error) {

                        }
                    });
                });
                //when the desired intake value changes do the following
                $("#candidate_desiredintake").change(function () {
                    //get the program type element
                    var program_type_element = document.getElementById("candidate_programtype");
                    //get the program type value
                    var program_type = program_type_element.options[program_type_element.selectedIndex].value;

                    //get the program of interest element
                    var program_of_interest_element = document.getElementById("candidate_programofinterest");
                    //get the program of interest value
                    var program_of_interest = program_of_interest_element.options[program_of_interest_element.selectedIndex].value;

                    //get the desired intake element
                    var desired_intake_element = document.getElementById("candidate_desiredintake");
                    //get the desired intake value
                    var desired_intake = desired_intake_element.options[desired_intake_element.selectedIndex].value;
                    //initiate the ajax call

                    $.ajax({
                        type: "POST",
                        url: Routing.generate('homepage'),
                        contentType: 'application/x-www-form-urlencoded',
                        //send the program_of_interest_id and flag to the server
                        data: {program_type_id: program_type, program_of_interest_id: program_of_interest, desired_intake_id: desired_intake, flag: 'desired_intake'},
                        //on successfull ajax call do the following
                        success: function (result, status, xhr) {
                            //parse the result and save it in intakeyear
                            var intakeyear = JSON.parse(result);
                            //remove all the options from the intakeyear select element
                            $("#candidate_intakeyear").empty();
                            $("#candidate_intakeyear").append($("<option/>", {"value": intakeyear, "text": intakeyear}));
                        },
                        //on unsuccessfull ajax call do the following
                        error: function (xhr, status, error) {

                        }
                    });
                });
            });

CandidateType.php :

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CandidateType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('name', TextType::class, array());

        $builder->add('programtype', EntityType::class, array(
            'class' => 'AppBundle:ProgramType',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('p')
                                ->where('p.enabled = 1')
                                ->orderBy('p.id', 'ASC');
            },
            'choice_label' => 'description',
            'expanded' => false,
            'multiple' => false,
            'label' => 'Program Type',
        ));

        $builder->add('programofinterest', EntityType::class, array(
            'class' => 'AppBundle:ProgramOfInterest',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('p')
                                ->where('p.enabled = 1')
                                ->orderBy('p.id', 'ASC');
            },
            'choice_label' => 'description',
            'expanded' => false,
            'multiple' => false,
            'label' => 'Program of Interest',
        ));

        $builder->add('desiredintake', EntityType::class, array(
            'class' => 'AppBundle:DesiredIntake',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('p')
                                ->where('p.enabled = 1')
                                ->orderBy('p.id', 'ASC');
            },
            'choice_label' => 'description',
            'expanded' => false,
            'multiple' => false,
            'label' => 'Desired Intake',
        ));

//        $builder->add('intakeyear', ChoiceType::class, array(
//            'choices' => array(
//                '2017' => 2017,
//                '2018' => 2018,
//            ),
//            'expanded' => false,
//            'multiple' => false,
//            'label' => 'Intake Year',
//        ));

        $builder->add('intakeyear', ChoiceType::class, array(
            'choices' => array(
                '2017' => 2017,
                '2018' => 2018,
            ),
            'expanded' => true,
            'multiple' => false,
            'label' => 'Intake Year',
            'label_attr' => array('class' => 'radio-inline'),
        ));

        $builder->add('save', SubmitType::class, array('label' => 'Submit'));
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Candidate',
        ));
    }

}

You don't have to split the widget up. You can do this via the label_attr option, either in the form definition or in the Twig template itself:

$builder->add('intakeyear', ChoiceType::class, array(
    'choices' => array(
        '2017' => 2017,
        '2018' => 2018,
    ),
    'expanded' => true,
    'multiple' => false,
    'label' => 'Intake Year',
    'label_attr' => array('class' => 'radio-inline'),
));

or

{{ form_widget(form.intakeyear, {'label_attr': {'class': 'radio-inline'}}) }}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM