我在我的网络应用程序中使用Select2。我用Ajax加载我的Select2框。验证失败时,除Select2框外,所有输入都按照之前的方式填充。如何在表单验证失败后恢复旧值?我的赌注是使用Request::old('x')
,但这会插入值(在我的情况下是用户ID)而不是所选文本。例如,文本John
将在选择框中变为27
。我怎样才能收回文字?
<select id="customer" name="customer" class="searchselect searchselectstyle">
</select>
js:
token = '{{csrf_token()}}';
$(".searchselect").select2({
ajax: {
dataType: "json",
type: "POST",
data: function (params) {
return {
term: params.term,
'_token': token,
'data' : function(){
var result = [];
var i = 1;
$('.searchselect').each(function(){
result[i] = $(this).val();
i++;
});
return result;
}
};
},
url: function() {
var type = $(this).attr('id');
return '/get' + type;
},
cache: false,
processResults: function (data) {
return {
results: data
};
}
}
});
修改
到目前为止我找到的唯一(脏)解决方案如下:
<select id="customer" name="customer" class="searchselect searchselectstyle">
@if(Request::old('customer') != NULL)
<option value="{{Request::old('customer')}}">{{$customers->where('id', intval(Request::old('customer')))->first()->name}}</option>
@endif
</select>
$customers
是所有客户的列表,因此这意味着对于每个Select2框,我需要查询大项目列表才能使其正常工作。如果我们在每个Select2框中讨论数千行,这将是非常低效的。
我想必须有更好的解决方案。谁能帮帮我?
答案 0 :(得分:2)
通常以编程方式设置select2的值,您可以使用.val()
方法,然后使用.trigger('change')
调用as per their documentation(以及other queries like this on SO)。但是,select2本身在其文档中有关于preselecting options for remotely sourced data的内容。
基本上他们的建议可归结为(在推动你的AJAX驱动<select>
之后):
<select>
)追加到底层.then()
change
事件select2:select
事件(并传递整个data
对象)假设您已经以各种方式将旧数据闪烁到会话Laravel provides handy access to the previously requested input,特别是这三个:
Request
类进行静态访问,例如{/ 1}}与OP old()
helper例如Request::old('customer')
,如果给定字段没有旧输入,则返回old('customer')
,并且可以将默认值作为第二个参数null
实例上的old()
方法,例如Request
全局辅助方法通常建议在Blade模板中使用,就像这里的其他一些答案一样,当你不需要操纵值并且可以直接将其插回时,它非常有用,你会喜欢文字输入。
最后一种方法可能会为您提供您正在寻找的答案 - 而不是从视图内部查询整个集合,您可以从控制器操作集合(类似于OP,但应该更好,因为它没有在视图中解析它)或者根据旧ID从控制器发出另一个查询并获取你想要的数据而不必搜索集合(更少的开销):
$request->old('customer')
无论哪种方式,您都可以在刀片模板处理任何内容之前,在指尖(作为视图变量)获得特定数据。
但是,您选择注入数据,它仍将遵循select2建议的模式:
唯一的区别是您不需要从其他API端点获取数据(除非您出于其他程序原因需要/需要)。
答案 1 :(得分:1)
我最终使用类似你的流程。但我的刀片模板使用的是htmlcollection包。
控制器: -
我们假设您使用的是create()
方法。验证失败时,它将重定向回创建页面。在此页面中,您可以重新填充列表。
$customer_list = [];
if(old('customer') != NULL){
$customer_list = [old('customer') => $customers->where('id', old('customer'))->first()->name];
}
Blade View:
{{ Form::select('customer', $customer_list, null, ['class' => 'searchselect searchselectstyle', 'id' => 'customer']) }}
答案 2 :(得分:0)
也许你可以尝试(一旦ajax调用结束):
var oldCustomer = $('#customer > option[value={{ Request::old('customer') }}]');
if (oldCustomer.length > 0) {
oldCustomer.attr('selected', 'selected');
}
答案 3 :(得分:0)
同样的问题;我使用了类似的解决方案:如果设置了旧的$ id,我会得到名称,并将其用作视图的变量;请注意,我也转发了id,因为我也使用此方法预填充表单(来自其他地方),但在这种情况下,名称只应该被使用,并且id {{old(&#39) ; author_id&#39;)}}可以在视图中使用:
在控制器中:
elseif (($request->old('author_id') !== null) && ($request->old('author_id') != '')) {
$my_author_id = $request->old('author_id');
$my_name = Author::find($my_author_id)->name;
return view('admin/url_author.create', compact('my_name', 'my_author_id'));
}
在视图中(更准确地说,部分用于创作和版本):
@if (isset($record)) // for use in edit case with laravelcollective)
<select class="form-control js-data-author-ajax" id="author_id" name="author_id">
<option value="{{ $record->author_id }}">{{ $record->author->name }}</option>
</select>
@else
@if (isset($my_name)) // old input after validation + pre-filling cases
<select class="form-control js-data-author-ajax" id="author_id" name="author_id">
<option value="{{ $my_author_id }}">{{ $my_name }}</option>
</select>
@else // for create cases
<select class="form-control js-data-auteur-ajax" id="auteur_id" name="auteur_id">
<option></option>
</select>
@endif
@endif
答案 4 :(得分:0)
您的代码有点令人困惑。我不明白为什么你使用POST
请求使用ajax来填充select2框来获取数据。
假设使用ajax调用返回的data
采用以下格式。
[
{
"id": "Some id",
"text": "Some text"
},
{
"id": "ID 2",
"text": "Text 2"
},
]
现在您可以做的是将一个额外的参数传递给您的ajax调用,如下所示
url: function() {
var type = $(this).attr('id');
@if(old('customer'))
return '/get' + type + '?customer='+ {{ old('customer') }};
@else
return '/get' + type;
@endif
}
现在在您的控制器中返回数据时,您可以为与该特定ID匹配的ID抛出额外的属性selected:true
。
if( Request::has('customer') && Request::input('customer') == $id )
{
[
"id" => $id,
"text" => $text,
"selected" => "true"
]
}
else
{
[
"id" => $id,
"text" => $text,
]
}
答案 5 :(得分:0)
如果我理解正确,我可以建议您为每个select2框隐藏输入<input type="hidden" name="customer_name" value="{{old('customer_name', '')}}">
,其中在select2更改事件后,您可以插入所选名称(等John
)。因此,如果验证失败,您可以:
<select id="customer" name="customer" class="searchselect searchselectstyle">
@if(!is_null(old('customer')))
<option value="{{old('customer')}}">{{old('customer_name')}}
</option>
@endif
</select>
答案 6 :(得分:0)
你可以这样做:
首先在控制器传递标签中使用如下所示的pluck helper进行查看:
public function create()
{
$tags= Customer::pluck('name','name');
return view('view',compact('tags'));
}
然后在你的表格中试试这个:
{!! Form::select('tag_list[]',$tags,old('tag_list'),'multiple','id'=>'tag_list']) !!}
不要忘记调用select2函数。
$('#tag_list').select2();
最后在控制器中:
public function store(ArticleRequest $request)
{
$model = new Model;
$tags=$request->input('tag_list');
$model->tag($tags);
}
注意标签功能不是Laravel的帮手,你实现它!该函数接受名称并将它们附加到某个事物的实例上。
祝你好运。
答案 7 :(得分:0)
我认为你自己的解决方案非常正确。你说$ customers的名单会变得非常大。
$customers->where('id', intval(Request::old('customer')))->first()
您是否需要将列表存储在变量$ customers中?您可以只搜索您想要的ID
App\Customer::where('id', intval(Request::old('customer')))->first()
按ID搜索不应该效率低下。否则,您可以使用表单发送名称并将其存储在旧请求中。下面显示了一些(脏)javascript。
$("#form").submit( function() {
var sel = document.getElementById("customer");
var text= sel.options[sel.selectedIndex].text;
$('<input />').attr('type', 'hidden')
.attr('name', "selected_customer_name")
.attr('value', text)
.appendTo('#form');
return true;
});
然后像yrv 16s回答:
<option value="{{old('customer')}}">{{old('selected_customer_name')}}
答案 8 :(得分:0)
我这样做是在文本输入隐藏的情况下进行的,效果很好:
此表单显示在弹出窗口和ajax中(使用Jquery-UJS)
表格:
<form action="{{ route('store_item', $order) }}" method="POST" data-remote="true">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('item_id') ? ' has-error' : '' }}">
<label class="control-label col-sm-2" for="item_id">Item: </label>
<div class="col-sm-10">
<select name="item_id" class="form-control" id="item_id">
@if(old('item_id') != null)
<option value="{{ old('item_id') }}" selected="selected">
{{ old('item_title') }}
</option>
@endif
</select>
</div>
{!! $errors->first('item_id', '<p class="text-center text-danger"<strong>:message</strong></p>') !!}
</div>
<input type="hidden" id="item_title" name ="item_title" value="{{ old('item_title') }}" />
<div class="form-group{{ $errors->has('quantity') ? ' has-error' : '' }}">
<label class="control-label col-sm-2" for="quantity">Cantidad: </label>
<div class="col-sm-10">
<input name="quantity" type="number" class="form-control" id="quantity" value="{{ old('quantity') }}"/>
</div>
{!! $errors->first('quantity', '<p class="text-center text-danger"><strong>:message</strong></p>') !!}
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-primary" data-disable-with="Guardando...">Guardar</button>
</form>
JAVASCRIPT:
<script type="text/javascript">
$(document).ready(function(){
$('#item_id').select2({
placeholder: 'Elige un item',
ajax: {
url: '{{ route('select_item_data') }}',
dataType: 'json',
delay: 250,
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.title,
id: item.id
}
})
};
},
cache: true
}
});
$('#item_id').on('change', function(e){
var title = $(this).select2('data')[0].text;
$('#item_title').val(title);
});
});
</script>
验证存储方法(控制器)
$validator = Validator::make($request->all(), [
'item_id' => 'required',
'quantity' => 'required'
]);
if ($validator->fails()) {
return redirect()
->route('create_item', $order)
->withInput($request->all())
->withErrors($validator);
}
在重定向中发送“ withInput”和“ withErrors”非常重要,因为我们正在使用再次创建的弹出窗口和ajax,并且不保留旧值。