Mr.P Mr.P - 1 year ago 545
jQuery Question

Laravel 5.2 update table with newly added record with AJAX without reloading page

My question is a bit specific ... I have a simple form in Laravel and on some of those fields I bind pop up windows with simple table ...

I need to achieve, that when you click on the icon after input field, popup will show up and you can insert via AJAX fields to the table .. This works perfect, until you want too see newly added record in the popup .. when I want to see it, i need to reload the page and open the popup again ...

Here comes my source ...

This my VIEW:

{{ Form::label('department_id', 'Department:') }}
{{ Form::select('department_id', $departments, $emp->department_id, array('placeholder' => 'Choose department ...')) }}

<a href="" id="firePopup_department">
<img src="{{ URL::asset('img/future.png') }}" alt="add_future_fields" title="Add future fields" class="add_future_icon"/>

<div id="department_content" title="Departments" style="display:none">
<div class="future_field_form">
{{ Form::label('dpt_new', 'Department:', array('class' => 'future_field_label')) }}
{{ Form::select('dpt_new', $departments, null, array('class' => 'future_field_input dpt_new', 'placeholder' => 'Choose department ...')) }}
<br />
{{ Form::label('dpt_from', 'Valid from:', array('class' => 'future_field_label')) }}
{{ Form::date('dtp_from', null, array('id' => 'from', 'class' => 'future_field_input dpt_from')) }}
{{ Form::submit('Save', array('class' => 'future_field_button', 'placeholder' => 'Submit')) }}
<br />
<p class="future_field_msg"></p>

<table class="future_field_table">
<th class="sys_action">Delete</th>
@foreach($future_fields as $ffield)
@if($ffield->field_name == 'department_id')
<td>{{ $departments->get($ffield->field_value) }}</td>
<td>{{ $ffield->valid_from }}</td>
<td>{{ $ffield->valid_to }}</td>
<td class="sys_action"><a href="#" title="Delete">delete</a></td>

This is AJAX I am calling (fired by event OnClick on .future_field_button)

$( ".future_field_button" ).click(function() {
var field_value = $('.dpt_new').val();
var valid_from = $('.dpt_from').val();
var field_name = 'department_id';
var emp_id = $('.emp_id').val();

//alert(field_name + " => " + field_value + ", " + valid_from + " for: " + emp_id);

// get real data
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
method: "POST",
url: '/add_future_field',
data: { field_value: field_value,
valid_from: valid_from,
field_name: field_name,
emp_id: emp_id,
// results on ERROR or SUCCESS
error: function(xhr, status, error){
$('.future_field_msg').css('color','red').text("Error! Contact admin ...");
success: function(data){
if(data == 'both_missing'){
$('.future_field_msg').css('color','red').text("Both fields must be filled!");
$('.future_field_msg').css('color','green').text(" " + data);

Route is pretty simple:

Route::post('add_future_field', 'EmployeeController@add_future_field');

and finally Controller:

public function add_future_field(Request $request){

$field_value = $request->input('field_value');
$valid_from = $request->input('valid_from');
$field_name = $request->input('field_name');
$emp_id = $request->input('emp_id');
$changed_by = Auth::user()->id;

if($field_value == '' || $valid_from == '') {
return "both_missing";

// insert data
$ffield = new FutureField;
$ffield->employee_id = $emp_id;
$ffield->field_name = $field_name;
$ffield->field_value = $field_value;
$ffield->valid_from = $valid_from;
$ffield->valid_to = '3000-01-01';
$ffield->created_by = $changed_by;

// get new actual results
$future_fields = array (
'future_fields' => FutureField::select('id', 'employee_id', 'field_name', 'valid_from', 'valid_from')
->where('field_name','=', $field_name) // only selected one
return $future_fields;
//return $field_name.";".$field_value.";".$valid_from.";".$emp_id.";".$changed_by;

I am not able to parse final $future_fields (with newly added records) to the destination table (view) .. can you help me how to do it? What am I missing?

Everything works well, until getting the up2date data ... they are inserted but now shown in the pop up window :( In the future_field_msg (p tag) i recieve
[object Object]

message in green color

Thank you

I've found one possible solution how to potentially deal with it .. after successful ajax request, I hide the table in div and rebuild it with jquery in the same structure again ... but is there is more sophisticated way how to achieve it? this sounds me like a 'nasty' workaround :) I'd prefer clean solution

SOLUTION (thx to @Thomas Van der Veen )


return response()->json($future_fields);

Ajax: (only the success part)

success: function(data){
if(data == 'both_missing'){
$('.future_field_msg').css('color','red').text("Both fields must be filled!");

// get table body and remove it
$('#department_content .future_field_table > tbody').empty();

// transform JSON object to JS array
var future_fields = data.future_fields;

for (i in future_fields) {

var future_field = future_fields[i];

// generate new row content
var newRowContent = "<tr><td>"+future_field.field_value_display+"</td><td>"+future_field.valid_from+"</td><td>"+future_field.valid_to+"</td><td class=\"sys_action\"><a href=\"#\" title=\"Delete\">x</a></td></tr>";

$(newRowContent).appendTo($('#department_content .future_field_table > tbody'));

$('.future_field_msg').css('color','green').text(field_value_display+" inserted!");

But I'm now facing the issue, that I am not able to repopulate the table with default {{ }} echo function in laravel .. I need to generate this

<td class="sys_action">
<a href="#" title="Delete">
<img src="{{ URL::asset('img/delete.gif') }}" class="future_field_edit_img" alt="delete" />

How could I do it??

Answer Source

In your controller you will have to return json.

Like this:

return response()->json($future_fields);


In your javascript you will have to loop this data and add them to the table.


success: function(data)

    for (i in data)

        var future_field = data[i];

        // Populate table



Edit after OP update

Instead of rebuilding the entire table you can remove the old rows and add new.


$table_body = $table.find('tbody');

// Remove all table rows

$table_row = $('<tr><td class="somecolumn"></td><td class="othercolumn"></td></tr>');

for (i in future_fields)

    var future_field = future_fields[i];

    // Fill table row with desired values


    // Append new table row to tbody


This code has not been tested but should be working (I think)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download