如何在树枝上拆分form_widget

时间:2017-08-15 12:34:44

标签: php html twitter-bootstrap symfony twig

我有一个带2个输入的单选按钮表单

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

和枝条

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

这会将表单呈现为

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

但我想将{{ form_widget(form.intakeyear) }}分成以下各个选项:

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

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

这样我就可以将bootstrap类radio-inline添加到标签标签中,并将最终的html输出作为:

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

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

有什么想法吗?

修改

以下是我得到的输出的快照:

enter image description here

为了更好地理解这里是我的代码: 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',
        ));
    }

}

1 个答案:

答案 0 :(得分:0)

您无需拆分窗口小部件。您可以通过表单定义或Twig模板本身中的label_attr选项执行此操作:

$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'),
));

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