Laravel - 表单输入 - 一对多关系的多重选择

问题描述 投票:0回答:7

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

人们可以参加的运动项目数量有限(可以说),因此应从表单输入中的“下拉”类型列表中选择这些项目。

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


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

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


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

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

php forms laravel one-to-many
7个回答
69
投票

我同意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>

47
投票

@SamMonk 你的技术很棒。但您可以使用 Laravel 表单助手来执行此操作。我有顾客和狗的关系。

在您的控制器上

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

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

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

第三个参数接受数组 a 的列表。如果您在模型上定义关系,您可以执行以下操作:

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

Laravel 5.1 更新

lists 方法现在返回一个 Collection。 升级至5.1.0

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

11
投票

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']) }}

6
投票

多重选择实际上只是带有

multiple
属性的选择。考虑到这一点,它应该很简单......

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

第一个参数只是名称,但使用

[]
对其进行后修复,当您使用
Input::get('sports')
时,会将其作为数组返回。

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

第三个参数是您想要预先选择的选项数组。

第四个参数实际上是通过将

multiple
属性添加到实际的选择元素来将其设置为多选下拉列表..


3
投票

如果您需要相互比较 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>

1
投票

我的解决方案,它是用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'
});

0
投票

只需单个 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>
© www.soinside.com 2019 - 2024. All rights reserved.