Na podstawie tego świetnego odcinka railscasts na temat wielokrokowych formularzy zrobiłem właśnie taki form. I dokładnie tak jak Ryan, używam dwóch submitów, ‘back’ i ‘continue’, wygląda to tak:
= simple_form_for @poster do |f|
= render "#{@poster.current_step}_step", f: f
= f.submit "Back", name: "back_button" unless @poster.first_step?
= f.submit "Continue"
oczywiście wszystko działa, ptaszki ćwierkają z radości, jest tylko jeden problem: kliknięcie przycisku “Back” by cofnąć się do poprzedniego kroku również wymaga by cała walidacja po stronie klienta przeszła pomyślnie. a to troche bez sensu żeby użytkownik musiał wypełniać pola przed tym jak poprawi błąd, którego skutkiem jest to że wyświetliły się zupełnie inne pola niż te o które mu chodziło. Jak zrobić taką magię żeby po kliknięciu w ten nieszczęsny “Back” walidacja client-side była omijana?
Ok, racja, dopiero teraz zauważyłem, że jest tam if @order.valid?. W takim razie chyba nie do końca rozumiem problem - ogólnie wykonanie metod takich jak #save i #valid? odpala walidację. Zmień kod tak, żeby #valid? wywoływać tylko jeśli to krok do przodu i nie będziesz miał tego problemu.
Jemu chodzi o walidacje html5, którą dodaje prawdopodobnie rails_ujs, tzn. dodaje ‘required: true’ jeżeli w modelu jest walidacja presence na jakieś pole.
if params[:back_button]
@order.previous_step
elsif @order.last_step?
@order.save if @order.all_valid?
else
if @order.valid?
@order.next_step
end
end
session[:order_step] = @order.current_step
czyli sprawdzać poprawność tylko w przypadku przejścia w przód? A na dobrą sprawę można by tylko zapamiętywać dane modelu a walidację robić na samym końcu - aczkolwiek przy takim podejściu i formularzu składającym się z wielu kroków, może być trochę głupio na samym końcu dostać błędy z kilku poprzednich formularzy
Zakładając oczywiście, że dasz odpowiednie id elementom. #myfield możesz zamienić na listę klas lub coś bardziej ogólnego jak #myform input[type=text], #myform input[type=email] etc.
@magnus proponujesz to samo co ja, a chodzi o walidację html5, która jest różna dla różnych przeglądarek.
Wow, patrzę co napisałem i przecieram oczy ;] Oczywiście, że bez żadnego else then - jak to sprawdzałem, to napisałem tam stringi, później zdałem sobie sprawę, że z true/false też będzie poprawnie, ale już konstrukcji nie zmieniłem.
P.S. to jest też dowód na to, że nie powinno się pisać kodu po prawie nieprzespanej nocy i locie samolotem, trzeba się porządnie wyspać… ;]
Pamiętaj, że ten odcinek ma ponad 3 lata. Omawiana tam metoda nie jest zbyt dobra i przejrzysta. Polecam do takich celów https://github.com/pluginaweek/state_machine - można definiować sobie walidacje per stan (krok).