0

I have this very basic table displaying companies:

<table id="companies" class="table table-striped table-bordered" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th>Company Name</th>
            <th class="hidden-xs hidden-sm hidden-md">Business Field</th>
            <th class="hidden-xs hidden-sm">Area</th>
            <th class="hidden-xs hidden-sm">Related Items</th>
            <th class="hidden-xs">Subscription ends</th>
        </tr>
    </thead>
</table>

I am using "datatables 1.10" and the following initialization script:

oTable = $('#companies').dataTable({
    "processing": true,
    "serverSide": true,
    "ajax": {
        "url": "ajax/companies/get_companies.ajax.php"
        "type": "POST"
    },
    "columns": [
        { "bSearchable": true, "data": "company_name" },
        { "bSearchable": true, "data": "company_field" },
        { "bSearchable": true, "data": "company_area" },
        //{ "bSearchable": true, "data": "relative_items" }, //displays id numbers from DB eg: (6, 32, 17, 24) but I dont want to display just ID numbers
        { // Here I convert the item ID's array to Item Names
            "bSearchable": true,
            "data": "relative_items", 
            "mRender": function ( data )  {
                var trimResponse = "initialValue"; //if I don't set this variable I get datatables error...
                $.ajax({
                    type: "POST",
                    url: "companies/get_relative_items.php",
                    data: "datastring="+data,
                    success: function(resp){ 
                        trimResponse = $.trim(resp); 
                        console.log(trimResponse); //works! I can see the item names in console log
                    }
                })
                return trimResponse; //HOWEVER, datatables display the initial value of this variable and NOT the new one set by the above function
            }
        },
        { "bSearchable": false, "data": "subscription_end" }
    ],
    "order": [[1, 'asc']]
});
//alert(trimResponse); //if commented out, it also displays the initial value and not the one acquired by ajax

By reading the comments along the javascript, you may have already figured out that in the fourth column I want to display each company's related items (which are stored in another DB table).

I can display the ID numbers so far, but since ID numbers are not "human-friendly" I use ajax to return the id numbers array (eg: 2, 5, 3, 12) as the actual names that correspond with each item id (eg: Shirt, Trouser, Sock, Jacket).

But, although I can see the names array displayed correctly in the console, the datatables fourth column displays only the initial value of the variable "trimResponse" and NOT the new value that was given by ajax...

Any suggestions on how to display the ajax response in the datatables column? Thank you in advance.

1 Answer 1

1

Well, that was a tough one huh? :)

Anyway, after a lot of struggle, I decided to make a different approach to the problem:

  1. I changed the initialization script to it's "default" state:

    oTable = $('#companies').dataTable({
    "processing": true,
    "serverSide": true,
    "ajax": {
        "url": "ajax/companies/get_companies.ajax.php"
        "type": "POST"
    },
    "columns": [
        { "bSearchable": true, "data": "company_name" },
        { "bSearchable": true, "data": "company_field" },
        { "bSearchable": true, "data": "company_area" },
        { "bSearchable": true, "data": "relative_items" },
        { "bSearchable": false, "data": "subscription_end" }
    ],
    "order": [[1, 'asc']] });
    
  2. I decided that any changes should take place not in the initialization script, but in the ajax file that provided the results to the table ( ajax/companies/get_companies.ajax.php ).
    This script is the default server-side script which I got from datatables.net. Link here: http://www.datatables.net/examples/server_side/simple.html

Initially I would just define the columns array for the datatables like that:

$columns = array(
    array( 'db' => 'name', 'dt' => 'company_name' ),
    array( 'db' => 'business_field',  'dt' => 'company_field' ),
    array( 'db' => 'area',   'dt' => 'company_area' ),
    array( 'db' => 'items',     'dt' => 'relative_items' ),
    array(
        'db'        => 'subscription_ends',
        'dt'        => 'subscription_end',
        'formatter' => function( $d, $row ) {
            return date( 'd M Y', strtotime($d));
        }
    )
);

The WORKING SOLUTION was to use the 'formatter' also for the fourth column (as I was already doing for the fifth column). Like that:

$columns = array(
array( 'db' => 'name', 'dt' => 'company_name' ),
array( 'db' => 'business_field',  'dt' => 'company_field' ),
array( 'db' => 'area',   'dt' => 'company_area' ),
array( 
    'db'        => 'items',     
    'dt'        => 'relative_items',
    'formatter' => function( $d, $row ) {

        $conn = ... //CONNECTION TO THE DATABASE

        $items_array = str_replace("|", ", ", substr(substr($d, 1), 0, -1));
        //format the items strin from this: |3|12|7| to comma-separated 3,12,7

        $arr = explode(", ", $items_array);
        //create my array

        $first = reset($arr);
        $last = end($arr);

        foreach ($arr as $item_id) { //For each Id, get the corresponding Item Name:
            $get_item_name = mysql_query("SELECT name FROM ".DB_TABLE_PREFIX."items WHERE id = '$item_id' ");
            $row = mysql_fetch_array($get_item_name);
            //Append to the results comma and space (", ") except to the last one...
            if ($item_idx == $last) {
                $res .= $row["name"];
            }else{
                $res .= $row["name"];
                $res .= ", ";
            }
        }
        return $res;
        //and voila! worked like charm!
        //column now shows: Jacket, Shirt, T-shirt (instead of id's: 3, 12, 7)
    }
),
array(
    'db'        => 'subscription_ends',
    'dt'        => 'subscription_end',
    'formatter' => function( $d, $row ) {
        return date( 'd M Y', strtotime($d));
        }
    )
);

So, the solution was simply to look at the problem from a different angle!

Hope this helps some people!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.