5

I've got a form that I want to send by ajax-post to my controller. Meanwhile the HTML is waiting for the generation and saving of the records, I want to display the progress (for now just numbers). I really don't understand why the following code doesn't update <div id="progress"> with Session::get('progress').

Controller:

public function postGenerate() {
    // getting values from form (like $record_num)
    Session::flash('progress', 0);
    $i = 1;
    for ($i; $i < $record_num; $i++) {
        $record = new Record();
        // adding attributes...
        $record->save;
        Session::flash('progress', $i);
    }
    $response = Response::make();
    $response->header('Content-Type', 'application/json');
    return $response;
}

Javascript:

@section('scripts')
<script type="text/javascript">
    $(document).ready(function() {
        $('#form-overview').on('submit', function() {
            setInterval(function(){
                $('#progress').html( "{{ Session::get('progress') }}" );
            }, 1000);
            $.post(
                $(this).prop('action'),
                {"_token": $(this).find('input[name=_token]').val()},
                function() {
                    window.location.href = 'success';
                },
                'json'
            );
            return false;
        });
    });
</script>   
@stop

HTML:

@section('content')
    {{ Form::open(array('url' => 'code/generate', 'class' => 'form-inline', 'role' => 'form', 'id' => 'form-overview' )) }}
    <!-- different inputs ... -->
        {{ Form::submit('Codes generieren', array('class' => 'btn btn-lg btn-success')) }}
    {{ Form::close() }}

    <div id="progress">-1</div>
@stop
carl
  • 57
  • 1
  • 1
  • 5
  • Chances are the session data doesn't get stored until the end of the request. – ceejayoz Feb 03 '14 at 17:02
  • It seems to me that the session doesn't get updatet at all - even after the end of the request it contains still the initial value. Is there anybody who may explain this behaviour?? – carl Feb 03 '14 at 17:20
  • 1
    Well, that's because `{{ Session::get('progess') }}` is only evaluated once, when the page is first rendered. – rmobis Feb 03 '14 at 17:20

1 Answers1

7

Well, that's because {{ Session::get('progess') }} is only evaluated once, when the page is first rendered. The only way to do what you want is to actually make extra AJAX requests to a different URL that reports the progress. Something like this:

Controller

// Mapped to yoursite.com/progress
public function getProgess() {
    return Response::json(array(Session::get('progress')));
}

public function postGenerate() {
    // getting values from form (like $record_num)
    Session::put('progress', 0);
    Session::save(); // Remember to call save()

    for ($i = 1; $i < $record_num; $i++) {
        $record = new Record();

        // adding attributes...

        $record->save();
        Session::put('progress', $i);
        Session::save(); // Remember to call save()
    }

    $response = Response::make();
    $response->header('Content-Type', 'application/json');
    return $response;
}

JavaScript

@section('scripts')
<script type="text/javascript">
    $(document).ready(function() {
        $('#form-overview').on('submit', function() {
            setInterval(function(){
                $.getJSON('/progress', function(data) {
                    $('#progress').html(data[0]);
                });
            }, 1000);

            $.post(
                $(this).prop('action'),
                {"_token": $(this).find('input[name=_token]').val()},
                function() {
                    window.location.href = 'success';
                },
                'json'
            );

            return false;
        });
    });
</script>   
@stop
rmobis
  • 26,129
  • 8
  • 64
  • 65
  • Raphael_, thank you very much! Although your suggested solution seems to point into the right direction, I couldn't solve my problem by now: The `getJSON('/progress'...` is fired continuous, that's good. But their responses come not until the response of the `$.post` as arrived. So the `
    ` gets updated **to late**!
    – carl Feb 04 '14 at 08:40
  • That's probably because your main action is simply too fast. (As it seems to be, since all you're doing is saving a few records to the database) – rmobis Feb 04 '14 at 17:27
  • No, my main action takes definitely quite a while. But after some more research I found out that the problem is caused by locked session data. I can handle this problem with a simple `session_write_close`. More details may be found here: http://stackoverflow.com/questions/6903318/multiple-ajax-requests-delay-each-other – carl Feb 05 '14 at 12:08
  • 1
    I see... I thought `Session::save()` was meant to do that, though. – rmobis Feb 05 '14 at 19:08
  • Thanks for the idea. Except that instead of session I'm using temporary MySQL table. – Daniel Jan 09 '15 at 22:00
  • for me getjson not working.progress not updated.can u help me on this? – sivakumar Jun 16 '15 at 17:27
  • Thank you Raphael Mobis :) `Session::save();` this is really saved my ass! – Shinu K Narayanan Jan 19 '18 at 12:07