Laravel-форма ввода-множественный выбор для отношения один ко многим
одним из требований в приложении, которое я создаю, является ввод формы, которая принимает различное количество элементов для одного поля. Например, спорт, в который я играю ("футбол", "теннис", "крокет").
существует конечное количество видов спорта, в которые можно играть (возможно), поэтому эти элементы должны быть выбраны из списка типов "выпадающий" в форме ввода.
ниже по потоку этой формы будут две таблицы, которые имеют отношение "один ко многим". Так от выше таблица " пользователь "будет иметь одну строку, в то время как таблица" user_sports " будет иметь три строки. Затем они будут связаны полем id в таблице user.
Я не смог найти такой функции, где это может быть достигнуто в документации (возможно, я не искал нужная вещь). Ниже было самое близкое, что я нашел, но только для выбора одного элемента из выпадающего список.
http://laravel.com/docs/html#drop-down-lists
есть ли обходной путь, который позволит мне получить этот элемент формы и работает с помощью Laravel framework?
кроме того, есть ли другие способы, которыми можно достичь такого рода функциональности, не повреждая пользовательский интерфейс?
6 ответов
Я согласен с user3158900, и я только немного отличаюсь тем, как я его использую:
{{Form::label('sports', 'Sports')}}
{{Form::select('sports',$aSports,null,array('multiple'=>'multiple','name'=>'sports[]'))}}
однако, по моему опыту, 3-й параметр select-это только строка, поэтому для повторного заполнения данных для multi-select мне пришлось сделать что-то вроде этого:
<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>
@SamMonk ваша техника великолепна. Но вы можете использовать Laravel form helper для этого. У меня отношения с клиентами и собаками.
на геймпаде
$dogs = Dog::lists('name', 'id');
on customer create view вы можете использовать.
{{ 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 теперь возвращает Коллекция. Обновление До 5.1.0
{!! Form::label('dogs', 'Dogs') !!}
{!! Form::select('dogs[]', $dogs, $customer->dogs->lists('id')->all(), ['id' => 'dogs', 'multiple' => 'multiple']) !!}
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/ " и включил его в EOF глобальный.в 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;
});
использование
список без предварительно выбранных элементов (создать вид)
{{ 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']) }}
мое решение, его сделать с jQuery-chosen и bootstrap, идентификатор для jQuery выбран, протестирован и работает, у меня были проблемы с конкатенацией @foreach, но теперь работают с double @foreach и 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>
это выбранный код por jquery (лезвие.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>