Laravel-form Input-Multiple select pour une relation de un à plusieurs

l'Une des exigences dans une application que je suis bâtiment est pour un formulaire de saisie qui prend un nombre variable d'éléments pour un seul champ. Par exemple, les sports que je pratique sont ("football", "Tennis", "Croquet").

il y a un nombre fini de sports que l'on peut pratiquer (sans doute), donc ces éléments doivent être sélectionnés à partir d'une liste de type "drop down" dans le formulaire input.

en aval de ce formulaire, il y aura deux tables qui ont une relation de un à plusieurs. Donc, à partir de ci-dessus, la table" user "aurait une seule ligne, tandis que la table" user_sports " aurait trois lignes. Celles-ci seraient alors liés par le champ id dans la table user.


Je n'ai pas été en mesure de trouver le type de fonctionnalité où cela peut être réalisé dans la documentation (peut-être que je ne cherche pas la bonne chose). Ci-dessous était le plus proche que j'ai trouvé, mais est seulement pour sélectionner un seul article à partir d'une goutte vers le bas liste.

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


y a-t-il une solution de contournement qui me permettra de faire démarrer cet élément de formulaire en utilisant le cadre Laravel?

Sinon, y a-t-il d'autres façons d'obtenir ce genre de fonctionnalité, sans nuire à l'expérience de l'utilisateur?

19
demandé sur tereško 2014-07-08 13:09:28

6 réponses

je suis d'accord avec user3158900, et je ne diffèrent légèrement dans la façon dont je l'utilise:

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

cependant, d'après mon expérience, le troisième paramètre du select est une chaîne de caractères seulement, donc pour repopuler des données pour un multi-select j'ai dû faire quelque chose comme ceci:

<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>
41
répondu SamMonk 2014-07-08 13:26:51

@SamMonk votre technique est excellente. Mais vous pouvez utiliser laravel aide de forme pour le faire. J'ai un client et les chiens de la relation.

Sur votre contrôleur

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

sur le client create view vous pouvez utiliser.

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

Troisième paramètre accepte une liste de tableau d'un bien. Si vous définissez une relation sur votre modèle, vous pouvez faire ceci:

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

Mise À Jour Pour Laravel 5.1

la méthode listes retourne maintenant un Collection. Mise À Jour De 5.1.0

{!! Form::label('dogs', 'Dogs') !!}
{!! Form::select('dogs[]', $dogs, $customer->dogs->lists('id')->all(), ['id' => 'dogs', 'multiple' => 'multiple']) !!}
39
répondu Sushant Aryal 2015-12-04 06:52:22

Laravel 4.2

@ SamMonk a donné la meilleure alternative, j'ai suivi son exemple et construit le dernier morceau de code

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

dans mon projet je vais avoir beaucoup de relations de table comme celle-ci donc j'ai écrit une extension pour le garder propre. Pour le charger, le mettre dans un fichier de configuration comme "app/commencer/global.php". J'ai créé un fichier "macros.php" dans le répertoire "app/" et l'a inclus dans L'EOF de mondial.php

// 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;
});

Utilisation

Liste sans pré-éléments sélectionnés (create view)

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

Présélections (modifier la vue)

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

utilisation

{{ Form::chosen('places', $places, $job->places, ['multiple': false, 'title': 'I\'m a selectbox', 'class': 'bootstrap_is_mainstream']) }}
4
répondu Ben K. 2014-11-04 13:50:12

Une sélection multiple est vraiment juste un select avec un multiple l'attribut. Avec cela à l'esprit, il devrait être aussi facile...

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

Le premier paramètre est juste le nom, mais après la fixer avec l' [] le renvoie sous forme de tableau lorsque vous utilisez Input::get('sports').

le second paramètre est un tableau d'options sélectionnables.

Le troisième paramètre est un tableau d'options que vous souhaitez pré-sélectionnés.

le quatrième paramètre est en train de définir ceci sélectionnez une liste déroulante en ajoutant le multiple propriété de l'élément select réel..

3
répondu user3158900 2014-07-08 11:56:11

ma solution, sa marque avec jQuery-choisi et bootstrap, l'id est pour jquery choisi, testé et de travail, j'ai eu des problèmes concatenating @foreach mais maintenant travailler avec un double @foreach et double @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>
    $(".chosen-tag").chosen({
  placeholder_text_multiple: "Selecciona alguna etiqueta",
  no_results_text: "No hay resultados para la busqueda",
  search_contains: true,
  width: '500px'
});
1
répondu Raul Fernandez Marques 2016-02-13 00:31:38

cela pourrait être une meilleure approche que top answer si vous avez besoin de comparer 2 tableaux de sortie l'un à l'autre mais utilisez le premier tableau pour remplir les options.

ceci est également utile lorsque vous avez un index non-numérique ou offset (clé) dans votre tableau.

<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
répondu Tom van Tilburg 2018-06-20 17:10:04