Laravel сохраняет многостраничную форму

У меня есть форма из трех частей, в которой я хочу иметь возможность обновлять базу данных после каждой отправки. Есть одна таблица, в которой хранятся все поля ниже.

form1 asks for first and last name
form2 asks for email and phone
form3 asks for city and state

В моем контроллере у меня есть 3 отдельные функции для сохранения каждого шага формы:

public function name(Request $request){
    $lead = Lead::firstOrNew(123);
    $lead->firstName = $request->get('firstName ');
    $lead->lastName = $request->get('lastName');
    $lead->save();
    return redirect('/form2');
}

public function info(Request $request){
    $lead = Lead::find(123);
    $lead->email = $request->get('email');
    $lead->phone = $request->get('phone');
    $lead->save();
    return redirect('/form3');
}

public function address(Request $request){
    $lead = Lead::find(123);
    $lead->city = $request->get('city');
    $lead->state = $request->get('state');
    $lead->save();
    return redirect('/done');
}

Есть ли способ объединить это с одной функцией обновления?

0
0
579
5

Ответы 5

Вы можете реорганизовать методы для вызова общей функции «обновления». См. Пример кода ниже.

public function name(Request $request){
    $this->update(123, $request);
    return redirect('/form2');
}

public function info(Request $request){
    $this->update(123, $request);
    return redirect('/form3');
}

public function address(Request $request){
    $this->update(123, $request);
    return redirect('/done');
}

private function update($id, $request) {
    $lead = Lead::find($id);
    foreach ($field as ['firstName', 'lastName', ...]) {
        if ($request->has($field)) {
            $lead->{$field} = $request->get($field);
        }
    }
    $lead->save();
}

Вам нужно будет передать $request в качестве параметра функции update, иначе он будет недоступен.

Seva Kalashnikov 13.09.2018 20:37

Хороший улов. Обновлено

KJ789 13.09.2018 20:42

Просто выполните условную проверку, обновите модель и определите URL-адрес перенаправления:

public function info(Request $request) {
    $lead = Lead::firstOrNew(123);

    if ($request->has('firstName') && $request->has('lastName')) {
        $lead->firstName = $request->get('firstName ');
        $lead->lastName = $request->get('lastName');
        $redirect = '/form2';
    } else if ($request->has('email') && $request->has('phone')) {
        $lead->email = $request->get('email');
        $lead->phone = $request->get('lastName');
        $redirect = '/form3';
    } else if ($request->has('city') && $request->has('state')) {
        $lead->city = $request->get('city');
        $lead->state = $request->get('state');
        $redirect = '/done';
    }

    $lead->save();

    return redirect($redirect);
}

Кроме того, вы, вероятно, можете выполнить групповое обновление через update, просто убедитесь, что вы занесли в белый список атрибуты в своей модели.

public function info(Request $request) {
    $lead = Lead::firstOrNew(123);
    $lead->update($request->all());

    if ($request->has('firstName') && $request->has('lastName')) {
        $redirect = '/form2';
    } else if ($request->has('email') && $request->has('phone')) {
        $redirect = '/form3';
    } else if ($request->has('city') && $request->has('state')) {
        $redirect = '/done';
    }

    return redirect($redirect);
}

Или мне лучше просто добавить в вашу форму переменную перенаправления, например:

<input type="hidden" name="redirect" value="form1">

и упростите свой метод контроллера, например:

public function info(Request $request) {
    $lead = Lead::firstOrNew(123);
    $lead->update($request->all());

    return redirect($request->input('redirect'));
}

Вы можете добавить скрытое поле во все три формы (но с именем, например form_name) и установить их значения для идентификации формы (form1, form2, form3) при ее отправке. Затем в вашем контроллере вы проверяете значение поля form_name в запросе, чтобы определить, куда вы хотите перенаправить, например:

public function info(Request $request) {
    $lead = Lead::firstOrNew(123);
    $lead->update($request->all());

    //this will be from the hidden field (form_name)
    $form_type = $request->get('form_name');

    if ($form_type == 'form1') {
        $redirect = '/form2';
    } else if ($form_type == 'form2') {
        $redirect = '/form3';
    } else if ($form_type == 'form3') {
        $redirect = '/done';
    }

    return redirect($redirect);
}

Если у вас есть возможность использовать javaScript, сохраните данные первой и второй формы в файлах cookie или в локальном хранилище, и когда пользователь достигнет последней части формы, извлеките данные из файлов cookie или локального хранилища, а затем добавите их с последней формой, но сохраните их. в скрытом входе.

Учитывая, что HTTP-запросы не имеют состояния (что означает, что каждый запрос ничего не знает о запросе до и после него), я бы предпочел, чтобы вы использовали сеансы, чтобы вы могли хранить информацию, как вы redirect, от одного form к другому. В этом случае ваш код должен выглядеть так:

<?php

public function name(Request $request){
    Session::put('nameData', $request->all());   //Store the info from form1 in session and redirect to form2
    return redirect('/form2');
}

public function info(Request $request){
    $validSessionData = Session::has('nameData');

    if (!$validSessionData) {    //Check if the user filled form1, if not, go back to form1
        return redirect('/form1');
    }

    $nameAndInfo = Session::pull('nameData', []) + $request->all();  //Merge the info from form1 with info from form2. You could decide to keep them separate and merge later.

    Session::put('nameAndInfo', $nameAndInfo);
    return redirect('/form3');
}

public function address(Request $request){
    $validSessionData = Session::has('nameAndInfo');

    if (!$validSessionData) {   Another check. You could also extend this by checking for form2 session data
        return redirect('/form1');
    }

    $allData = Session::pull('nameAndInfo', []) + $request->all();  //Merge all session data
    $lead = Lead::firstOrNew(123);
    $lead->firstName = $allData['firstName'];
    $lead->lastName = $allData['lastName'];
    $lead->email = $allData['email'];
    $lead->phone = $allData['phone'];
    $lead->city = $allData['city'];
    $lead->state = $allData['state'];

    $lead->save();
    return redirect('/done');
}

Другие вопросы по теме