验证后,Laravel Select2旧输入

问题描述 投票:9回答:8

我在我的webapplication中使用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框中讨论数千行,这将是非常低效的。

我想必须有一个更好的解决方案。谁能帮我?

ajax laravel laravel-5 jquery-select2
8个回答
2
投票

通常以编程方式设置select2的值,您可以使用.val()方法,然后使用.trigger('change')调用as per their documentation(和other queries like this on SO)。但是,select2本身在他们的文档中有关于preselecting options for remotely sourced data的内容。

基本上他们的建议归结为(在初始化你的AJAX驱动的qazxsw poi之后):

  • 使用预先选择的ID对新的API端点进行另一次AJAX调用
  • 在AJAX调用完成后,动态创建一个新选项并从promise函数(<select>)附加到底层的<select> 也可以使用一些常规的jQuery回调链接函数
  • 触发.then()事件
  • 触发change事件(并传递整个select2:select对象)

假设您已经将旧数据闪存到会话中,data以各种方式,特别是这三个:

全局辅助方法更常被建议在Blade模板中使用,就像在这里的一些其他答案中一样,当你不需要操纵值并且可以直接将其插回时,它非常有用,你可以使用文字输入。

最后一个方法可能为您提供了您正在寻找的答案 - 而不是从视图内部查询整个集合,您可以从控制器中操作集合(类似于OP,但是应该更好,因为它不是在视图中解析它)或者根据旧ID从控制器发出另一个查询并获取所需的数据而不必搜索集合(更少的开销):

$request->old('customer')

无论哪种方式,在刀片模板处理任何内容之前,您都可以在指尖(作为视图变量)获得特定数据。

但是,如果您选择注入数据,它仍将遵循select2建议的模式:

  • 获取预先选择的数据
  • 为它创建一个选项
  • 触发相应的事件

唯一的区别是您不需要从另一个API端点获取数据(除非您因其他程序原因需要/需要)。


1
投票

我最终使用类似你的流程。但我的刀片模板使用的是htmlcollection包。

控制器: -

假设您使用的是$old_customer = Customer::find($request->old('customer')); 方法。验证失败时,它将重定向回创建页面。在此页面中,您可以重新填充列表。

create()

刀片视图:

$customer_list = [];
if(old('customer') != NULL){
    $customer_list = [old('customer') => $customers->where('id', old('customer'))->first()->name];        
}

0
投票

也许你可以尝试(一旦ajax调用结束):

{{ Form::select('customer', $customer_list, null,  ['class' => 'searchselect searchselectstyle', 'id' => 'customer']) }}

0
投票

同样的问题;我正在使用类似的解决方案:如果设置了旧的$ id,我得到了名称,并将其用作视图的变量;请注意,我也转发了id,因为我也使用此方法预填充表单(来自其他地方),但在这种情况下,名称只应该被使用,而id {{old('author_id') )}}可以在视图中使用:

在控制器中:

var oldCustomer = $('#customer > option[value={{ Request::old('customer') }}]');

if (oldCustomer.length > 0) {
    oldCustomer.attr('selected', 'selected');
}

在视图中(更准确地说,部分用于创作和版本):

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

0
投票

你的代码有点混乱。我不明白为什么你使用@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 请求使用ajax填充select2框来获取数据。

假设使用ajax调用返回的POST采用以下格式。

data

现在您可以做的是将一个额外的参数传递给您的ajax调用,如下所示

   [
     {
     "id": "Some id",
     "text": "Some text"
     },
     {
     "id": "ID 2",
     "text": "Text 2"
     },
    ]

现在在您的控制器中返回数据时,您可以为匹配该特定ID的ID抛出额外的属性url: function() { var type = $(this).attr('id'); @if(old('customer')) return '/get' + type + '?customer='+ {{ old('customer') }}; @else return '/get' + type; @endif }

selected:true

0
投票

如果我理解你,我可以建议你为每个你的select2框隐藏输入if( Request::has('customer') && Request::input('customer') == $id ) { [ "id" => $id, "text" => $text, "selected" => "true" ] } else { [ "id" => $id, "text" => $text, ] } ,在select2的更改事件之后,你可以插入所选名称(等<input type="hidden" name="customer_name" value="{{old('customer_name', '')}}">)。因此,如果验证失败,您有:

John

0
投票

你可以这样做:

首先在控制器传递标签中使用如下所示的pluck helper进行查看:

<select id="customer" name="customer" class="searchselect searchselectstyle">
@if(!is_null(old('customer')))
    <option value="{{old('customer')}}">{{old('customer_name')}}
   </option>
@endif
</select>

然后在你的表单中试试这个:

public function create()
{
    $tags= Customer::pluck('name','name');

    return view('view',compact('tags'));
}

不要忘记调用select2函数。

   {!! Form::select('tag_list[]',$tags,old('tag_list'),'multiple','id'=>'tag_list']) !!}

最后在控制器中:

    $('#tag_list').select2();

注意标记功能不是Laravel的帮手,你实现它!该函数接受名称并将它们附加到某个事物的实例上。

祝好运。


0
投票

我认为你自己的解决方案非常正确。你说$ customers的名单会变得非常大。

public function store(ArticleRequest $request)
 {
    $model = new Model;
    $tags=$request->input('tag_list');

    $model->tag($tags);
  }  

您是否需要将列表存储在变量$ customers中?你可以只搜索你想要的id

$customers->where('id', intval(Request::old('customer')))->first()

按id搜索不应该是低效的。否则,您可以使用表单发送名称并将其存储在旧请求中。下面显示了一些(脏)javascript。

App\Customer::where('id', intval(Request::old('customer')))->first()

然后像yrv 16s回答:

$("#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;
});
© www.soinside.com 2019 - 2024. All rights reserved.