Nikolay Naydenov
Nikolay Naydenov

Reputation: 113

Basic usage of ajax in Laravel

I'm developing a question and answer site and I want to be able to submit an answer to a question without refreshing the page. I'm using ajax but I click on the submit button nothing happens.

Here is my form. I know it's quite messy ;)

{{Form::open(array('method' => 'POST', 'class' => 'post_ans','action' => 'QuestionController@post_answer','style'=>'display:'.$textarea_display))}}
<textarea name="answer_content" rows="12"></textarea>
{{$errors->first('answer_content')}}
<input type="hidden" name="this_question" value="{{$question[0]->question_id}}">
<input type="submit" id="post_answer" value="Добави">

{{Form::close()}}

My route:

Route::post('/question','QuestionController@post_answer');

The controller:

public static function post_answer()
        {
            $data=Input::all();
            return Answer::postAnswer($data);
        }

The jquery code:

$('form.post_ans').on('submit',function(event){
        event.preventDefault();
        var data={
        this_question:$('#this_question').val(),
        answer_content:$('#answer_content').val()
    };

    console.log(data);
    var url= $(this).attr('action');
    console.log(url);
    $.ajax({
        type:"POST",
        url:url,
        data:data
    }).done(function(){
        console.log("success!");
    }).fail(function(){
        console.log('fail');
    }).always(function(){
        console.log("always");
    });

    });

And the model:

public static function postAnswer($data)
        {
            $rules=array(
                'answer_content'=>'required'
            );

            $messages=array(
                'answer_content.required'=>'Това поле е задължително'
            );

            $validator=Validator::make($data, $rules, $messages);

            if($validator->fails())
            {
                return Redirect::to('/question/'.$data['this_question'])->withErrors($validator);
            }
            else
            {
                $date=date('d.m.Y');
                $poster=Session::get('user_logged');
                DB::table('answers')->insert(array(
                    'to_question'=>$data['this_question'],
                    'content'=>$data['answer_content'],
                    'date'=>$date,
                    'class'=>0,
                    'subject'=>'undefined',
                    'likes'=>0,
                    'best_answer'=>'false',
                    'by'=>$poster
                ));

                DB::table('questions')->where('question_id',$data['this_question'])->increment('answers');
                return Redirect::to('/question/'.$data['this_question']);
            }

        }

And this is what I get in the console:

enter image description here

In the model I'm not sure what to do after the data is stored so I just redirect to the same page.

Upvotes: 0

Views: 109

Answers (1)

lesssugar
lesssugar

Reputation: 16181

Problem

First of all, if you look at your screenshot, the this_question property of the data object is undefined and this is how it gets to QuestionController in which you use $data['this_question'] for redirection. See how this can't work? Check the hidden field in your form, as this is where this_question is being set:

<input type="hidden" name="this_question" value="{{$question[0]->question_id}}">

Also, check your jQuery selectors for the data object. You use $('#...') for id, but I don't see elements with those id-s in the form.

Ajax

Secondly, the flag puropse of Ajax is not to make any reloads (or redirects), due to user experience. If you need a redirect and you want to keep Ajax, the right way to do it would be via JavaScript, in the .done() method - with window.location.href or window.location.reload(true).

To get a result in your .done() method, you need to return something to the JS script from your QuestionController. So, instead of redirecting, you would do something like that:

return Response::json(true);

after which you would get the response for .done():

.done(function(response) {
    cosole.log(response); // true
    window.location.href = '.......';
})

In general, consider whether having Ajax for the form is important or/and justified. Then refactor your code to something like I showed above, or forget the Ajax and make a standard form submit with redirect instead.

Knowledge

Good luck.

Upvotes: 1

Related Questions