2016-04-19 27 views
7

Używam Select2 w moim webaplikacji. Ładuję moje pola Select2 za pomocą Ajax. Gdy sprawdzanie poprawności zakończy się niepowodzeniem, wszystkie dane wejściowe zostaną wypełnione tak jak poprzednio, z wyjątkiem pola wyboru2. Jak mogę przywrócić starą wartość po niepowodzeniu sprawdzania poprawności formularza? Mój zakład korzystał z Request::old('x'), ale wstawia wartość (w moim przypadku identyfikator użytkownika) zamiast wybranego tekstu. Na przykład tekst John stanie się 27 w polu wyboru. Jak mogę odzyskać tekst?Laravel Select2 stare dane wejściowe po sprawdzeniu poprawności

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

Edit

Jedyny (brudny) rozwiązanie znalazłem tak daleko jest następujące:

<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 jest lista wszystkich klientów, więc oznacza to, że dla każdego pola Select2 muszę zapytaj dużą listę elementów, aby działało. Będzie to dość nieefektywne, jeśli mówimy o tysiącach wierszy na pole Select2.

Chyba musi być lepsze rozwiązanie. Kto może mi pomóc?

Odpowiedz

0

Może spróbujesz (raz wywołanie ajax zakończył):

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

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

Nie działa, ponieważ spowoduje ustawienie identyfikatora w polu zamiast powiązanego tekstu. Należy pamiętać, że dane dla select2 wyglądają następująco: [id: ..., text: ...] Więc twoje rozwiązanie ustawi identyfikator jako tekst dla opcji zamiast identyfikatora skojarzonego z identyfikatorem – Markinson

0

sam problem; Używam podobnego rozwiązania: Jeśli stary $ id jest ustawiony, otrzymuję nazwę i używam go jako zmiennej dla widoku; Zauważ, że przekazuję również ten identyfikator, ponieważ użyłem tej metody również do wcześniejszego wypełnienia formularza (pochodzącego z innego miejsca), ale w tym przypadku nazwa powinna być użyta tylko i dla id {{old ('author_id'))}} mogą być stosowane w ocenie:

w kontrolerze:

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

i w widoku (dokładniej, w częściowym używane do tworzenia & wydanie)

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

Twój kod jest nieco mylący. Nie rozumiem, dlaczego używasz żądania POST, aby uzyskać dane przy użyciu ajax, aby wypełnić pole select2.

Założenie, że data powrócił przy użyciu wywołania ajax, znajduje się w poniższym formacie.

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

Teraz to, co można zrobić, to przejść na dodatkowym parametrem do wywołania ajax jak poniżej

url: function() { 
        var type = $(this).attr('id'); 
        @if(old('customer')) 
        return '/get' + type + '?customer='+ {{ old('customer') }}; 
        @else 
        return '/get' + type; 
        @endif 
       } 

Teraz w kontrolerze podczas zwracania danych można rzucić dodatkowy atrybut selected:true dla dopasowania ID że konkretny identyfikator.

if(Request::has('customer') && Request::input('customer') == $id) 
{ 
[ 
"id" => $id, 
"text" => $text, 
"selected" => "true" 
] 
} 
else 
{ 
[ 
"id" => $id, 
"text" => $text, 
] 
} 
+0

twoja funkcja 'url:() {'to wywołanie, gdy strona przekierowuje z powrotem po niepowodzeniu sprawdzania poprawności, ale w jaki sposób zamierzasz pozostać w polu wyboru preselekcji select2? – Shiro

1

Kończę używać podobny przepływ jak twój. Ale mój szablon ostrza używa pakietu htmlcollection.

Kontroler: -

Powiedzmy jesteś w create() metody.Jeśli sprawdzanie poprawności nie powiedzie się, nastąpi przekierowanie z powrotem na stronę tworzenia. Z tej strony możesz ponownie zaludnić listę.

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

Blade Widok:

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

Gdybym zrozumiał pan rację mogę polecić cię mieć dla każdej skrzynce select2 ukryty wejściowego <input type="hidden" name="customer_name" value="{{old('customer_name', '')}}"> gdzie po zmianie imprezy dla Select2 można wstawić wybraną nazwę (itd. John). Więc jeżeli walidacja jest nie masz:

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

