web-dev-qa-db-ja.com

Laravel-フォーム入力-1対多関係の複数選択

私が作成しているアプリケーションの要件の1つは、1つのフィールドに対してさまざまな数のアイテムを取り込むフォーム入力に関するものです。たとえば、私がプレイするスポーツは( 'Soccer'、 'Tennis'、 'C​​roquet')です。

(おそらく)プレイできるスポーツの数には限りがあるため、これらのアイテムはフォーム入力の「ドロップダウン」タイプリストから選択する必要があります。

このフォームの下流には、1対多の関係を持つ2つのテーブルがあります。したがって、上記から、「user」テーブルには1つの行があり、「user_sports」テーブルには3つの行があります。これらは、ユーザーテーブルのidフィールドによってリンクされます。


ドキュメントでこれを達成できる機能の種類を見つけることができませんでした(おそらく正しいものを検索していないのでしょう)。以下は私が見つけた最も近いものでしたが、ドロップダウンリストから単一のアイテムを選択するためのものです。

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


Laravelフレームワークを使用してこのフォーム要素を起動して実行できるようにする回避策はありますか?

または、ユーザーエクスペリエンスを損なうことなく、この種の機能を実現できる他の方法はありますか?

21
datavoredan

私はuser3158900に同意し、使用方法がわずかに異なります。

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

ただし、私の経験では、選択の3番目のパラメーターは文字列のみであるため、複数選択のデータを再入力するには、次のようにする必要がありました。

<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>
54
SamMonk

@SamMonkあなたのテクニックは素晴らしいです。しかし、あなたはそうするためにlaravelフォームヘルパーを使用することができます。私は顧客と犬の関係を持っています。

コントローラー上

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

顧客作成ビューで使用できます。

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

3番目のパラメーターは、配列のリストを受け入れます。モデルで関係を定義する場合、これを行うことができます。

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

Laravel 5.1の更新

リストメソッドは、コレクションを返すようになりました。 5.1.0へのアップグレード

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

ララヴェル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']) }}
7
Ben K.

複数選択は、実際にはmultiple属性を持つ単なる選択です。それを念頭に置いて、それはできるだけ簡単でなければなりません...

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

最初のパラメーターは単なる名前ですが、Input::get('sports')を使用すると、_[]_を使用して後修正すると、配列として返されます。

2番目のパラメーターは、選択可能なオプションの配列です。

3番目のパラメーターは、事前に選択するオプションの配列です。

4番目のパラメーターは、実際にselect要素にmultipleプロパティを追加することにより、実際にこれを複数選択ドロップダウンとして設定しています。

4
user1669496

私の解決策は、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 porのコードです(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'
});

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>
0
Tom van Tilburg