【问题标题】:Laravel - Form Input - Multiple select for a one to many relationshipLaravel - 表单输入 - 一对多关系的多项选择
【发布时间】:2014-08-28 22:58:28
【问题描述】:

我正在构建的应用程序中的一个要求是表单输入,它为单个字段接收不同数量的项目。例如,我参加的运动是('足球'、'网球'、'槌球')。

一个人可以参加的运动是有限的(可以说),所以这些项目应该从表单输入的“下拉”类型列表中选择。

此表单的下游将是两个具有一对多关系的表。所以从上面看,“user”表将只有一行,而“user_sports”表将有三行。然后这些将通过用户表中的 id 字段链接。


我无法在文档中找到可以实现这一点的功能(也许我没有在寻找正确的东西)。下面是我找到的最接近的,但仅用于从下拉列表中选择单个项目。

http://laravel.com/docs/html#drop-down-lists


有没有一种解决方法可以让我使用 Laravel 框架启动并运行这个表单元素?

或者,是否有其他方法可以在不损害用户体验的情况下实现此类功能?

【问题讨论】:

    标签: php forms laravel one-to-many


    【解决方案1】:

    多重选择实际上只是一个带有multiple 属性的选择。考虑到这一点,它应该像...一样简单。

    Form::select('sports[]', $sports, null, array('multiple'))
    

    第一个参数只是名称,但使用[] 对其进行后修复将在您使用Input::get('sports') 时将其作为数组返回。

    第二个参数是一个可选选项的数组。

    第三个参数是你想要预选的选项数组。

    第四个参数实际上是通过将multiple 属性添加到实际的选择元素来将其设置为多选下拉菜单。..

    【讨论】:

      【解决方案2】:

      我同意user3158900,只是在使用方式上略有不同:

      {{Form::label('sports', 'Sports')}}
      {{Form::select('sports',$aSports,null,array('multiple'=>'multiple','name'=>'sports[]'))}}
      

      但是,根据我的经验,选择的第三个参数只是一个字符串,所以为了重新填充多选的数据,我不得不做这样的事情:

      <select multiple="multiple" name="sports[]" id="sports">
      @foreach($aSports as $aKey => $aSport)
          @foreach($aItem->sports as $aItemKey => $aItemSport)
              <option value="{{$aKey}}" @if($aKey == $aItemKey)selected="selected"@endif>{{$aSport}}</option>
          @endforeach
      @endforeach
      </select>
      

      【讨论】:

        【解决方案3】:

        @SamMonk 你的技术很棒。但是你可以使用 laravel 表单助手来做到这一点。我有客户和狗的关系。

        在你的控制器上

        $dogs = Dog::lists('name', 'id');
        

        您可以在客户创建视图中使用。

        {{ Form::label('dogs', 'Dogs') }}
        {{ Form::select('dogs[]', $dogs, null, ['id' => 'dogs', 'multiple' => 'multiple']) }}
        

        第三个参数接受一个数组的列表。如果您在模型上定义关系,您可以这样做:

        {{ Form::label('dogs', 'Dogs') }}
        {{ Form::select('dogs[]', $dogs, $customer->dogs->lists('id'), ['id' => 'dogs', 'multiple' => 'multiple']) }}
        

        Laravel 5.1 更新

        lists 方法现在返回一个集合。 Upgrading To 5.1.0

        {!! Form::label('dogs', 'Dogs') !!}
        {!! Form::select('dogs[]', $dogs, $customer->dogs->lists('id')->all(), ['id' => 'dogs', 'multiple' => 'multiple']) !!}
        

        【讨论】:

        • 我不知道您是否可以将 Collection 作为第一个参数传递。你不应该使用$customer-&gt;dogs-&gt;lists('id')-&gt;toArray()吗?
        • 这个答案是在 Laravel 5 发布之前给出的。当时(v. 4.2)lists() 默认返回数组。
        • 我认为这应该被标记为正确答案。
        • 你也可以在 Dog Model 上创建一个 Accessor,在我看来这更简洁一些。 public function getDogListAttribute() { return $this->dogs->lists('id')->all();然后在视图中,将 dog_list[] 属性与 select form helper 的第一个参数中的数组括号一起使用(以及一个空的第三个参数)。
        • 请注意lists 已重命名为pluck。方法签名是相同的,所以对于 laravel 5.4,它将是 $customer-&gt;dogs-&gt;pluck('id')-&gt;all()
        【解决方案4】:

        Laravel 4.2

        @SamMonk 给出了最好的选择,我按照他的例子构建了最后一段代码

        <select class="chosen-select" multiple="multiple" name="places[]" id="places">
            @foreach($places as $place)
                <option value="{{$place->id}}" @foreach($job->places as $p) @if($place->id == $p->id)selected="selected"@endif @endforeach>{{$place->name}}</option>
            @endforeach
        </select>
        

        在我的项目中,我将有很多这样的表关系,所以我写了一个扩展来保持它的整洁。要加载它,请将其放入“app/start/global.php”之类的配置文件中。我在“app/”目录下创建了一个文件“macros.php”,并将其包含在 global.php 的 EOF 中

        // app/start/global.php
        require app_path().'/macros.php';
        
        // macros.php
        Form::macro("chosen", function($name, $defaults = array(), $selected = array(), $options = array()){
        
            // For empty Input::old($name) session, $selected is an empty string
            if(!$selected) $selected = array();
        
            $opts = array(
                'class' => 'chosen-select',
                'id' => $name,
                'name' => $name . '[]',
                'multiple' => true
            );
            $options = array_merge($opts, $options);
            $attributes = HTML::attributes($options);
        
            // need an empty array to send if all values are unselected
            $ret = '<input type="hidden" name="' . HTML::entities($name) . '[]">';
            $ret .= '<select ' . $attributes . '>';
            foreach($defaults as $def) {
                $ret .= '<option value="' . $def->id . '"';
                foreach($selected as $p) {
                    // session array or passed stdClass obj
                    $current = @$p->id ? $p->id: $p;
                    if($def->id == $current) {
                        $ret .= ' selected="selected"';
                    }
                }
                $ret .= '>' . HTML::entities($def->name) . '</option>';
            }
            $ret .= '</select>';
            return $ret;
        });
        

        用法

        没有预选项目的列表(创建视图)

        {{ Form::chosen('places', $places, Input::old('places')) }}
        

        预选(编辑视图)

        {{ Form::chosen('places', $places, $job->places) }}
        

        完整使用

        {{ Form::chosen('places', $places, $job->places, ['multiple': false, 'title': 'I\'m a selectbox', 'class': 'bootstrap_is_mainstream']) }}
        

        【讨论】:

        • 这个怎么样:@foreach($tags as $key=&gt;$value) &lt;option value="{{ $key }}" {{ in_array($key, array_values($feature-&gt;tags-&gt;pluck('id')-&gt;toArray())) ? 'selected' : '' }} &gt; {{ $value }}&lt;/option&gt; @endforeach
        【解决方案5】:

        我的解决方案,它是使用 jquery-chosen 和 bootstrap 制作的,id 用于选择、测试和工作的 jquery,我在连接 @foreach 时遇到问题,但现在使用双 @foreach 和双 @if:

          <div class="form-group">
            <label for="tagLabel">Tags: </label>
            <select multiple class="chosen-tag" id="tagLabel" name="tag_id[]" required>
              @foreach($tags as $id => $name)
                @if (is_array(Request::old('tag_id')))
                        <option value="{{ $id }}" 
                        @foreach (Request::old('tag_id') as $idold)
                          @if($idold==$id)
                            selected
                          @endif 
                        @endforeach
                        style="padding:5px;">{{ $name }}</option>
                @else
                  <option value="{{ $id }}" style="padding:5px;">{{ $name }}</option>
                @endif
              @endforeach
            </select>
          </div>
        

        这是选择的 jquery 代码(blade.php 代码不需要此代码工作)

            $(".chosen-tag").chosen({
          placeholder_text_multiple: "Selecciona alguna etiqueta",
          no_results_text: "No hay resultados para la busqueda",
          search_contains: true,
          width: '500px'
        });
        

        【讨论】:

          【解决方案6】:

          如果您需要相互比较 2 个输出数组但使用第一个数组填充选项,这可能是比最佳答案更好的方法。

          当您的数组中有非数字或偏移索引(键)时,这也很有帮助。

          <select name="roles[]" multiple>
              @foreach($roles as $key => $value)
                  <option value="{{$key}}" @if(in_array($value, $compare_roles))selected="selected"@endif>
                      {{$value}}
                  </option>
              @endforeach
          </select>
          

          【讨论】:

            【解决方案7】:

            只有一个 if 条件

            <select name="category_type[]" id="category_type" class="select2 m-b-10 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose" tooltip="Select Category Type">
             @foreach ($categoryTypes as $categoryType)
              <option value="{{ $categoryType->id }}"
                **@if(in_array($categoryType->id,
                 request()->get('category_type')??[]))selected="selected"
                @endif**>
                 {{ ucfirst($categoryType->title) }}</option>
                 @endforeach
             </select>
            

            【讨论】:

              猜你喜欢
              • 2014-07-22
              • 1970-01-01
              • 2014-07-22
              • 1970-01-01
              • 2017-01-24
              • 1970-01-01
              • 1970-01-01
              • 2020-11-08
              • 2013-11-13
              相关资源
              最近更新 更多