Można zrobić coś takiego:

Pierwszy w tagach kontroler podaje do wyświetlenia za pomocą oskubać pomocnika jak poniżej:

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

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

Następnie w formularzu spróbuj tego:

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

Nie zapomnij zadzwonić do funkcji select2.

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

I wreszcie w kontrolerze:

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

    $model->tag($tags); 
    } 

Wskazówka funkcja tag nie jest pomocnikiem w laravel, można wdrożyć go! Funkcja przyjmuje nazwy i dołącza je do instancji jakiejś rzeczy.

Powodzenia.

0

Myślę, że twoje własne rozwiązanie jest prawie poprawne. Mówisz, że lista $ klientów będzie dość duża.

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

Czy lista musi być przechowywana w zmiennej $ klienci? Możesz po prostu przeszukać identyfikator, który chcesz, aby nie był nieefektywny. Wyszukiwanie według identyfikatora nie powinno być nieskuteczne. W przeciwnym razie możesz wysłać imię i nazwisko za pomocą formularza i zapisać je w starym żądaniu. Pokazane poniżej z niektórymi (brudnymi) 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; 
}); 

Potem jak 16s YRV odpowiedzieć:

<option value="{{old('customer')}}">{{old('selected_customer_name')}} 
1

Normalnie programowo ustawić wartość Select2, można oczekiwać, aby użyć metody .val() następnie przez .trigger('change') rozmowy as per their documentation (i other queries like this on SO). Jednak select2 sami mają coś w swojej dokumentacji o preselecting options for remotely sourced data.

Zasadniczo ich propozycja sprowadza się do (po initalizing swój AJAX-driven <select>):

  • dokonać innego wywołanie AJAX do nowego punktu końcowego API przy użyciu wstępnie wybrany identyfikator
  • dynamicznie tworzyć nową opcję i dołączyć do leżącej <select> z funkcji obietnicy (.then()) po wywołaniu AJAX jest wykończone
    • mogą również korzystać z niektórych regularnych jQuery zwrotnego łańcuchowym funkcje na tej
  • spust change wydarzenie
  • wyzwalania zdarzenie select2:select (i przechodzą wzdłuż całej data obiektu)

Zakładając jesteś już migać starych danych do sesji Laravel provides handy access to the previously requested input w różnych sposoby, w szczególności te trzy:

  • dostęp statyczny za pośrednictwem klasy Request np. Request::old('customer') jak w OP
  • globalny old() helper np. old('customer'), która zwraca null Jeśli stary wejście dla danej dziedzinie istnieje i może mieć domyślnie jako drugiego parametru
  • stosując metodę old() na przykład Request z regulatora np $request->old('customer')

Globalna metoda pomocnik jest powszechnie sugerowane do stosowania wewnątrz szablonów Blade, jak w niektórych innych odpowiedzi tutaj, i jest przydatna, gdy nie trzeba manipulować wartość i można po prostu podłączyć go prosto w , co byś zrobił z takimi rzeczami jak wprowadzanie tekstu.

Ostatnia metoda prawdopodobnie zapewnia odpowiedź, której szukasz - zamiast wysyłać zapytania do całej kolekcji od wewnątrz widoku, możesz manipulować zbiorem z kontrolera (podobnie jak w przypadku OP, ale powinien być lepszy, ponieważ nie jest analizowanie go w widoku) lub dokonać innego zapytania z kontrolera opartego na starym ID i pobierać dane, które chcesz bez konieczności włoka kolekcja (mniej napowietrznych):

$old_customer = Customer::find($request->old('customer')); 

czy inaczej , będziesz miał dostęp do konkretnych danych na wyciągnięcie ręki (jako zmienna widoku), zanim szablon błon przetwarza cokolwiek.

jednak zdecydujesz się wprowadzić dane, to nadal będzie zgodne z wzorcem sugeruje Select2:

  • dostać wstępnie wybrane dane
  • utworzyć odpowiednią opcję dla niego
  • spustowych odpowiednich zdarzeń

Jedyną różnicą jest to, że nie trzeba pobierać danych z innego punktu końcowego API (chyba że chcesz/potrzebujesz z innych powodów programowych).

Powiązane problemy