Ejemplo n.º 1
0
function array_utf8_decode_recursive($dat)
{
    if (is_string($dat)) {
        return utf8_decode($dat);
    }
    if (is_object($dat)) {
        $ovs = get_object_vars($dat);
        $new = $dat;
        foreach ($ovs as $k => $v) {
            $new->{$k} = array_utf8_decode_recursive($new->{$k});
        }
        return $new;
    }
    if (!is_array($dat)) {
        return $dat;
    }
    $ret = array();
    foreach ($dat as $i => $d) {
        $ret[$i] = array_utf8_decode_recursive($d);
    }
    return $ret;
}
Ejemplo n.º 2
0
    /**
     * Generate JSON array for grid rendering
     * @param $grid_id Unique ID for grid
     */
    function render($grid_id)
    {
        // render grid for first time (non ajax), but specific grid on ajax calls
        $is_ajax = isset($_REQUEST["nd"]) || isset($_REQUEST["oper"]) || isset($_REQUEST["export"]);
        if ($is_ajax && $_REQUEST["grid_id"] != $grid_id) {
            return;
        }
        $append_by = strpos($this->options["url"], "?") === false ? "?" : "&";
        $this->options["url"] .= $append_by . "grid_id={$grid_id}";
        $this->options["editurl"] .= $append_by . "grid_id={$grid_id}";
        $this->options["cellurl"] .= $append_by . "grid_id={$grid_id}";
        if (isset($_REQUEST["subgrid"])) {
            $grid_id = "_" . $_REQUEST["subgrid"];
            #$grid_id = "_".preg_replace("/[^a-zA-Z0-9]+/", "", $grid_id);
        }
        $this->id = $grid_id;
        ### P ###
        // custom on select event execution
        if (!empty($this->events["on_select"])) {
            $func = $this->events["on_select"][0];
            $obj = $this->events["on_select"][1];
            $continue = $this->events["on_select"][2];
            $event_sql = "";
            $event_sql_count = "";
            if ($obj) {
                call_user_func(array($obj, $func), array("param" => $_REQUEST, "grid" => $this, "sql" => &$event_sql, "sql_count" => &$event_sql_count));
            } else {
                call_user_func($func, array("param" => $_REQUEST, "grid" => $this, "sql" => &$event_sql, "sql_count" => &$event_sql_count));
            }
            $this->internal["sql_count"] = $event_sql_count;
            $this->internal["sql"] = $event_sql;
        }
        // generate column names, if not defined
        if (!$this->options["colNames"]) {
            $this->set_columns();
        }
        ### P ###
        // persist search if asked
        if ($this->options["persistsearch"] === true) {
            $this->options["search"] = true;
            $this->options["postData"] = array("filters" => $_SESSION["jqgrid_{$grid_id}_searchstr"]);
            // this performs the search
            $array_of_search_values = json_decode($_SESSION["jqgrid_{$grid_id}_searchstr"], true);
            foreach ($array_of_search_values["rules"] as &$rules) {
                foreach ($this->options["colModel"] as &$col) {
                    if ($rules['field'] == $col["name"]) {
                        $search_word = $rules['data'];
                        $col["searchoptions"] = array("defaultValue" => $search_word);
                    }
                }
            }
        }
        ### P ###
        // manage uploaded files (grid_id check for master-detail fix || subgrid check)
        if (count($_FILES) && ($_REQUEST["grid_id"] == $grid_id || "_" . $_REQUEST["subgrid"] == $grid_id)) {
            $files = array_keys($_FILES);
            $fileElementName = $files[0];
            if (!empty($_FILES[$fileElementName]['error'])) {
                switch ($_FILES[$fileElementName]['error']) {
                    case '1':
                        $error = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
                        break;
                    case '2':
                        $error = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
                        break;
                    case '3':
                        $error = 'The uploaded file was only partially uploaded';
                        break;
                    case '4':
                        $error = 'No file was uploaded.';
                        break;
                    case '6':
                        $error = 'Missing a temporary folder';
                        break;
                    case '7':
                        $error = 'Failed to write file to disk';
                        break;
                    case '8':
                        $error = 'File upload stopped by extension';
                        break;
                    case '999':
                    default:
                        $error = 'No error code avaiable';
                }
            } elseif (empty($_FILES[$fileElementName]['tmp_name']) || $_FILES[$fileElementName]['tmp_name'] == 'none') {
                $error = 'No file was uploaded';
            } else {
                foreach ($this->options["colModel"] as $c) {
                    if ($c["upload_dir"] != "" && $c["name"] . "_file" == $fileElementName) {
                        $tmp_name = $_FILES[$fileElementName]["tmp_name"];
                        $name = $_FILES[$fileElementName]["name"];
                        $uploads_dir = $c["upload_dir"];
                        @mkdir($uploads_dir, 0755, true);
                        // set to rename file by default
                        if (empty($c["editrules"]["ifexist"])) {
                            $c["editrules"]["ifexist"] = "rename";
                        }
                        // check if required
                        if ($c["editrules"]["ifexist"] == "error") {
                            if (file_exists("{$uploads_dir}/{$name}")) {
                                $error = "File already exist: {$uploads_dir}/{$name}";
                                break;
                            }
                        } else {
                            if ($c["editrules"]["ifexist"] == "rename") {
                                // rename file if exist
                                $ext = strrchr($name, '.');
                                $prefix = substr($name, 0, -strlen($ext));
                                $i = 0;
                                while (file_exists("{$uploads_dir}/{$name}")) {
                                    $name = $prefix . "_" . ++$i . $ext;
                                }
                            }
                        }
                        if (@move_uploaded_file($tmp_name, "{$uploads_dir}/{$name}")) {
                            $msg = "{$uploads_dir}/{$name}";
                        } else {
                            $error = "Unable to move to desired folder {$uploads_dir}/{$name}";
                        }
                        break;
                    }
                }
            }
            echo "{";
            echo "error: '" . $error . "',";
            echo "msg: '" . $msg . "'";
            echo "}//";
            # fix for upload lib, it get response from doc body that include <canvas>
            die;
        }
        ### P-END ###
        if (isset($_POST['oper'])) {
            $op = $_POST['oper'];
            $data = $_POST;
            $pk_field = $this->options["colModel"][0]["index"];
            // fix for dialog edit v/s inline edit
            $id = isset($data[$pk_field]) ? $data[$pk_field] : $data["id"];
            // fix for mssql utf8 fix
            if (strpos($this->db_driver, "mssql") !== false) {
                $data = array_utf8_decode_recursive($data);
            }
            // formatters array for k->v
            $is_numeric = array();
            // reformat date w.r.t mysql
            foreach ($this->options["colModel"] as $c) {
                // don't fix vars that are not posted (celledit mode)
                if (!isset($data[$c["index"]])) {
                    continue;
                }
                // fix for short weekday name
                if (strstr($c["formatoptions"]["newformat"], "D")) {
                    $data[$c["index"]] = str_ireplace(array("sun", "mon", "tue", "wed", "thu", "fri", "sat"), "", $data[$c["index"]]);
                    $data[$c["index"]] = trim($data[$c["index"]]);
                }
                // fix for d/m/Y date format. strtotime expects m/d/Y
                if (strstr($c["formatoptions"]["newformat"], "d/m/Y")) {
                    $tmp = explode("/", $data[$c["index"]]);
                    $data[$c["index"]] = $tmp[1] . "/" . $tmp[0] . "/" . $tmp[2];
                }
                // put zeros for blank date field
                if (($c["formatter"] == "date" || $c["formatter"] == "datetime") && (empty($data[$c["index"]]) || $data[$c["index"]] == "//")) {
                    $data[$c["index"]] = "NULL";
                } else {
                    if ($c["isnull"] && empty($data[$c["index"]])) {
                        $data[$c["index"]] = "NULL";
                    } else {
                        if ($c["formatter"] == "date") {
                            $data[$c["index"]] = date("Y-m-d", strtotime($data[$c["index"]]));
                        } else {
                            if ($c["formatter"] == "datetime") {
                                $data[$c["index"]] = date("Y-m-d H:i:s", strtotime($data[$c["index"]]));
                            } else {
                                if ($c["formatter"] == "autocomplete" && $c["index"] != $c["formatoptions"]["update_field"]) {
                                    unset($data[$c["index"]]);
                                } else {
                                    if ($c["formatter"] == "password" && $data[$c["index"]] == "*****") {
                                        unset($data[$c["index"]]);
                                    }
                                }
                            }
                        }
                    }
                }
                // isnumeric check for sql '' issue
                if ($c["isnum"] === true) {
                    $is_numeric[$c["index"]] = true;
                }
            }
            // handle grid operations of CRUD
            switch ($op) {
                ### P ###
                case "autocomplete":
                    $field = $data['element'];
                    $term = $data['term'];
                    foreach ($this->options["colModel"] as $c) {
                        if ($c["index"] == $field) {
                            // if subqurey
                            if (preg_match('/SELECT (.*) \\((.*)\\) (.*)/', $c["formatoptions"]["sql"], $match)) {
                                if (preg_match('/SELECT .* \\((.*)\\) (.*) WHERE (.*)/', $c["formatoptions"]["sql"], $match)) {
                                    $cond = "AND";
                                } else {
                                    $cond = "WHERE";
                                }
                            } else {
                                if (stristr($c["formatoptions"]["sql"], " WHERE ")) {
                                    $cond = "AND";
                                } else {
                                    $cond = "WHERE";
                                }
                            }
                            $sql = $c["formatoptions"]["sql"] . " {$cond} {$c["formatoptions"]["search_on"]} like '{$term}%'";
                            $result = $this->execute_query($sql);
                            if ($this->con) {
                                $rows = $result->GetArray();
                                foreach ($rows as $key => $row) {
                                    $arr = array();
                                    $arr['id'] = isset($row["K"]) ? $row["K"] : $row["k"];
                                    $arr['label'] = isset($row["V"]) ? $row["V"] : $row["v"];
                                    $arr['value'] = isset($row["V"]) ? $row["V"] : $row["v"];
                                    $data_arr[] = $arr;
                                }
                            } else {
                                while ($row = mysql_fetch_assoc($result)) {
                                    $arr = array();
                                    $arr['id'] = $row['k'];
                                    $arr['label'] = $row['v'];
                                    $arr['value'] = $row['v'];
                                    $data_arr[] = $arr;
                                }
                            }
                            header('Content-type: application/json');
                            echo json_encode($data_arr);
                            die;
                        }
                    }
                    break;
                    ### P ###
                ### P ###
                case "clone":
                    // only clone if grid id is matched (fix for master-detail)
                    if ($data["grid_id"] != $grid_id) {
                        break;
                    }
                    $src_id = $data['id'];
                    // get columns to build INSERT - SELECT query
                    $sql = "SELECT * FROM " . $this->table . " LIMIT 1 OFFSET 0";
                    $sql = $this->prepare_sql($sql, $this->db_driver);
                    $result = $this->execute_query($sql);
                    // and exclude PK
                    if ($this->con) {
                        $arr = $result->FetchRow();
                        foreach ($arr as $k => $rs) {
                            if ($k != $pk_field) {
                                $f[] = $k;
                            }
                        }
                    } else {
                        $numfields = mysql_num_fields($result);
                        for ($i = 0; $i < $numfields; $i++) {
                            $k = mysql_field_name($result, $i);
                            if ($k != $pk_field) {
                                $f[] = $k;
                            }
                        }
                    }
                    // custom onclone event execution
                    if (!empty($this->events["on_clone"])) {
                        $func = $this->events["on_clone"][0];
                        $obj = $this->events["on_clone"][1];
                        $continue = $this->events["on_clone"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $src_id, "params" => &$f));
                        } else {
                            call_user_func($func, array($pk_field => $src_id, "params" => &$f));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    $fields_str = implode(",", $f);
                    $sql = "INSERT INTO {$this->table} ({$fields_str}) SELECT {$fields_str} FROM {$this->table} WHERE {$pk_field} = {$src_id}";
                    $insert_id = $this->execute_query($sql, "insert_id");
                    if (intval($insert_id) > 0) {
                        $res = array("id" => $insert_id, "success" => true);
                    } else {
                        $res = array("id" => 0, "success" => false);
                    }
                    echo json_encode($res);
                    break;
                case "add":
                    if ($pk_field != "id") {
                        unset($data['id']);
                    }
                    unset($data['oper']);
                    $update_str = array();
                    ### P ###
                    // custom oninsert event execution
                    if (!empty($this->events["on_insert"])) {
                        $func = $this->events["on_insert"][0];
                        $obj = $this->events["on_insert"][1];
                        $continue = $this->events["on_insert"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $id, "params" => &$data));
                        } else {
                            call_user_func($func, array($pk_field => $id, "params" => &$data));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    foreach ($data as $k => $v) {
                        // skip first column while insert, unless autoid = false
                        if ($k == $pk_field && $this->options["colModel"][0]["autoid"] !== false) {
                            continue;
                        }
                        $k = addslashes($k);
                        $v = $this->escape_string($v);
                        $v = $v == "NULL" || $is_numeric[$k] === true ? $v : "'{$v}'";
                        $values_str[] = "{$v}";
                        // add tilde sign for mysql
                        if (strpos($this->db_driver, "mysql") !== false || !isset($this->db_driver)) {
                            $k = "`{$k}`";
                        }
                        $fields_str[] = "{$k}";
                    }
                    $insert_str = "(" . implode(",", $fields_str) . ") VALUES (" . implode(",", $values_str) . ")";
                    $sql = "INSERT INTO {$this->table} {$insert_str}";
                    $insert_id = $this->execute_query($sql, "insert_id");
                    ### P ###
                    // custom onupdate event execution
                    if (!empty($this->events["on_after_insert"])) {
                        $func = $this->events["on_after_insert"][0];
                        $obj = $this->events["on_after_insert"][1];
                        $continue = $this->events["on_after_insert"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $insert_id, "params" => &$data));
                        } else {
                            call_user_func($func, array($pk_field => $insert_id, "params" => &$data));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    // for inline row addition, return insert id to update PK of grid (e.g. order_id#33)
                    if ($id == "new_row") {
                        die($pk_field . "#" . $insert_id);
                    }
                    // return JSON response for insert id
                    if (intval($insert_id) > 0) {
                        $res = array("id" => $insert_id, "success" => true);
                    } else {
                        $res = array("id" => 0, "success" => false);
                    }
                    echo json_encode($res);
                    break;
                case "edit":
                    //pr($_POST);
                    if ($pk_field != "id") {
                        unset($data['id']);
                    }
                    unset($data['oper']);
                    $update_str = array();
                    ### P ###
                    // custom onupdate event execution
                    if (!empty($this->events["on_update"])) {
                        $func = $this->events["on_update"][0];
                        $obj = $this->events["on_update"][1];
                        $continue = $this->events["on_update"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $id, "params" => &$data));
                        } else {
                            call_user_func($func, array($pk_field => $id, "params" => &$data));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    foreach ($data as $k => $v) {
                        $k = addslashes($k);
                        // skip PK in update sql
                        if ($k == $pk_field) {
                            continue;
                        }
                        // add tilde sign for mysql
                        if (strpos($this->db_driver, "mysql") !== false || !isset($this->db_driver)) {
                            $k = "`{$k}`";
                        }
                        $v = $this->escape_string($v);
                        // dont update blank fields in case of bulk edit
                        if (strstr($id, ",") !== false && ($v === "" || $v == "NULL")) {
                            continue;
                        }
                        $v = $v == "NULL" || $is_numeric[$k] === true ? $v : "'{$v}'";
                        $update_str[] = "{$k}={$v}";
                    }
                    // don't run update if no field is changed (in bulk edit)
                    if (count($update_str) == 0) {
                        break;
                    }
                    $update_str = "SET " . implode(",", $update_str);
                    $id = "'" . implode("','", explode(",", $id)) . "'";
                    $sql = "UPDATE {$this->table} {$update_str} WHERE {$pk_field} IN ({$id})";
                    $ret = $this->execute_query($sql);
                    ### P ###
                    // custom on after update event execution
                    if (!empty($this->events["on_after_update"])) {
                        $func = $this->events["on_after_update"][0];
                        $obj = $this->events["on_after_update"][1];
                        $continue = $this->events["on_after_update"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $id, "params" => &$data));
                        } else {
                            call_user_func($func, array($pk_field => $id, "params" => &$data));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    // return JSON response for update (passing id that was updated)
                    if ($ret) {
                        $res = array("id" => $id, "success" => true);
                    } else {
                        $res = array("id" => 0, "success" => false);
                    }
                    echo json_encode($res);
                    break;
                case "del":
                    // row to delete is passed as id
                    $id = $data["id"];
                    ### P ###
                    // custom on delete event execution
                    if (!empty($this->events["on_delete"])) {
                        $func = $this->events["on_delete"][0];
                        $obj = $this->events["on_delete"][1];
                        $continue = $this->events["on_delete"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $id));
                        } else {
                            call_user_func($func, array($pk_field => $id));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    $id = "'" . implode("','", explode(",", $id)) . "'";
                    $sql = "DELETE FROM {$this->table} WHERE {$pk_field} IN ({$id})";
                    $this->execute_query($sql);
                    ### P ###
                    // custom on after delete event execution
                    if (!empty($this->events["on_after_delete"])) {
                        $func = $this->events["on_after_delete"][0];
                        $obj = $this->events["on_after_delete"][1];
                        $continue = $this->events["on_after_delete"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array($pk_field => $id));
                        } else {
                            call_user_func($func, array($pk_field => $id));
                        }
                        if (!$continue) {
                            break;
                        }
                    }
                    break;
            }
            die;
        }
        // apply search conditions (where clause)
        $wh = "";
        if (!isset($_REQUEST['_search'])) {
            $_REQUEST['_search'] = "";
        }
        $searchOn = $this->strip($_REQUEST['_search']);
        if ($searchOn == 'true') {
            $fld = $this->strip($_REQUEST['searchField']);
            $cols = array();
            foreach ($this->options["colModel"] as $col) {
                $cols[] = $col["index"];
            }
            // quick search bar
            if (!$fld) {
                $searchstr = $this->strip($_REQUEST['filters']);
                // persist search string
                $_SESSION["jqgrid_{$this->id}_searchstr"] = $searchstr;
                $wh = $this->construct_where($searchstr);
            } else {
                if (in_array($fld, $cols)) {
                    $fldata = $this->strip($_REQUEST['searchString']);
                    $foper = $this->strip($_REQUEST['searchOper']);
                    // costruct where
                    $wh .= " AND " . $fld;
                    switch ($foper) {
                        case "eq":
                            if (is_numeric($fldata)) {
                                $wh .= " = " . $fldata;
                            } else {
                                $wh .= " = '" . $fldata . "'";
                            }
                            break;
                        case "ne":
                            if (is_numeric($fldata)) {
                                $wh .= " <> " . $fldata;
                            } else {
                                $wh .= " <> '" . $fldata . "'";
                            }
                            break;
                        case "lt":
                            if (is_numeric($fldata)) {
                                $wh .= " < " . $fldata;
                            } else {
                                $wh .= " < '" . $fldata . "'";
                            }
                            break;
                        case "le":
                            if (is_numeric($fldata)) {
                                $wh .= " <= " . $fldata;
                            } else {
                                $wh .= " <= '" . $fldata . "'";
                            }
                            break;
                        case "gt":
                            if (is_numeric($fldata)) {
                                $wh .= " > " . $fldata;
                            } else {
                                $wh .= " > '" . $fldata . "'";
                            }
                            break;
                        case "ge":
                            if (is_numeric($fldata)) {
                                $wh .= " >= " . $fldata;
                            } else {
                                $wh .= " >= '" . $fldata . "'";
                            }
                            break;
                        case "ew":
                            $wh .= " LIKE '%" . $fldata . "'";
                            break;
                        case "en":
                            $wh .= " NOT LIKE '%" . $fldata . "'";
                            break;
                        case "cn":
                            $wh .= " LIKE '%" . $fldata . "%'";
                            break;
                        case "nc":
                            $wh .= " NOT LIKE '%" . $fldata . "%'";
                            break;
                        case "in":
                            $wh .= " IN (" . $fldata . ")";
                            break;
                        case "ni":
                            $wh .= " NOT IN (" . $fldata . ")";
                            break;
                        case "nu":
                            $wh .= " IS NULL";
                            break;
                        case "nn":
                            $wh .= " IS NOT NULL";
                            break;
                        case "bw":
                        default:
                            $fldata .= "%";
                            $wh .= " LIKE '" . $fldata . "'";
                            break;
                    }
                }
            }
            // setting to persist where clause in export option
            $_SESSION["jqgrid_{$grid_id}_filter"] = $wh;
            $_SESSION["jqgrid_{$grid_id}_filter_request"] = $_REQUEST["filters"];
        } elseif ($searchOn == 'false') {
            unset($_SESSION["jqgrid_{$grid_id}_filter"]);
            unset($_SESSION["jqgrid_{$grid_id}_filter_request"]);
        }
        // generate main json
        if (isset($_GET['jqgrid_page'])) {
            $page = $_GET['jqgrid_page'];
            // get the requested page
            $limit = $_GET['rows'];
            // get how many rows we want to have into the grid
            $sidx = $_GET['sidx'];
            // get index row - i.e. user click to sort
            $sord = $_GET['sord'];
            // get the direction
            if (!$sidx) {
                $sidx = 1;
            }
            if (!$limit) {
                $limit = 20;
            }
            // persist for export data
            if (isset($_GET["export"])) {
                $sidx = $_SESSION["jqgrid_{$grid_id}_sort_by"];
                $sord = $_SESSION["jqgrid_{$grid_id}_sort_order"];
                $limit = $_SESSION["jqgrid_{$grid_id}_rows"];
            } else {
                $_SESSION["jqgrid_{$grid_id}_sort_by"] = $sidx;
                $_SESSION["jqgrid_{$grid_id}_sort_order"] = $sord;
                $_SESSION["jqgrid_{$grid_id}_rows"] = $limit;
            }
            ### P ###
            // if export option is requested
            if (isset($_GET["export"])) {
                set_time_limit(0);
                $arr = array();
                // export data array (if grid loaded from array)
                if (is_array($this->table)) {
                    $t = $this->table;
                    foreach ($t[0] as $k => $v) {
                        $temp[$k] = ucwords($k);
                    }
                    $arr[] = $temp;
                    foreach ($t as $key => $value) {
                        $arr[] = $value;
                    }
                    // custom export function if needed
                    if (!empty($this->events["on_export"])) {
                        $func = $this->events["on_export"][0];
                        $obj = $this->events["on_export"][1];
                        $continue = $this->events["on_export"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array("data" => $arr, "grid" => &$this));
                        } else {
                            call_user_func($func, array("data" => $arr, "grid" => &$this));
                        }
                        if (!$continue) {
                            exit(0);
                        }
                    }
                } else {
                    // by default export all
                    $export_where = "";
                    if ($this->options["export"]["range"] == "filtered") {
                        $export_where = $_SESSION["jqgrid_{$grid_id}_filter"];
                    }
                    $limit_sql = "";
                    if ($this->options["export"]["paged"] == "1") {
                        $offset = $limit * $page - $limit;
                        // do not put $limit*($page - 1)
                        if ($offset < 0) {
                            $offset = 0;
                        }
                        $limit_sql = "LIMIT {$limit} OFFSET {$offset}";
                    }
                    // if sql is set on on_select event
                    if (!empty($this->internal["sql"])) {
                        $SQL = $this->internal["sql"] . " {$limit_sql}";
                    } else {
                        if (($p = stripos($this->select_command, "GROUP BY")) !== false) {
                            $start = substr($this->select_command, 0, $p);
                            $end = substr($this->select_command, $p);
                            $SQL = $start . $export_where . $end . " ORDER BY {$sidx} {$sord} {$limit_sql}";
                        } else {
                            $SQL = $this->select_command . $export_where . " ORDER BY {$sidx} {$sord} {$limit_sql}";
                        }
                    }
                    // custom export function if needed
                    if (!empty($this->events["on_export"])) {
                        $func = $this->events["on_export"][0];
                        $obj = $this->events["on_export"][1];
                        $continue = $this->events["on_export"][2];
                        if ($obj) {
                            call_user_func(array($obj, $func), array("sql" => $SQL, "grid" => &$this));
                        } else {
                            call_user_func($func, array("sql" => $SQL, "grid" => &$this));
                        }
                        if (!$continue) {
                            exit(0);
                        }
                    }
                    $SQL = $this->prepare_sql($SQL, $this->db_driver);
                    $result = $this->execute_query($SQL);
                    foreach ($this->options["colModel"] as $c) {
                        $header[$c["name"]] = $c["title"];
                    }
                    $arr[] = $header;
                    if ($this->con) {
                        $rows = $result->GetRows();
                        foreach ($rows as $row) {
                            $export_data = array();
                            foreach ($header as $k => $v) {
                                $export_data[$k] = $row[$k];
                            }
                            $arr[] = $export_data;
                        }
                    } else {
                        while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                            $export_data = array();
                            foreach ($header as $k => $v) {
                                $export_data[$k] = $row[$k];
                            }
                            $arr[] = $export_data;
                        }
                    }
                }
                $col_widths = array();
                // export only selected columns
                $cols_not_to_export = array();
                $cols_to_export = array();
                if ($this->options["colModel"]) {
                    foreach ($this->options["colModel"] as $c) {
                        // column chooser integration with export
                        if (isset($_COOKIE["jqgrid_colchooser"])) {
                            $colchooser = explode(",", $_COOKIE["jqgrid_colchooser"]);
                            if (!in_array($c["name"], $colchooser)) {
                                $c["export"] = false;
                            }
                        }
                        if ($c["export"] === false) {
                            $cols_not_to_export[] = $c["name"];
                        } else {
                            $cols_to_export[] = $c["name"];
                            $col_widths[$c["name"]] = !empty($c["width"]) ? $c["width"] : 'auto';
                        }
                    }
                }
                // custom on_data_display event execution (for export)
                if (!empty($this->events["on_data_display"])) {
                    $func = $this->events["on_data_display"][0];
                    $obj = $this->events["on_data_display"][1];
                    // remove header
                    $h = array_shift($arr);
                    if ($obj) {
                        call_user_func(array($obj, $func), array("params" => &$arr));
                    } else {
                        call_user_func($func, array("params" => &$arr));
                    }
                    // add header
                    array_unshift($arr, $h);
                }
                // fix for d/m/Y date format in export. strtotime expects m/d/Y
                foreach ($this->options["colModel"] as $c) {
                    foreach ($arr as &$rec) {
                        // skip header from date format conversion
                        if ($rec === $arr[0]) {
                            continue;
                        }
                        // show masked data in password
                        if (isset($c["formatter"]) && $c["formatter"] == "password") {
                            $rec[$c["name"]] = "*****";
                        }
                        if (!empty($rec[$c["name"]]) && ($c["formatter"] == "date" || $c["formatter"] == "datetime")) {
                            $dt = $rec[$c["name"]];
                            $js_dt_fmt = $c["formatoptions"]["newformat"];
                            $js_dt_fmt = str_replace("yy", "Y", $js_dt_fmt);
                            $js_dt_fmt = str_replace("mm", "m", $js_dt_fmt);
                            $js_dt_fmt = str_replace("dd", "d", $js_dt_fmt);
                            $rec[$c["name"]] = date($js_dt_fmt, strtotime($dt));
                        }
                        ### P ###
                        // Replace condition data in pdf export
                        $col_name = $c["name"];
                        if (isset($c["default"]) && !isset($rec[$col_name])) {
                            $rec[$col_name] = $c["default"];
                        }
                        // link data in grid to any given url
                        if (!empty($link_c["default"])) {
                            // replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
                            $rec[$col_name] = $this->replace_row_data($rec, $c["default"]);
                        }
                        // check conditional data
                        if (!empty($c["condition"][0])) {
                            $r = true;
                            // replace {} placeholders from connditional data
                            $c["condition"][1] = $this->replace_row_data($rec, $c["condition"][1]);
                            $c["condition"][2] = $this->replace_row_data($rec, $c["condition"][2]);
                            $row = $rec;
                            eval("\$r = " . $c["condition"][0] . ";");
                            $rec[$col_name] = $r ? $c["condition"][1] : $c["condition"][2];
                            $rec[$col_name] = strip_tags($rec[$col_name]);
                        }
                        // check data filter (alternate of grid on_data_display, but for current column)
                        if (!empty($c["on_data_display"])) {
                            $func = $c["on_data_display"][0];
                            $obj = $c["on_data_display"][1];
                            if ($obj) {
                                $row[$col_name] = call_user_func(array($obj, $func), $rec);
                            } else {
                                $row[$col_name] = call_user_func($func, $rec);
                            }
                        }
                    }
                }
                // remove db columns as well as virtual columns
                if (!empty($cols_to_export)) {
                    $export_arr = array();
                    foreach ($arr as $arr_item) {
                        foreach ($arr_item as $k => $i) {
                            if (!in_array($k, $cols_to_export)) {
                                unset($arr_item[$k]);
                            }
                        }
                        $export_arr[] = $arr_item;
                    }
                    $arr = $export_arr;
                }
                // fix for mssql utf8 fix
                if (strpos($this->db_driver, "mssql") !== false) {
                    $arr = array_utf8_encode_recursive($arr);
                }
                if (!$this->options["export"]["filename"]) {
                    $this->options["export"]["filename"] = $grid_id;
                }
                if (!$this->options["export"]["sheetname"]) {
                    $this->options["export"]["sheetname"] = ucwords($grid_id) . " Sheet";
                }
                // fix for ie - http://support.microsoft.com/kb/316431
                if (preg_match('/(?i)msie /', $_SERVER['HTTP_USER_AGENT'])) {
                    header('Cache-control: cache,must-revalidate');
                }
                if ($this->options["export"]["format"] == "pdf") {
                    if ($this->options["export"]["render_type"] == "html") {
                        $html = "";
                        // if customized pdf render is defined, use that
                        if (!empty($this->events["on_render_pdf"])) {
                            $func = $this->events["on_render_pdf"][0];
                            $obj = $this->events["on_render_pdf"][1];
                            if ($obj) {
                                $html = call_user_method($func, $obj, array("grid" => $this, "data" => $arr));
                            } else {
                                $html = call_user_func($func, array("grid" => $this, "data" => $arr));
                            }
                        } else {
                            $html .= "<h1>" . $this->options["export"]["heading"] . "</h1>";
                            $html .= '<table border="0" cellpadding="4" cellspacing="2">';
                            $i = 0;
                            foreach ($arr as $v) {
                                $shade = $i++ % 2 ? 'bgcolor="#efefef"' : '';
                                $html .= "<tr>";
                                foreach ($v as $d) {
                                    // bold header
                                    if ($i == 1) {
                                        $html .= "<td bgcolor=\"lightgrey\"><strong>{$d}</strong></td>";
                                    } else {
                                        $html .= "<td {$shade}>{$d}</td>";
                                    }
                                }
                                $html .= "</tr>";
                            }
                            $html .= "</table>";
                        }
                    }
                    $orientation = $this->options["export"]["orientation"];
                    if ($orientation == "landscape") {
                        $orientation = "L";
                    } else {
                        $orientation = "P";
                    }
                    $paper = $this->options["export"]["paper"];
                    // Using opensource TCPdf lib
                    // for more options visit http://www.tcpdf.org/examples.php
                    require_once 'tcpdf/config/lang/eng.php';
                    require_once 'tcpdf/class.TCPDF.EasyTable.php';
                    // create new PDF document
                    $pdf = new TCPDF_EasyTable($orientation, PDF_UNIT, $paper, true, 'UTF-8', false);
                    // set document information
                    $pdf->SetCreator("www.phpgrid.org");
                    $pdf->SetAuthor('www.phpgrid.org');
                    $pdf->SetTitle('www.phpgrid.org');
                    $pdf->SetSubject($this->options["caption"]);
                    $pdf->SetKeywords('www.phpgrid.org');
                    // remove default header/footer
                    $pdf->setPrintHeader(true);
                    $pdf->setPrintFooter(true);
                    // set default monospaced font
                    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
                    $pdf->setFontSubsetting(false);
                    //set margins
                    $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
                    //set auto page breaks
                    $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
                    //set image scale factor
                    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
                    // set some language dependent data:
                    // lines for rtl pdf generation
                    if ($this->options["direction"] == "rtl") {
                        $lg = array();
                        $lg['a_meta_charset'] = 'UTF-8';
                        $lg['a_meta_dir'] = 'rtl';
                        $lg['a_meta_language'] = 'fa';
                        $lg['w_page'] = 'page';
                    }
                    $pdf->setLanguageArray($lg);
                    // To set your custom font
                    // $fontname = $pdf->addTTFfont('/path-to-font/DejaVuSans.ttf', 'TrueTypeUnicode', '', 32);
                    // set font http://www.tcexam.org/doc/code/classTCPDF.html#afd56e360c43553830d543323e81bc045
                    # Table parameters
                    $pdf->SetFont('helvetica', '', 12);
                    // for special charset language, uncoment this line
                    // $pdf->SetFont('cid0jp', '', 10);
                    // add a page
                    $pdf->AddPage();
                    // output the HTML content
                    if ($this->options["export"]["render_type"] == "html") {
                        $pdf->writeHTML($html, true, false, true, false, '');
                        $pdf->Output($this->options["export"]["filename"] . ".pdf", 'I');
                        die;
                    }
                    $pdf->SetY(10, true);
                    $pdf->Cell(0, 15, $this->options["export"]["heading"], 0, 1);
                    $pdf->SetHeaderCellsFontStyle('');
                    // 'b'
                    $pdf->SetHeaderCellsFillColor(150, 150, 150);
                    $pdf->SetHeaderCellsFontColor(0, 0, 0);
                    $pdf->SetFillColor(240, 240, 240);
                    // for cells background
                    $pdf->SetCellFontColor(0, 0, 0);
                    // auto set column widths based on grid column width
                    $margins = $pdf->GetMargins();
                    $pdf_page_width = $pdf->GetPageWidth() - $margins['left'] - $margins['right'];
                    $total_width = 0;
                    foreach ($col_widths as $key => $value) {
                        $total_width += $value;
                    }
                    $new_widths = array();
                    foreach ($col_widths as $key => $value) {
                        $new_widths[$key] = $pdf_page_width * ($value / $total_width);
                        $new_widths[] = $pdf_page_width * ($value / $total_width);
                    }
                    $pdf->SetCellWidths($new_widths);
                    $pdf->SetCellFillStyle(2);
                    $pdf->SetCellPadding(1);
                    $pdf->SetCellMinimumHeight(null);
                    // if customized pdf render is defined, use that
                    if (!empty($this->events["on_render_pdf"])) {
                        $func = $this->events["on_render_pdf"][0];
                        $obj = $this->events["on_render_pdf"][1];
                        if ($obj) {
                            call_user_func(array($obj, $func), array("pdf" => &$pdf, "data" => &$arr));
                        } else {
                            call_user_func($func, array("pdf" => &$pdf, "data" => &$arr));
                        }
                    }
                    $h = $arr[0];
                    array_shift($arr);
                    $pdf->EasyTable($arr, $h);
                    if (strstr($this->options["export"]["filename"], ".pdf") === false) {
                        $this->options["export"]["filename"] .= ".pdf";
                    }
                    //Close and output PDF document
                    $pdf->Output($this->options["export"]["filename"], 'I');
                    die;
                } else {
                    if ($this->options["export"]["format"] == "csv") {
                        if (strstr($this->options["export"]["filename"], ".csv") === false) {
                            $this->options["export"]["filename"] .= ".csv";
                        }
                        header('Content-Type: text/csv');
                        header('Content-Disposition: attachment;filename=' . $this->options["export"]["filename"]);
                        $fp = fopen('php://output', 'w');
                        foreach ($arr as $key => $value) {
                            fputcsv($fp, $value);
                        }
                        die;
                    } else {
                        include_once "php-export-data.class.php";
                        $excel = new ExportDataExcel('browser');
                        if (strstr($this->options["export"]["filename"], ".xls") === false && strstr($this->options["export"]["filename"], ".xlsx") === false) {
                            $this->options["export"]["filename"] .= ".xls";
                        }
                        $excel->filename = $this->options["export"]["filename"];
                        $excel->initialize();
                        foreach ($arr as $row) {
                            $excel->addRow($row);
                        }
                        $excel->finalize();
                        die;
                    }
                }
            }
            // if defined in on_select event
            if (!empty($this->internal["sql_count"])) {
                $sql_count = $this->internal["sql_count"];
            } else {
                if (!empty($this->select_count)) {
                    $sql_count = $this->select_count . $wh;
                } else {
                    if (($p = stripos($this->select_command, "GROUP BY")) !== false) {
                        $sql_count = $this->select_command;
                        $p = stripos($sql_count, "GROUP BY");
                        $start_q = substr($sql_count, 0, $p);
                        $end_q = substr($sql_count, $p);
                        $sql_count = "SELECT count(*) as c FROM ({$start_q} {$wh} {$end_q}) pg_tmp";
                    } else {
                        $sql_count = $this->select_command . $wh;
                        $sql_count = "SELECT count(*) as c FROM (" . $sql_count . ") pg_tmp";
                    }
                }
            }
            # print_r($sql_count);
            $result = $this->execute_query($sql_count);
            if ($this->con) {
                $row = $result->FetchRow();
            } else {
                $row = mysql_fetch_array($result, MYSQL_ASSOC);
            }
            $count = $row['c'];
            // fix for oracle, alias in capitals
            if (empty($count)) {
                $count = $row['C'];
            }
            if ($count > 0) {
                $total_pages = ceil($count / $limit);
            } else {
                $total_pages = 0;
            }
            if ($page > $total_pages) {
                $page = $total_pages;
            }
            $start = $limit * $page - $limit;
            // do not put $limit*($page - 1)
            if ($start < 0) {
                $start = 0;
            }
            $responce = new stdClass();
            $responce->page = $page;
            $responce->total = $total_pages;
            $responce->records = $count;
            if (!empty($this->internal["sql"])) {
                $SQL = $this->internal["sql"] . " LIMIT {$limit} OFFSET {$start}";
            } else {
                if (($p = stripos($this->select_command, "GROUP BY")) !== false) {
                    $start_q = substr($this->select_command, 0, $p);
                    $end_q = substr($this->select_command, $p);
                    $SQL = "{$start_q} {$wh} {$end_q} ORDER BY {$sidx} {$sord} LIMIT {$limit} OFFSET {$start}";
                } else {
                    $SQL = $this->select_command . $wh . " ORDER BY {$sidx} {$sord} LIMIT {$limit} OFFSET {$start}";
                }
            }
            $SQL = $this->prepare_sql($SQL, $this->db_driver);
            $result = $this->execute_query($SQL);
            if ($this->con) {
                $rows = $result->GetRows();
                // simulate artificial paging for mssql
                if (count($rows) > $limit) {
                    $rows = array_slice($rows, count($rows) - $limit);
                }
            } else {
                $rows = array();
                while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                    $rows[] = $row;
                }
            }
            ### P ###
            // custom on_data_display event execution
            if (!empty($this->events["on_data_display"])) {
                $func = $this->events["on_data_display"][0];
                $obj = $this->events["on_data_display"][1];
                if ($obj) {
                    call_user_func(array($obj, $func), array("params" => &$rows));
                } else {
                    call_user_func($func, array("params" => &$rows));
                }
            }
            // preserve userdata for response
            if (!empty($rows["userdata"])) {
                $userdata = $rows["userdata"];
                unset($rows["userdata"]);
            }
            foreach ($rows as $row) {
                $orig_row = $row;
                // apply php level formatter for image url 30.12.10
                foreach ($this->options["colModel"] as $c) {
                    $col_name = $c["name"];
                    ### P ###
                    if (isset($c["default"]) && !isset($row[$col_name])) {
                        $row[$col_name] = $c["default"];
                    }
                    // link data in grid to any given url
                    if (!empty($c["default"])) {
                        // replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
                        $row[$col_name] = $this->replace_row_data($orig_row, $c["default"]);
                    }
                    // check conditional data
                    if (!empty($c["condition"][0])) {
                        $r = true;
                        // replace {} placeholders from connditional data
                        $c["condition"][1] = $this->replace_row_data($orig_row, $c["condition"][1]);
                        $c["condition"][2] = $this->replace_row_data($orig_row, $c["condition"][2]);
                        eval("\$r = " . $c["condition"][0] . ";");
                        $row[$col_name] = $r ? $c["condition"][1] : $c["condition"][2];
                    }
                    // check data filter (alternate of grid on_data_display, but for current column)
                    if (!empty($c["on_data_display"])) {
                        $func = $c["on_data_display"][0];
                        $obj = $c["on_data_display"][1];
                        if ($obj) {
                            $row[$col_name] = call_user_func(array($obj, $func), $row);
                        } else {
                            $row[$col_name] = call_user_func($func, $row);
                        }
                    }
                    ### P-END ###
                    // link data in grid to any given url
                    if (!empty($c["link"])) {
                        // replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
                        // replace_row_data not used due to urlencode work
                        foreach ($this->options["colModel"] as $link_c) {
                            // if there is url in data, don't urlencode
                            if (strstr($orig_row[$link_c["name"]], "http://")) {
                                $link_row_data = $orig_row[$link_c["name"]];
                            } else {
                                $link_row_data = urlencode($orig_row[$link_c["name"]]);
                            }
                            $c["link"] = str_replace("{" . $link_c["name"] . "}", $link_row_data, $c["link"]);
                        }
                        $attr = "";
                        if (!empty($c["linkoptions"])) {
                            $attr = $c["linkoptions"];
                        }
                        // fix for mssql utf8 fix
                        if (strpos($this->db_driver, "mssql") !== false) {
                            $row[$col_name] = htmlentities(utf8_encode($row[$col_name]), ENT_QUOTES, "UTF-8");
                        } else {
                            $row[$col_name] = htmlentities($row[$col_name], ENT_QUOTES, "UTF-8");
                        }
                        // if link is made with custom date format
                        if (isset($c["formatoptions"]["newformat"])) {
                            $js_dt_fmt = $c["formatoptions"]["newformat"];
                            $js_dt_fmt = str_replace("yy", "Y", $js_dt_fmt);
                            $js_dt_fmt = str_replace("mm", "m", $js_dt_fmt);
                            $js_dt_fmt = str_replace("dd", "d", $js_dt_fmt);
                            $row[$col_name] = date($c["formatoptions"]["newformat"], strtotime($row[$col_name]));
                        }
                        $row[$col_name] = "<a {$attr} href='{$c["link"]}'>{$row[$col_name]}</a>";
                    }
                    // render row data as "src" value of <img> tag
                    if (isset($c["formatter"]) && $c["formatter"] == "image") {
                        $attr = array();
                        foreach ($c["formatoptions"] as $k => $v) {
                            $attr[] = "{$k}='{$v}'";
                        }
                        $attr = implode(" ", $attr);
                        $row[$col_name] = "<img {$attr} src='" . $row[$col_name] . "'>";
                    }
                    // show masked data in password
                    if (isset($c["formatter"]) && $c["formatter"] == "password") {
                        $row[$col_name] = "*****";
                    }
                }
                foreach ($row as $k => $r) {
                    $row[$k] = stripslashes($row[$k]);
                }
                $responce->rows[] = $row;
            }
            // set custom userdata in footer (controlled with on_data_display event)
            if (!empty($userdata)) {
                $responce->userdata = $userdata;
            }
            // fix for mssql utf8 fix
            if (strpos($this->db_driver, "mssql") !== false) {
                $responce = array_utf8_encode_recursive($responce);
            }
            echo json_encode($responce);
            die;
        }
        ### P ###
        // if loading from array
        if (is_array($this->table)) {
            $this->options["data"] = json_encode($this->table);
            $this->options["datatype"] = "local";
            $this->actions["rowactions"] = false;
            $this->actions["add"] = false;
            $this->actions["edit"] = false;
            $this->actions["delete"] = false;
        }
        // few overides - pagination fixes
        $this->options["pager"] = '#' . $grid_id . "_pager";
        $this->options["jsonReader"] = array("repeatitems" => false, "id" => "0");
        // allow/disallow edit,del operations
        if ($this->actions["edit"] === false && $this->actions["delete"] === false || $this->options["cellEdit"] === true) {
            $this->actions["rowactions"] = false;
        }
        if ($this->actions["rowactions"] !== false) {
            // CRUD operation column
            $f = false;
            $defined = false;
            foreach ($this->options["colModel"] as &$c) {
                if ($c["name"] == "act") {
                    $defined =& $c;
                }
                if (!empty($c["width"])) {
                    $f = true;
                }
            }
            // icon col fix, text links as old behavior (fixed:true, mean exact px)
            if ($this->internal["actionicon"] === true) {
                $w = $this->actions["clone"] === true ? "80" : "55";
            } else {
                $w = $this->actions["clone"] === true ? "120" : "100";
            }
            // width adjustment for row actions column
            $action_column = array("name" => "act", "fixed" => true, "align" => "center", "index" => "act", "width" => "{$w}", "sortable" => false, "search" => false, "viewable" => false);
            if (!$defined) {
                $this->options["colNames"][] = "Actions";
                $this->options["colModel"][] = $action_column;
            } else {
                $defined = array_merge($action_column, $defined);
            }
        }
        // simulate field access right options
        $str_add_form = '';
        $str_edit_form = '';
        $str_delete_form = '';
        $str_edit_access = '';
        $str_inline_access = '';
        foreach ($this->options["colModel"] as &$c) {
            // auto reload & edit for link pattern fix
            if (!empty($c["link"])) {
                $this->options["reloadedit"] = true;
                $c["formatter"] = "function(cellvalue, options, rowObject){ \n\n\t\t\t\t\t\t\t\t\t\tarr = jQuery(document).data('link_{$c["name"]}');\n\t\t\t\t\t\t\t\t\t\tif (!arr) arr = {};\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\tif (jQuery(cellvalue).text() != '')\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tarr[jQuery(cellvalue).text()] = cellvalue;\n\t\t\t\t\t\t\t\t\t\t\tjQuery(document).data('link_{$c["name"]}',arr);\n\t\t\t\t\t\t\t\t\t\t\treturn arr[jQuery(cellvalue).text()];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t// fix for link text 'undefined'\n\t\t\t\t\t\t\t\t\t\t\tif (typeof(arr[cellvalue]) == 'undefined')\n\t\t\t\t\t\t\t\t\t\t\t\treturn '';\n\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\treturn arr[cellvalue];\n\t\t\t\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\t\t\t}";
                $c["unformat"] = "function(cellvalue, options, cell){return jQuery(cell).text();}";
            }
            // make readonly field while editing
            if (isset($c["editrules"]["readonly"])) {
                if ($c["editrules"]["readonly"] === true) {
                    $tag = "input";
                    if (!empty($c["edittype"])) {
                        $tag = $c["edittype"];
                    }
                    if (!empty($c["editrules"]["readonly-when"])) {
                        $cond = $c["editrules"]["readonly-when"];
                        if (!is_numeric($cond[1])) {
                            $cond[1] = '"' . $cond[1] . '"';
                        }
                        $str_edit_access .= 'if (jQuery("#tr_' . $c["index"] . ' .DataTD ' . $tag . '",formid).val() ' . $cond[0] . ' ' . $cond[1] . ')';
                        $str_inline_access .= 'if (jQuery("' . $tag . '[name=' . $c["index"] . ']:last").val() ' . $cond[0] . ' ' . $cond[1] . ')';
                    }
                    // make textbox hidden, for postback
                    $str_edit_access .= '{';
                    if ($tag == "select") {
                        $str_edit_access .= 'jQuery("#tr_' . $c["index"] . ' .DataTD",formid).append("&nbsp;" + jQuery("#tr_' . $c["index"] . ' .DataTD ' . $tag . ' option:selected",formid).text());';
                    } else {
                        $str_edit_access .= 'jQuery("#tr_' . $c["index"] . ' .DataTD",formid).append("&nbsp;" + jQuery("#tr_' . $c["index"] . ' .DataTD ' . $tag . '",formid).val());';
                    }
                    $str_edit_access .= 'jQuery("#tr_' . $c["index"] . ' .DataTD ' . $tag . '",formid).hide();';
                    // remove required (*) from readonly
                    $str_edit_access .= 'jQuery("#tr_' . $c["index"] . ' .DataTD font",formid).hide();';
                    $str_edit_access .= '}';
                    $str_inline_access .= '{';
                    $str_inline_access .= 'jQuery("' . $tag . '[name=' . $c["index"] . ']:last").hide();';
                    $str_inline_access .= 'jQuery("' . $tag . '[name=' . $c["index"] . ']:last").parent().not(":has(span)").append("<span></span>");';
                    $str_inline_access .= 'jQuery("' . $tag . '[name=' . $c["index"] . ']:last").parent().children("span").html(jQuery("' . $tag . '[name=' . $c["index"] . ']:last").val());';
                    $str_inline_access .= '}';
                }
            }
            if (!empty($c["show"])) {
                if ($c["show"]["list"] === false) {
                    $c["hidden"] = true;
                } else {
                    $c["hidden"] = false;
                }
                if ($c["formoptions"]["rowpos"]) {
                    $str_pos = '';
                    $str_pos .= 'jQuery("#TblGrid_' . $grid_id . ' tr:eq(' . ($c["formoptions"]["rowpos"] + 1) . ') td:nth-child(' . $c["formoptions"]["colpos"] * 2 . ')").html("");';
                    $str_pos .= 'jQuery("#TblGrid_' . $grid_id . ' tr:eq(' . ($c["formoptions"]["rowpos"] + 1) . ') td:nth-child(' . ($c["formoptions"]["colpos"] * 2 - 1) . ')").html("");';
                }
                if ($c["show"]["edit"] === false) {
                    $str_edit_access .= 'jQuery("#tr_' . $c["index"] . '",formid).hide();';
                    if (!empty($str_pos)) {
                        $str_edit_access .= $str_pos;
                    }
                } else {
                    $str_edit_access .= 'jQuery("#tr_' . $c["index"] . '",formid).show();';
                }
                if ($c["show"]["add"] === false) {
                    $str_add_access .= 'jQuery("#tr_' . $c["index"] . '",formid).hide();';
                    if (!empty($str_pos)) {
                        $str_add_access .= $str_pos;
                    }
                } else {
                    $str_add_access .= 'jQuery("#tr_' . $c["index"] . '",formid).show();';
                }
                if ($c["show"]["view"] === false) {
                    $str_view_access .= 'jQuery("#trv_' . $c["index"] . '").hide();';
                    if ($c["formoptions"]["rowpos"]) {
                        $str_pos = '';
                        $str_pos .= 'jQuery("#ViewTbl_' . $grid_id . ' tr:eq(' . ($c["formoptions"]["rowpos"] - 1) . ') td:nth-child(' . $c["formoptions"]["colpos"] * 2 . ')").html("");';
                        $str_pos .= 'jQuery("#ViewTbl_' . $grid_id . ' tr:eq(' . ($c["formoptions"]["rowpos"] - 1) . ') td:nth-child(' . ($c["formoptions"]["colpos"] * 2 - 1) . ')").html("");';
                        $str_view_access .= $str_pos;
                    }
                } else {
                    $str_view_access .= 'jQuery("#trv_' . $c["index"] . '").show();';
                }
                unset($c["show"]);
            }
        }
        // set before show form events
        if (!empty($this->internal["add_options"]["beforeShowForm"])) {
            $str_add_form = $str_add_access . $this->internal["add_options"]["beforeShowForm"];
        } else {
            $str_add_form = $str_add_access;
        }
        if (!empty($this->internal["edit_options"]["beforeShowForm"])) {
            $str_edit_form = $str_edit_access . $this->internal["edit_options"]["beforeShowForm"];
        } else {
            $str_edit_form = $str_edit_access;
        }
        if (!empty($this->internal["delete_options"]["beforeShowForm"])) {
            $str_delete_form = $str_delete_access . $this->internal["delete_options"]["beforeShowForm"];
        } else {
            $str_delete_form = $str_delete_access;
        }
        if (!empty($this->internal["view_options"]["beforeShowForm"])) {
            $str_view_form = $str_view_access . $this->internal["view_options"]["beforeShowForm"];
        } else {
            $str_view_form = $str_view_access;
        }
        ### P ###
        $this->options["add_options"]["beforeShowForm"] = 'function(formid) { ' . $str_add_form . ' }';
        $this->options["edit_options"]["beforeShowForm"] = 'function(formid) { ' . $str_edit_form . ' }';
        $this->options["delete_options"]["beforeShowForm"] = 'function(formid) { ' . $str_delete_form . ' }';
        // append view options beforeShowForm implementation
        $fx = "";
        if (!empty($this->options["view_options"]["beforeShowForm"])) {
            $fx = "var o=" . $this->options["view_options"]["beforeShowForm"] . "; o(formid);";
        }
        $this->options["view_options"]["beforeShowForm"] = 'function(formid) { ' . $str_view_form . $fx . ' }';
        // focus / select newly inserted row
        $this->options["add_options"]["afterComplete"] = "function (response, postdata) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tr = JSON.parse(response.responseText); \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery( document ).ajaxComplete(function() {\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').setSelection(r.id);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery( document ).unbind('ajaxComplete');\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}";
        // event for dialog < > navigation
        $this->options["view_options"]["afterclickPgButtons"] = 'function(formid) { ' . $str_view_access . ' }';
        ### P-END ###
        $reload_after_edit = "";
        // after save callback
        if (!empty($this->options["onAfterSave"])) {
            $reload_after_edit .= "var fx_save = {$this->options["onAfterSave"]}; fx_save();";
        }
        if ($this->options["reloadedit"] === true) {
            $reload_after_edit .= "jQuery('#{$grid_id}').jqGrid().trigger('reloadGrid',[{jqgrid_page:1}]);";
        }
        ### P ###
        if (empty($this->options["add_options"]["success_msg"])) {
            $this->options["add_options"]["success_msg"] = "Enr&eacute;gistrement ajout&eacute;";
        }
        if (empty($this->options["edit_options"]["success_msg"])) {
            $this->options["edit_options"]["success_msg"] = "Enr&eacute;gistrement mis &agrave; jour";
        }
        if (empty($this->options["edit_options"]["success_msg_bulk"])) {
            $this->options["edit_options"]["success_msg_bulk"] = "Enr&eacute;gistrements ajout&eacute;s";
        }
        if (empty($this->options["delete_options"]["success_msg"])) {
            $this->options["delete_options"]["success_msg"] = "Enr&eacute;gistrement effac&eacute";
        }
        if (empty($this->options["add_options"]["afterSubmit"])) {
            $this->options["add_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					fx_success_msg("' . $this->options["add_options"]["success_msg"] . '",1);
																			      	return [true,""];
																				} 
																			}';
        }
        if (empty($this->options["edit_options"]["afterSubmit"])) {
            $this->options["edit_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					' . $reload_after_edit . '
																					fx_success_msg("' . $this->options["edit_options"]["success_msg"] . '",1);
																			      	return [true,""];
																				} 
																			}';
        }
        if (empty($this->options["delete_options"]["afterSubmit"])) {
            $this->options["delete_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					fx_success_msg("' . $this->options["delete_options"]["success_msg"] . '",1);
																			      	return [true,""];
																				} 
																			}';
        }
        ### P-END ###
        // search options for templates
        $this->options["search_options"]["closeAfterSearch"] = true;
        $this->options["search_options"]["multipleSearch"] = $this->actions["search"] == "advance" ? true : false;
        $this->options["search_options"]["sopt"] = array('eq', 'ne', 'lt', 'le', 'gt', 'ge', 'bw', 'bn', 'in', 'ni', 'ew', 'en', 'cn', 'nc', 'nu', 'nn');
        $out = json_encode_jsfunc($this->options);
        $out = substr($out, 0, strlen($out) - 1);
        // create Edit/Delete - Save/Cancel column in grid
        if ($this->actions["rowactions"] !== false) {
            $act_links = array();
            ### P-START ###
            if ($this->internal["actionicon"] === true) {
                if ($this->actions["edit"] !== false) {
                    $act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-pencil\" title=\"Editer la ligne\" href=\"javascript:void(0);\" onclick=\"jQuery(this).dblclick();\"></a>";
                }
                ### P ###
                if ($this->actions["clone"] === true) {
                    $act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-copy\" title=\"Cloner la ligne\" href=\"javascript:void(0);\" onclick=\"fx_clone_row(\\'{$grid_id}\\',\\''+cl+'\\'); \"></a>";
                }
                ### P-END ###
                if ($this->actions["delete"] !== false) {
                    $act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-trash\" title=\"Effacer la ligne\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}\\').delGridRow(\\''+cl+'\\',{errorTextFormat:function(r){ return r.responseText;}}); jQuery(\\'#delmod{$grid_id}\\').abscenter(); \"></a>";
                }
                $act_links = implode("", $act_links);
                $out .= ",'gridComplete': function()\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar ids = jQuery('#{$grid_id}').jqGrid('getDataIDs');\n\t\t\t\t\t\t\t\tfor(var i=0;i < ids.length;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar cl = ids[i];\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tbe = '{$act_links}';\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t// il_save, ilcancel, iledit are clicked for inlineNav button reset\n\t\t\t\t\t\t\t\t\tse = '<a class=\"ui-custom-icon ui-icon ui-icon-disk\" title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilsave\\').click(); if (jQuery(\\'#{$grid_id}\\').saveRow(\\''+cl+'\\') || jQuery(\\'.editable\\').length==0) { jQuery(this).parent().hide(); jQuery(this).parent().prev().show(); " . addslashes($reload_after_edit) . " }\"></a>';\n\t\t\t\t\t\t\t\t\tce = '<a class=\"ui-custom-icon ui-icon ui-icon-cancel\" title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilcancel\\').click(); jQuery(\\'#{$grid_id}\\').restoreRow(\\''+cl+'\\'); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\"></a>';\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t// for inline add option\n\t\t\t\t\t\t\t\t\tif (ids[i].indexOf('jqg') != -1)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tse = '<a class=\"ui-custom-icon ui-icon ui-icon-disk\" title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilsave\\').click(); \">Save</a>';\n\t\t\t\t\t\t\t\t\t\tce = '<a class=\"ui-custom-icon ui-icon ui-icon-cancel\" title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilcancel\\').click(); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>';\n\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').jqGrid('setRowData',ids[i],{act:'<span style=display:none id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').jqGrid('setRowData',ids[i],{act:'<span id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span style=display:none id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}";
            } else {
                if ($this->actions["edit"] !== false) {
                    $act_links[] = "<a title=\"Editer la ligne\" href=\"javascript:void(0);\" onclick=\"jQuery(this).dblclick();\">Edit</a>";
                }
                ### P ###
                if ($this->actions["clone"] === true) {
                    $act_links[] = "<a title=\"Cloner la ligne\" href=\"javascript:void(0);\" onclick=\"fx_clone_row(\\'{$grid_id}\\',\\''+cl+'\\'); \">Clone</a>";
                }
                ### P-END ###
                if ($this->actions["delete"] !== false) {
                    $act_links[] = "<a title=\"Effacer la ligne\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}\\').delGridRow(\\''+cl+'\\',{errorTextFormat:function(r){ return r.responseText;}}); jQuery(\\'#delmod{$grid_id}\\').abscenter(); \">Delete</a>";
                }
                $act_links = implode(" | ", $act_links);
                $out .= ",'gridComplete': function()\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\tvar ids = jQuery('#{$grid_id}').jqGrid('getDataIDs');\n\t\t\t\t\t\t\t\tfor(var i=0;i < ids.length;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar cl = ids[i];\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tbe = '{$act_links}'; \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// il_save, ilcancel, iledit are clicked for inlineNav button reset\n\t\t\t\t\t\t\tse = ' <a title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilsave\\').click(); if (jQuery(\\'#{$grid_id}\\').saveRow(\\''+cl+'\\') || jQuery(\\'.editable\\').length==0) { jQuery(this).parent().hide(); jQuery(this).parent().prev().show(); " . addslashes($reload_after_edit) . " }\">Save</a>'; \n\t\t\t\t\t\t\tce = ' | <a title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilcancel\\').click(); jQuery(\\'#{$grid_id}\\').restoreRow(\\''+cl+'\\'); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>'; \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// for inline add option\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (ids[i].indexOf('jqg') != -1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tse = ' <a title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilsave\\').click(); \">Save</a>'; \n\t\t\t\t\t\t\t\tce = ' | <a title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\\'#{$grid_id}_ilcancel\\').click(); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>'; \n\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').jqGrid('setRowData',ids[i],{act:'<span style=display:none id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').jqGrid('setRowData',ids[i],{act:'<span id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span style=display:none id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});\n\t\t\t\t\t\t}\t\n\t\t\t\t\t}";
            }
        }
        $out .= ",'ondblClickRow': function (id, iRow, iCol, e) {";
        // double click editing option
        if ($this->actions["rowactions"] !== false && $this->actions["edit"] !== false && $this->options["cellEdit"] !== true) {
            $out .= "\n\t\t\t\t\t\t\tif (!e) e = window.event;\n\t\t\t\t\t\t\tvar element = e.target || e.srcElement;\n\n\t\t\t\t\t\t\tif(id && id!==lastSel && lastSel != 'jqg1')\n\t\t\t\t\t\t\t{ \n\t\t\t\t\t\t\t\t// reset data msg, for new row edit without save last row\n\t\t\t\t\t\t\t\tif (typeof(lastSel) != 'undefined' && jQuery('.editable').length >0 && !confirm('Changes are not saved, Reset changes?'))\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').restoreRow(lastSel); \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t// to enable autosave on dblclick new row + dont edit on validation error\n\t\t\t\t\t\t\t\t// if (typeof(lastSel) != 'undefined')\n\t\t\t\t\t\t\t\t\t// if (!jQuery('#{$grid_id}').saveRow(lastSel))\n\t\t\t\t\t\t\t\t\t\t// return;\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t// disabled previously edit icons\n\t\t\t\t\t\t\t\tjQuery('#edit_row_{$grid_id}_'+lastSel).show();\n\t\t\t\t\t\t\t\tjQuery('#save_row_{$grid_id}_'+lastSel).hide();\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tlastSel=id; \t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tjQuery('#{$grid_id}').editRow(id, true, function()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// focus on dblclicked element\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetTimeout(function(){ jQuery('input, select, textarea', element).focus(); },100);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}, \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tfunction()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#edit_row_{$grid_id}_'+id).show();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#save_row_{$grid_id}_'+id).hide();\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},null,null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tfunction()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// force reload grid after inline save\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{$reload_after_edit}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tfunction()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#edit_row_{$grid_id}_'+id).show();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#save_row_{$grid_id}_'+id).hide();\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t); \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// for inlineNav edit button fix\n\t\t\t\t\t\t\tif (jQuery('#{$grid_id}_iledit').length)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tjQuery('#{$grid_id}').setSelection(id, true);\n\t\t\t\t\t\t\t\tjQuery('#{$grid_id}_iledit').click();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tjQuery('#edit_row_{$grid_id}_'+id).hide();\n\t\t\t\t\t\t\tjQuery('#save_row_{$grid_id}_'+id).show();\n\n\t\t\t\t\t\t\t{$str_inline_access}";
        }
        // chain 'onSelectRow' function with base working
        if (!empty($this->options["ondblClickRow"])) {
            $out .= "var fx = " . $this->options["ondblClickRow"] . "; fx(id, iRow, iCol);";
            unset($this->options["ondblClickRow"]);
        }
        $out .= "}";
        ### P ###
        // if subgrid is there, enable subgrid feature
        if (isset($this->options["subgridurl"]) && $this->options["subgridurl"] != '') {
            // we pass two parameters
            // subgrid_id is a id of the div tag created within a table
            // the row_id is the id of the row
            // If we want to pass additional parameters to the url we can use
            // the method getRowData(row_id) - which returns associative array in type name-value
            // here we can easy construct the following
            $pass_params = "false";
            if (!empty($this->options["subgridparams"])) {
                $pass_params = "true";
            }
            // chain 'subGridRowExpanded' function with base working
            if (!empty($this->options["subGridRowExpanded"])) {
                $str_fx = "var fx = " . $this->options["subGridRowExpanded"] . "; fx();";
                unset($this->options["subGridRowExpanded"]);
            }
            $out .= ",'subGridRowExpanded': function(subgridid, id) \n\t\t\t\t\t\t\t\t\t\t\t{ \n\t\t\t\t\t\t\t\t\t\t\t\tvar data = {subgrid:subgridid, rowid:id};\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\tif('{$pass_params}' == 'true') {\n\t\t\t\t\t\t\t\t\t\t\t\t\tvar anm= '" . $this->options["subgridparams"] . "';\n\t\t\t\t\t\t\t\t\t\t\t\t\tanm = anm.split(',');\n\t\t\t\t\t\t\t\t\t\t\t\t\tvar rd = jQuery('#" . $grid_id . "').jqGrid('getRowData', id);\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(rd) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tfor(var i=0; i<anm.length; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif(rd[anm[i]]) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata[anm[i]] = rd[anm[i]];\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#'+jQuery.jgrid.jqID(subgridid)).load('" . $this->options["subgridurl"] . "',data,function(){ " . $str_fx . " });\n\t\t\t\t\t\t\t\t\t\t\t}";
        }
        // on error
        $out .= ",'loadError': function(xhr,status, err) { \n\t\t\t\t\ttry \n\t\t\t\t\t{\n\t\t\t\t\t\tjQuery.jgrid.info_dialog(jQuery.jgrid.errors.errcap,'<div class=\"ui-state-error\">'+ xhr.responseText +'</div>', \n\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery.jgrid.edit.bClose,{buttonalign:'right'});\n\n\t\t\t\t\t} \n\t\t\t\t\tcatch(e) { alert(xhr.responseText);}\n\t\t\t\t}\n\t\t\t\t";
        // on row selection operation
        $out .= ",'onSelectRow': function(ids) { ";
        ### P ###
        if (isset($this->options["detail_grid_id"]) && $this->options["detail_grid_id"] != '') {
            $detail_grid_id = $this->options["detail_grid_id"];
            $d_grids = explode(",", $detail_grid_id);
            foreach ($d_grids as $detail_grid_id) {
                $detail_url = $this->options["url"];
                // remove master grid's grid_id param
                $detail_url = str_replace('grid_id=', '', $detail_url);
                // append grid_id param for detail grid
                $s = strstr($this->options["url"], "?") ? "&" : "?";
                $detail_url .= $s . "grid_id=" . $detail_grid_id;
                $out .= "\n\t\t\n\t\t\t\t\t\tvar data = '';\n\t\t\t\t\t\tif ('{$this->options["subgridparams"]}'.length > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar anm = '" . $this->options["subgridparams"] . "';\n\t\t\t\t\t\t\tanm = anm.split(',');\n\t\t\t\t\t\t\tvar rd = jQuery('#" . $grid_id . "').jqGrid('getRowData', ids);\n\t\t\t\t\t\t\tif(rd) {\n\t\t\t\t\t\t\t\tfor(var i=0; i<anm.length; i++) {\n\t\t\t\t\t\t\t\t\tif(rd[anm[i]]) {\n\t\t\t\t\t\t\t\t\t\tdata += '&' + anm[i] + '=' + rd[anm[i]];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\tif(ids == null) \n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tids=0;\n\t\t\t\t\t\t\tif(jQuery('#" . $detail_grid_id . "').jqGrid('getGridParam','records') >0 )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').jqGrid('setGridParam',{url:'" . $detail_url . "&rowid='+ids+data,editurl:'" . $detail_url . "&rowid='+ids,jqgrid_page:1});\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').trigger('reloadGrid',[{jqgrid_page:1}]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} \n\t\t\t\t\t\telse \n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').jqGrid('setGridParam',{url:'" . $detail_url . "&rowid='+ids+data,editurl:'" . $detail_url . "&rowid='+ids,jqgrid_page:1});\n\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').trigger('reloadGrid',[{jqgrid_page:1}]);\t\t\t\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// enable detail grid buttons if master row selected\n\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "_pager_left .ui-pg-button').not(':has(span.ui-separator)').removeClass('ui-state-disabled');\n\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "_ilsave, #" . $detail_grid_id . "_ilcancel').addClass('ui-state-disabled');\n\t\t\t\t\t\t\n\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').data('jqgrid_detail_grid_params','&rowid='+ids+data);\n\t\t\t\t\t\t";
            }
        }
        ### P ###
        // obseleted now
        if (!empty($this->events["js_on_select_row"])) {
            $out .= "if (typeof({$this->events["js_on_select_row"]}) != 'undefined') {$this->events["js_on_select_row"]}(ids);";
        }
        // chain 'onSelectRow' function with base working
        if (!empty($this->options["onSelectRow"])) {
            $out .= "var fx = " . $this->options["onSelectRow"] . "; fx(ids);";
            unset($this->options["onSelectRow"]);
        }
        // closing of select row events
        $out .= "}";
        // fix for formatting, to apply on only new records of virtual scroll
        if ($this->options["scroll"] == true) {
            $out .= ",'beforeRequest': function() {";
            $out .= "jQuery('#{$grid_id}').data('jqgrid_rows',jQuery('#{$grid_id} tr.jqgrow').length);";
            $out .= "}";
        }
        // on load complete operation
        $out .= ",'loadComplete': function(ids) {";
        // In case 'All' param is used in pager
        $out .= "jQuery('#{$grid_id}_pager option[value=\"All\"]').val(99999);";
        // show no record message at center
        $out .= "if (jQuery('#{$grid_id}').getGridParam('records') == 0) \n\t\t\t\t\t\t{ \n\t\t\t\t\t\t\tif (jQuery('#div_no_record_{$grid_id}').length==0) \n\t\t\t\t\t\t\t\tjQuery('#gbox_{$grid_id} .ui-jqgrid-bdiv').not('.frozen-bdiv').append('<div id=\"div_no_record_{$grid_id}\" align=\"center\" style=\"padding:30px 0;\">'+jQuery.jgrid.defaults.emptyrecords+'</div>'); \n\t\t\t\t\t\t\telse \n\t\t\t\t\t\t\t\tjQuery('#div_no_record_{$grid_id}').show();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tjQuery('#div_no_record_{$grid_id}').hide();\n\t\t\t\t\t\t}";
        if (isset($this->options["detail_grid_id"]) && $this->options["detail_grid_id"] != '') {
            $detail_grid_id = $this->options["detail_grid_id"];
            $d_grids = explode(",", $detail_grid_id);
            foreach ($d_grids as $detail_grid_id) {
                $detail_url = $this->options["url"];
                $s = strstr($this->options["url"], "?") ? "&" : "?";
                $detail_url .= $s . "grid_id=" . $detail_grid_id;
                $out .= "\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').jqGrid('setGridParam',{url:'" . $detail_url . "&rowid=',editurl:'" . $detail_url . "&rowid=',jqgrid_page:1});\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').trigger('reloadGrid',[{jqgrid_page:1}]);\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "').data('jqgrid_detail_grid_params','');\n\t\t\t\t\t\t\t\tjQuery('#" . $detail_grid_id . "_pager_left .ui-pg-button').addClass('ui-state-disabled');\n\t\t\t\t\t\t\t\t";
            }
        }
        // formatting fix for virtual scrolling
        $fix_format = "";
        if ($this->options["scroll"] == true) {
            $fix_format .= " var last_rows = 0;\n\t\t\t\t\t\t\t\t\tif (typeof(jQuery('#{$grid_id}').data('jqgrid_rows')) != 'undefined')\n\t\t\t\t\t\t\t\t\t\ti = i + jQuery('#{$grid_id}').data('jqgrid_rows');\n\t\t\t\t\t\t\t\t\t";
        }
        // celledit option and readonly mode
        if ($this->options["cellEdit"] === true) {
            foreach ($this->options["colModel"] as $t) {
                if ($t["editrules"]["readonly"] == true) {
                    $fix_format .= "jQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$t[name]}]').addClass('not-editable-cell');";
                }
            }
        }
        $out .= "if(ids && ids.rows) jQuery.each(ids.rows,function(i){\n\t\t\t\t\t\t\t{$fix_format}\n\t\t\t\t\t\t\t";
        ### P ###
        if (count($this->conditional_css)) {
            foreach ($this->conditional_css as $value) {
                // if wrong column specified, skip formatting
                $out .= "if (typeof(this.{$value[column]}) == 'undefined') return;";
                // using {column} placeholder in formatting value
                preg_match('/{(.*)}/', $value[value], $match);
                if (count($match)) {
                    // if html remove it using text(), if string convert toString(), if numeric use parseFloat
                    if ($value["op"] == "cn" || $value["op"] == "eq" || $value["op"] == "=") {
                        $value[value] = "'+ (jQuery(this.{$match['1']}).html() ? jQuery(this.{$match['1']}).text() : (jQuery.isNumeric(this.{$match['1']}) ? parseFloat(this.{$match['1']}) : this.{$match['1']}.toString()) )+ '";
                    } else {
                        $value[value] = "(jQuery(this.{$match['1']}).html() ? jQuery(this.{$match['1']}).text() : (jQuery.isNumeric(this.{$match['1']}) ? parseFloat(this.{$match['1']}) : this.{$match['1']}.toString()) )";
                    }
                }
                $out .= "this.{$value[column]} = this.{$value[column]}.replace(/(<([^>]+)>)/ig,'');";
                if ($value["op"] == "cn") {
                    $out .= "\n\t\t\t\t\t\t\t\t\t\tif (this.{$value[column]}.toLowerCase().indexOf('{$value[value]}'.toLowerCase()) != -1)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif ('" . $value["class"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').addClass('" . $value["class"] . "');\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["css"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t\telse if ('" . $value["cellclass"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t{ \n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit'); \n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('" . $value["cellclass"] . "');\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["cellcss"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit');\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}";
                } else {
                    if ($value["op"] == "eq" || $value["op"] == "=") {
                        $out .= "\n\t\t\t\t\t\t\t\t\t\tif (this.{$value[column]}.toLowerCase() == '{$value[value]}'.toLowerCase())\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif ('" . $value["class"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').addClass('" . $value["class"] . "');\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["css"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t\telse if ('" . $value["cellclass"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit');\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('" . $value["cellclass"] . "');\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["cellcss"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit');\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}";
                    } else {
                        if ($value["op"] == "<" || $value["op"] == "<=" || $value["op"] == ">" || $value["op"] == ">=" || $value["op"] == "!=") {
                            $out .= "\n\t\t\t\t\t\t\t\t\t\tif (parseFloat(this.{$value[column]}) {$value["op"]} {$value[value]})\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif ('" . $value["class"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').addClass('" . $value["class"] . "');\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["css"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') a').css('background-image','inherit').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse if ('" . $value["cellclass"] . "' != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit');\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('" . $value["cellclass"] . "');\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse if (\"" . $value["cellcss"] . "\" != '')\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+')').css('background-image','inherit');\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}";
                        } else {
                            if (empty($value["op"]) && !empty($value["column"]) && !empty($value["css"])) {
                                $out .= "\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif (jQuery.browser.msie)\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} td[aria-describedby={$grid_id}_{$value["column"]}]').css('background','inherit').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#{$grid_id} td[aria-describedby={$grid_id}_{$value["column"]}]').removeClass('.ui-widget-content').css({{$value[css]}});\n\t\t\t\t\t\t\t\t\t\t}";
                            }
                        }
                    }
                }
            }
        }
        ### P-END ###
        $out .= "});";
        ### P ###
        // obseleted now
        if (!empty($this->events["js_on_load_complete"])) {
            $out .= "if (typeof({$this->events["js_on_load_complete"]}) != 'undefined') {$this->events["js_on_load_complete"]}(ids);";
        }
        // chain 'loadComplete' function with base working
        if (!empty($this->options["loadComplete"])) {
            $out .= "var fx = " . $this->options["loadComplete"] . "; fx(ids);";
            unset($this->options["loadComplete"]);
        }
        // closing of load complete events
        $out .= "}";
        // closing of param list
        $out .= "}";
        // Navigational grid params
        if (!isset($this->navgrid["param"])) {
            $this->navgrid["param"]["edit"] = $this->actions["edit"] === false ? false : true;
            $this->navgrid["param"]["add"] = $this->actions["add"] === false ? false : true;
            $this->navgrid["param"]["del"] = $this->actions["delete"] === false ? false : true;
            $this->navgrid["param"]["view"] = $this->actions["view"] === true ? true : false;
            $this->navgrid["param"]["refresh"] = $this->actions["refresh"] === false ? false : true;
            ### P ### -- turn false
            $this->navgrid["param"]["search"] = $this->actions["search"] === false ? false : true;
            // fix for del and delete text
            if (!empty($this->navgrid["param"]["delete"])) {
                $this->navgrid["param"]["del"] = $this->navgrid["param"]["delete"];
            }
        }
        // Generate HTML/JS code
        ob_start();
        ?>
			<table id="<?php 
        echo $grid_id;
        ?>
"></table> 
			<div id="<?php 
        echo $grid_id . "_pager";
        ?>
"></div> 
			<script>
			var phpgrid = jQuery("#<?php 
        echo $grid_id;
        ?>
");
			var phpgrid_pager = jQuery("#<?php 
        echo $grid_id . "_pager";
        ?>
");
			var fx_ajax_file_upload;
			var fx_replace_upload;
			var fx_bulk_update;
			var fx_get_dropdown;

			jQuery(document).ready(function(){
				<?php 
        echo $this->render_js($grid_id, $out);
        ?>
			});	

			</script>	
		<?php 
        return ob_get_clean();
    }
Ejemplo n.º 3
0
	/**
	 * Generate JSON array for grid rendering
	 * @param $grid_id Unique ID for grid
	 */
	function render($grid_id)
	{
		// render grid for first time (non ajax), but specific grid on ajax calls
		$is_ajax = isset($_REQUEST["nd"]) || isset($_REQUEST["oper"]) || isset($_REQUEST["export"]);
		if ($is_ajax && $_REQUEST["grid_id"] != $grid_id)
			return;

		$append_by = (strpos($this->options["url"],"?") === false) ? "?" : "&";

		$this->options["url"] .= $append_by."grid_id=$grid_id";
		$this->options["editurl"] .= $append_by."grid_id=$grid_id";
		$this->options["cellurl"] .= $append_by."grid_id=$grid_id";
		
		if (isset($_REQUEST["subgrid"]))
		{
			$grid_id .= "_".$_REQUEST["subgrid"];
			$grid_id = "_".preg_replace("/[^a-zA-Z0-9]+/", "", $grid_id);
		}

		### P ###
		// custom on select event execution
		if (!empty($this->events["on_select"]))
		{
			$func = $this->events["on_select"][0];
			$obj = $this->events["on_select"][1];
			$continue = $this->events["on_select"][2];
				
			$event_sql = "";
			$event_sql_count = "";
				
			if ($obj)
				call_user_func(array($obj,$func),array("param"=> $_REQUEST, "grid"=>$this, "sql" => &$event_sql, "sql_count" => &$event_sql_count));
			else
				call_user_func($func,array("param"=> $_REQUEST, "grid"=>$this, "sql" => &$event_sql, "sql_count" => &$event_sql_count));
				
			$this->internal["sql_count"] = $event_sql_count;
			$this->internal["sql"] = $event_sql;
		}
				
		// generate column names, if not defined
		if (!$this->options["colNames"])
			$this->set_columns();
			
		### P ###
		// manage uploaded files (grid_id check for master-detail fix)
		if (count($_FILES) && $_REQUEST["grid_id"] == $grid_id)
		{
			$files = array_keys($_FILES);
			$fileElementName = $files[0];

			if(!empty($_FILES[$fileElementName]['error']))
			{
				switch($_FILES[$fileElementName]['error'])
				{
					case '1':
						$error = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
						break;
					case '2':
						$error = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
						break;
					case '3':
						$error = 'The uploaded file was only partially uploaded';
						break;
					case '4':
						$error = 'No file was uploaded.';
						break;

					case '6':
						$error = 'Missing a temporary folder';
						break;
					case '7':
						$error = 'Failed to write file to disk';
						break;
					case '8':
						$error = 'File upload stopped by extension';
						break;
					case '999':
					default:
						$error = 'No error code avaiable';
				}
			}
			elseif(empty($_FILES[$fileElementName]['tmp_name']) || $_FILES[$fileElementName]['tmp_name'] == 'none')
			{
				$error = 'No file was uploaded';
			}
			else 
			{
				foreach($this->options["colModel"] as $c)
				{
					if ($c["upload_dir"] != "" && $c["name"] == $fileElementName)
					{
						$tmp_name = $_FILES[$fileElementName]["tmp_name"];
						$name = $_FILES[$fileElementName]["name"];
						
						$uploads_dir = $c["upload_dir"];
						mkdir($uploads_dir,0755,true);

						if (file_exists("$uploads_dir/$name"))
						{
							$error = "<br>File already exist: $uploads_dir/$name";
							break;
						}	

						if (move_uploaded_file($tmp_name, "$uploads_dir/$name"))
						{
							$field = $_POST["field"];
							$msg = "$uploads_dir/$name";
						}
						else
							$error = "Unable to move to desired folder $uploads_dir/$name";

						break;
					}
				}
			}
			
			echo "{";
			echo	"error: '" . $error . "',";
			echo	"msg: '" . $msg . "'";
			echo "}//"; # fix for upload lib, it get response from doc body that include <canvas>
			die;
		}
		### P-END ###
		
		if (isset($_POST['oper']))
		{
			$op = $_POST['oper'];
			$data = $_POST;
			$id = $data['id'];
			$pk_field = $this->options["colModel"][0]["index"];

			// fix for mssql utf8 fix
			if (strpos($this->db_driver,"mssql") !== false)
				$data = array_utf8_decode_recursive($data);

			// formatters array for k->v
			$is_numeric = array();

			// reformat date w.r.t mysql
			foreach( $this->options["colModel"] as $c )
			{
				// don't fix vars that are not posted (celledit mode)
				if (!isset($data[$c["index"]]))
					continue;

				// fix for short weekday name 
				if (strstr($c["formatoptions"]["newformat"],"D"))
				{
					$data[$c["index"]] = str_ireplace(array("sun","mon","tue","wed","thu","fri","sat"), "", $data[$c["index"]]);
					$data[$c["index"]] = trim($data[$c["index"]]);
				}

				// fix for d/m/Y date format. strtotime expects m/d/Y
				if (strstr($c["formatoptions"]["newformat"],"d/m/Y"))
				{
					$tmp = explode("/",$data[$c["index"]]);
					$data[$c["index"]] = $tmp[1]."/".$tmp[0]."/".$tmp[2];
				}

				// put zeros for blank date field
				if (($c["formatter"] == "date" || $c["formatter"] == "datetime") && (empty($data[$c["index"]]) || $data[$c["index"]] == "//"))
				{
					$data[$c["index"]] = "NULL";
				}
				// if db field allows null, then set NULL
				else if ($c["isnull"] && empty($data[$c["index"]]))
				{
					$data[$c["index"]] = "NULL";
				}
				else if ($c["formatter"] == "date")
				{
					$data[$c["index"]] = date("Y-m-d",strtotime($data[$c["index"]]));
				}
				else if ($c["formatter"] == "datetime")
				{
					$data[$c["index"]] = date("Y-m-d H:i:s",strtotime($data[$c["index"]]));
				}
				// remove for lookup FK data, and dont when searching in same field
				else if ($c["formatter"] == "autocomplete" && $c["index"] != $c["formatoptions"]["update_field"])
				{
					unset($data[$c["index"]]);
				}
				else if ($c["formatter"] == "password" && $data[$c["index"]] == "*****")
				{
					unset($data[$c["index"]]);
				}

				// isnumeric check for sql '' issue
				if ($c["isnum"] === true)
					$is_numeric[$c["index"]] = true;
			}

			// handle grid operations of CRUD
			switch($op)
			{
				### P ###
				case "autocomplete":
					$field = $data['element'];
					$term = $data['term'];
					foreach( $this->options["colModel"] as $c )
					{
						if ($c["index"] == $field)
						{
							// if subqurey
							if (preg_match('/SELECT (.*) \\((.*)\) (.*)/', $c["formatoptions"]["sql"], $match))
							{
								if (preg_match('/SELECT .* \\((.*)\) (.*) WHERE (.*)/', $c["formatoptions"]["sql"], $match))
									$cond = "AND";
								else
									$cond = "WHERE";
							}
							// if normal query
							else if (stristr($c["formatoptions"]["sql"], " WHERE "))
								$cond = "AND";
							else
								$cond = "WHERE";

							$sql = $c["formatoptions"]["sql"]. " $cond {$c["formatoptions"]["search_on"]} like '$term%'";
							$result = $this->execute_query($sql);
							if ($this->con)
							{
								$rows = $result->GetArray();
								foreach ($rows as $key => $row) 
								{
									$arr = array();
									$arr['id'] = (isset($row["K"]) ? $row["K"] : $row["k"]);
								    $arr['label'] = (isset($row["V"]) ? $row["V"] : $row["v"]);
								    $arr['value'] = (isset($row["V"]) ? $row["V"] : $row["v"]);
								    $data_arr[] = $arr;									
								}
							}
							else
							{
								while($row = mysql_fetch_assoc($result)) 
								{
									$arr = array();
								    $arr['id'] = $row['k'];
								    $arr['label'] = $row['v'];
								    $arr['value'] = $row['v'];
								    $data_arr[] = $arr;
								}
							}

							header('Content-type: application/json');
							echo json_encode($data_arr);
							die;
						}
					}
					break;

				### P ###
				case "clone":

						// only clone if grid id is matched (fix for master-detail)
						if ($data["grid_id"] != $grid_id)
							break;

						$src_id = $data['id'];

						// get columns to build INSERT - SELECT query
						$sql = "SELECT * FROM ".$this->table . " LIMIT 1 OFFSET 0";
						$sql = $this->prepare_sql($sql,$this->db_driver);
						
						$result = $this->execute_query($sql);

						// and exclude PK
						if ($this->con)
						{
							$arr = $result->FetchRow();
							foreach($arr as $k=>$rs)
								if ($k != $pk_field)
									$f[] = $k;
						}
						else
						{		
							$numfields = mysql_num_fields($result);
							for ($i=0; $i < $numfields; $i++) // Header
							{
								$k = mysql_field_name($result, $i);
								if ($k != $pk_field)
									$f[] = $k;
							}
						}

						// custom onclone event execution
						if (!empty($this->events["on_clone"]))
						{
							$func = $this->events["on_clone"][0];
							$obj = $this->events["on_clone"][1];
							$continue = $this->events["on_clone"][2];
								
							if ($obj)
								call_user_func(array($obj,$func),array($pk_field => $src_id, "params" => &$f));
							else
								call_user_func($func,array($pk_field => $src_id, "params" => &$f));
						
							if (!$continue)
								break;
						}						

						$fields_str = implode(",",$f);
						$sql = "INSERT INTO {$this->table} ($fields_str) SELECT $fields_str FROM {$this->table} WHERE $pk_field = $src_id";
						$insert_id = $this->execute_query($sql,"insert_id");
					break;

				case "add":
					unset($data['id']);
					unset($data['oper']);
					
					$update_str = array();

					### P ###
					// custom oninsert event execution
					if (!empty($this->events["on_insert"]))
					{
						$func = $this->events["on_insert"][0];
						$obj = $this->events["on_insert"][1];
						$continue = $this->events["on_insert"][2];
						
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $id, "params" => &$data));
						else
							call_user_func($func,array($pk_field => $id, "params" => &$data));
						
						if (!$continue)
							break;
					}
					
					foreach($data as $k=>$v)
					{
						// remove any table alias from query - obseleted
						if (strstr($k,"::") !== false)
							list($tmp,$k) = explode("::",$k);
						$k = addslashes($k);

						// escape quotes for mssql
						if (strpos($this->db_driver, "mssql") !== false)
							$v = $this->addslashes_mssql($v);
						else
							$v = addslashes($v);

						$fields_str[] = "$k";

						$v = ($v == "NULL" || $is_numeric[$k] === true) ? $v : "'$v'";
						$values_str[] = "$v";
					}
					
					$insert_str = "(".implode(",",$fields_str).") VALUES (".implode(",",$values_str).")";
					
					$sql = "INSERT INTO {$this->table} $insert_str";

					$insert_id = $this->execute_query($sql,"insert_id");

					### P ###
					// custom onupdate event execution
					if (!empty($this->events["on_after_insert"]))
					{
						$func = $this->events["on_after_insert"][0];
						$obj = $this->events["on_after_insert"][1];
						$continue = $this->events["on_after_insert"][2];
						
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $insert_id, "params" => &$data));
						else
							call_user_func($func,array($pk_field => $insert_id, "params" => &$data));
						
						if (!$continue)
							break;
					}
					
					// for inline row addition, return insert id to update PK of grid (e.g. order_id#33)
					if ($id == "new_row")
						die($pk_field."#".$insert_id);

					// return JSON response for insert id
					if (intval($insert_id)>0)
						$res = array("id" => $insert_id, "success" => true);
					else
						$res = array("id" => 0, "success" => false);

					echo json_encode($res);

					break;
					
				case "edit":
					//pr($_POST);
					unset($data['id']);
					unset($data['oper']);
					
					$update_str = array();

					### P ###
					// custom onupdate event execution
					if (!empty($this->events["on_update"]))
					{
						$func = $this->events["on_update"][0];
						$obj = $this->events["on_update"][1];
						$continue = $this->events["on_update"][2];
						
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $id, "params" => &$data));
						else
							call_user_func($func,array($pk_field => $id, "params" => &$data));
						
						if (!$continue)
							break;
					}

					foreach($data as $k=>$v)
					{
						// remove any table alias from query - obseleted
						if (strstr($k,"::") !== false)
							list($tmp,$k) = explode("::",$k);
							
						$k = addslashes($k);

						// escape quotes for mssql
						if (strpos($this->db_driver, "mssql")!== false)
							$v = $this->addslashes_mssql($v);
						else
							$v = addslashes($v);

						// dont update blank fields in case of bulk edit
						if (strstr($id,",") !== false && $v === "")
							continue;

						$v = ($v == "NULL" || $is_numeric[$k] === true) ? $v : "'$v'";

						$update_str[] = "$k=$v";
					}
					
					$update_str = "SET ".implode(",",$update_str);
					
					if (strstr($pk_field,"::") !== false)
					{
						$pk_field = explode("::",$pk_field);
						$pk_field = $pk_field[1];
					}

					$id = "'".implode("','",explode(",", $id))."'";
					$sql = "UPDATE {$this->table} $update_str WHERE $pk_field IN ($id)";
					$ret = $this->execute_query($sql);

					### P ###
					// custom on after update event execution
					if (!empty($this->events["on_after_update"]))
					{
						$func = $this->events["on_after_update"][0];
						$obj = $this->events["on_after_update"][1];
						$continue = $this->events["on_after_update"][2];
						
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $id, "params" => &$data));
						else
							call_user_func($func,array($pk_field => $id, "params" => &$data));
						
						if (!$continue)
							break;
					}

					// return JSON response for update (passing id that was updated)
					if ($ret)
						$res = array("id" => $id, "success" => true);
					else
						$res = array("id" => 0, "success" => false);

					echo json_encode($res);

				break;			
				
				case "del":
					
					// obseleted
					if (strstr($pk_field,"::") !== false)
					{
						$pk_field = explode("::",$pk_field);
						$pk_field = $pk_field[1];
					}
					
					### P ###
					// custom on delete event execution
					if (!empty($this->events["on_delete"]))
					{
						$func = $this->events["on_delete"][0];
						$obj = $this->events["on_delete"][1];
						$continue = $this->events["on_delete"][2];
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $id));
						else
							call_user_func($func,array($pk_field => $id));
						
						if (!$continue)
							break;
					}
					
					$id = "'".implode("','",explode(",",$id))."'";
					$sql = "DELETE FROM {$this->table} WHERE $pk_field IN ($id)";
					$this->execute_query($sql);
					
					### P ###
					// custom on after delete event execution
					if (!empty($this->events["on_after_delete"]))
					{
						$func = $this->events["on_after_delete"][0];
						$obj = $this->events["on_after_delete"][1];
						$continue = $this->events["on_after_delete"][2];
						if ($obj)
							call_user_func(array($obj,$func),array($pk_field => $id));
						else
							call_user_func($func,array($pk_field => $id));
					
						if (!$continue)
							break;
					}
										
				break;
			}
			
			die;
		}
		
		// apply search conditions (where clause)
		$wh = "";
		
		if (!isset($_REQUEST['_search']))
			$_REQUEST['_search'] = "";
		
		$searchOn = $this->strip($_REQUEST['_search']);
		if($searchOn=='true') 
		{
			$fld = $this->strip($_REQUEST['searchField']);
			
			$cols = array();
			foreach($this->options["colModel"] as $col)
				$cols[] = $col["index"];

			// quick search bar
			if (!$fld)
			{
				$searchstr = $this->strip($_REQUEST['filters']);
				$wh = $this->construct_where($searchstr);
			}
			// search popup form, simple one -- not used anymore
			else
			{
				if(in_array($fld,$cols)) 
				{	
					$fldata = $this->strip($_REQUEST['searchString']);
					$foper = $this->strip($_REQUEST['searchOper']);
					// costruct where
					$wh .= " AND ".$fld;
					switch ($foper) {					
						case "eq":
							if(is_numeric($fldata)) {
								$wh .= " = ".$fldata;
							} else {
								$wh .= " = '".$fldata."'";
							}
							break;
						case "ne":
							if(is_numeric($fldata)) {
								$wh .= " <> ".$fldata;
							} else {
								$wh .= " <> '".$fldata."'";
							}
							break;
						case "lt":
							if(is_numeric($fldata)) {
								$wh .= " < ".$fldata;
							} else {
								$wh .= " < '".$fldata."'";
							}
							break;
						case "le":
							if(is_numeric($fldata)) {
								$wh .= " <= ".$fldata;
							} else {
								$wh .= " <= '".$fldata."'";
							}
							break;
						case "gt":
							if(is_numeric($fldata)) {
								$wh .= " > ".$fldata;
							} else {
								$wh .= " > '".$fldata."'";
							}
							break;
						case "ge":
							if(is_numeric($fldata)) {
								$wh .= " >= ".$fldata;
							} else {
								$wh .= " >= '".$fldata."'";
							}
							break;
						case "ew":
							$wh .= " LIKE '%".$fldata."'";
							break;
						case "en":
							$wh .= " NOT LIKE '%".$fldata."'";
							break;
						case "cn":
							$wh .= " LIKE '%".$fldata."%'";
							break;
						case "nc":
							$wh .= " NOT LIKE '%".$fldata."%'";
							break;
						case "in":
							$wh .= " IN (".$fldata.")";
							break;
						case "ni":
							$wh .= " NOT IN (".$fldata.")";
							break;
						case "bw":
						default:
							$fldata .= "%";
							$wh .= " LIKE '".$fldata."'";
							break;
					}
				}
			}
			// setting to persist where clause in export option
			$_SESSION["jqgrid_{$grid_id}_filter"] = $wh;
			$_SESSION["jqgrid_{$grid_id}_filter_request"] = $_REQUEST["filters"];
		}
		elseif($searchOn=='false') 
		{
			unset($_SESSION["jqgrid_{$grid_id}_filter"]);
			unset($_SESSION["jqgrid_{$grid_id}_filter_request"]);
		}
		
		// generate main json
		if (isset($_GET['jqgrid_page']))
		{
			$page = $_GET['jqgrid_page']; // get the requested page
			$limit = $_GET['rows']; // get how many rows we want to have into the grid
			$sidx = $_GET['sidx']; // get index row - i.e. user click to sort
			$sord = $_GET['sord']; // get the direction

			if(!$sidx) $sidx = 1;
			if(!$limit) $limit = 20;

			$sidx = str_replace("::",".",$sidx);

			// persist for export data
			if (isset($_GET["export"]))
			{
				$sidx = $_SESSION["jqgrid_{$grid_id}_sort_by"];
				$sord = $_SESSION["jqgrid_{$grid_id}_sort_order"];
			}
			else
			{
				$_SESSION["jqgrid_{$grid_id}_sort_by"] = $sidx;
				$_SESSION["jqgrid_{$grid_id}_sort_order"] = $sord;
			}
						
			### P ###
			// if export option is requested
			if (isset($_GET["export"]))
			{
				set_time_limit(0);
				$arr = array();

				// export data array (if grid loaded from array)
				if (is_array($this->table))
				{
					$t = $this->table;
					foreach($t[0] as $k => $v)
						$temp[$k] = ucwords($k);

					$arr[] = $temp;
					foreach ($t as $key => $value) {
						$arr[] = $value;
					}
				}
				// if grid loaded from db
				else
				{
					// by default export all
					$export_where = "";
					if ($this->options["export"]["range"] == "filtered")
						$export_where = $_SESSION["jqgrid_{$grid_id}_filter"];

					$limit_sql= "";
					if ($this->options["export"]["paged"] == "1")
					{
						$offset = $limit*$page - $limit; // do not put $limit*($page - 1)
						if ($offset<0) $offset = 0;
						$limit_sql = "LIMIT $limit OFFSET $offset";
					}
					
					// if sql is set on on_select event
					if (!empty($this->internal["sql"]))
					{
						$SQL = $this->internal["sql"]." $limit_sql";
					}
					else if (($p = stripos($this->select_command,"GROUP BY")) !== false)
					{
						$start = substr($this->select_command,0,$p);
						$end = substr($this->select_command,$p);
						$SQL = $start.$export_where.$end." ORDER BY $sidx $sord $limit_sql";
					}
					else
						$SQL = $this->select_command.$export_where." ORDER BY $sidx $sord $limit_sql";

					// custom export function if needed
					if (!empty($this->events["on_export"]))
					{	
						$func = $this->events["on_export"][0];
						$obj = $this->events["on_export"][1];
						$continue = $this->events["on_export"][2];

						if ($obj)
							call_user_func(array($obj,$func),array("sql" => $SQL, "grid" => &$this));
						else
							call_user_func($func,array("sql" => $SQL, "grid" => &$this));

						if (!$continue)
							exit(0);						
					}

					$result = $this->execute_query($SQL);

					foreach ($this->options["colModel"] as $c)
					{
						$header[$c["name"]] = $c["title"];
					}

					$arr[] = $header;
					
					if ($this->con)
					{
						$rows = $result->GetRows();
						foreach($rows as $row)
						{
							$export_data = array();

							foreach($header as $k=>$v)
								$export_data[$k] = $row[$k];	

							$arr[] = $export_data;						
						}
					}
					else
					{
						while($row = mysql_fetch_array($result,MYSQL_ASSOC))
						{
							$export_data = array();

							foreach($header as $k=>$v)
								$export_data[$k] = $row[$k];
								
							$arr[] = $export_data;
						}
					}
				}

				$col_widths = array();
				// export only selected columns
				$cols_not_to_export = array();
				$cols_to_export = array();
				if ($this->options["colModel"])
				{
					foreach ($this->options["colModel"] as $c)
					{
						if ($c["export"] === false)
							$cols_not_to_export[] = $c["name"];
						else
						{
							$cols_to_export[] = $c["name"];
							$col_widths[$c["name"]] = (!empty($c["width"]) ? $c["width"] : 'auto');
						}
					}
				}

				// fix for d/m/Y date format in export. strtotime expects m/d/Y
				foreach($this->options["colModel"] as $c)
				{
					foreach ($arr as &$rec)
					{
						// skip header from date format conversion
						if ($rec === $arr[0])
							continue;
						
						// show masked data in password
						if (isset($c["formatter"]) && $c["formatter"] == "password")
							$rec[$c["name"]] = "*****";
						
						if (!empty($rec[$c["name"]]) && ($c["formatter"] == "date" || $c["formatter"] == "datetime"))
						{
							$dt = $rec[$c["name"]];

							$js_dt_fmt = $c["formatoptions"]["newformat"];
							$js_dt_fmt = str_replace("yy", "Y", $js_dt_fmt);
							$js_dt_fmt = str_replace("mm", "m", $js_dt_fmt);
							$js_dt_fmt = str_replace("dd", "d", $js_dt_fmt);

							$rec[$c["name"]] = date($js_dt_fmt,strtotime($dt));
						}

						### P ###
						// Replace condition data in pdf export
						$col_name = $c["name"];
						if (isset($c["default"]) && !isset($rec[$col_name]))
							$rec[$col_name] = $c["default"];

						// link data in grid to any given url
						if (!empty($link_c["default"]))
						{
							// replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
							$rec[$col_name] = $this->replace_row_data($rec,$c["default"]);
						}
						
						// check conditional data
						if (!empty($c["condition"][0]))
						{
							$r = true;

							// replace {} placeholders from connditional data
							$c["condition"][1] = $this->replace_row_data($rec,$c["condition"][1]);
							$c["condition"][2] = $this->replace_row_data($rec,$c["condition"][2]);

							$row = $rec;
							eval("\$r = ".$c["condition"][0].";");
							$rec[$col_name] = ( $r ? $c["condition"][1] : $c["condition"][2]);
							$rec[$col_name] = strip_tags($rec[$col_name]);
						}
					}
				}

				// remove db columns as well as virtual columns
				if (!empty($cols_to_export))
				{
					$export_arr = array();
					foreach($arr as $arr_item)
					{
						foreach($arr_item as $k=>$i)
						{
							if (!in_array($k, $cols_to_export))
							{
								unset($arr_item[$k]);
							}
						}
						$export_arr[] = $arr_item;
					}	
					$arr = $export_arr;
				}

				if (!$this->options["export"]["filename"])
					$this->options["export"]["filename"] = $grid_id;
					
				if (!$this->options["export"]["sheetname"])
					$this->options["export"]["sheetname"] = ucwords($grid_id). " Sheet";
					
				if ($this->options["export"]["format"] == "pdf")
				{
					$orientation = $this->options["export"]["orientation"];
					if ($orientation == "landscape")
						$orientation = "L";
					else
						$orientation = "P";

					$paper = $this->options["export"]["paper"];

					// Using opensource TCPdf lib
					// for more options visit http://www.tcpdf.org/examples.php

					require_once('tcpdf/config/lang/eng.php');
					require_once('tcpdf/class.TCPDF.EasyTable.php');

					// create new PDF document
					$pdf = new TCPDF_EasyTable($orientation, PDF_UNIT, $paper, true, 'UTF-8', false);

					// set document information
					$pdf->SetCreator("www.phpgrid.org");
					$pdf->SetAuthor('www.phpgrid.org');
					$pdf->SetTitle('www.phpgrid.org');
					$pdf->SetSubject($this->options["caption"]);
					$pdf->SetKeywords('www.phpgrid.org');

					// remove default header/footer
					$pdf->setPrintHeader(true);
					$pdf->setPrintFooter(true);

					// set default monospaced font
					$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
					$pdf->setFontSubsetting(false);

					//set margins
					$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);

					//set auto page breaks
					$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

					//set image scale factor
					$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

					// set some language dependent data:

					// lines for rtl pdf generation

					if ($this->options["direction"] == "rtl")
					{
						$lg = Array();
						$lg['a_meta_charset'] = 'UTF-8';
						$lg['a_meta_dir'] = 'rtl';
						$lg['a_meta_language'] = 'fa';
						$lg['w_page'] = 'page';
					}
					$pdf->setLanguageArray($lg);

					// To set your custom font
					// $fontname = $pdf->addTTFfont('/path-to-font/DejaVuSans.ttf', 'TrueTypeUnicode', '', 32);
					// set font http://www.tcexam.org/doc/code/classTCPDF.html#afd56e360c43553830d543323e81bc045

					// add a page
					$pdf->AddPage();

				    $pdf->SetY( 10, true );
					$pdf->Cell( 0, 15, $this->options["export"]["heading"], 0, 1 );

				    # Table parameters
					$pdf->SetFont('helvetica', '', 12);

					// for special charset language, uncoment this line
					// $pdf->SetFont('cid0jp', '', 10);

				    $pdf->SetHeaderCellsFontStyle(''); // 'b'
			        $pdf->SetHeaderCellsFillColor(150,150,150);
			        $pdf->SetHeaderCellsFontColor(0,0,0);
			        $pdf->SetFillColor(240,240,240); // for cells background
			        $pdf->SetCellFontColor(0,0,0);

			        // auto set column widths based on grid column width
					$margins = $pdf->GetMargins();
					$pdf_page_width = $pdf->GetPageWidth() - $margins['left'] - $margins['right'];
			        $total_width = 0;
			        foreach ($col_widths as $key => $value) 
			        	$total_width += $value;	

			        $new_widths = array();
			        foreach ($col_widths as $key => $value) 
			        {
			        	$new_widths[$key] = $pdf_page_width * ($value/$total_width);	
			        	$new_widths[] = $pdf_page_width * ($value/$total_width);	
			        }

			        $pdf->SetCellWidths($new_widths);
			        $pdf->SetCellFillStyle(2);
			        $pdf->SetCellPadding(1);
			        $pdf->SetCellMinimumHeight(null);

					// if customized pdf render is defined, use that
					if (!empty($this->events["on_render_pdf"]))
					{	
						$func = $this->events["on_render_pdf"][0];
						$obj = $this->events["on_render_pdf"][1];
						if ($obj)
							call_user_func(array($obj,$func),array("pdf" => &$pdf, "data" => &$arr));
						else
							call_user_func($func,array("pdf" => &$pdf, "data" => &$arr));
					}

					$h = $arr[0];
				    array_shift($arr);
				    $pdf->EasyTable($arr,$h);

				    if (strstr($this->options["export"]["filename"],".pdf") === false)
				    	$this->options["export"]["filename"] .= ".pdf";
				    
					//Close and output PDF document
					$pdf->Output($this->options["export"]["filename"], 'I');
					die;
				}
				else if ($this->options["export"]["format"] == "csv")
				{
					if (strstr($this->options["export"]["filename"],".csv") === false)
						$this->options["export"]["filename"] .= ".csv";
										
		            header( 'Content-Type: text/csv' );
		            header( 'Content-Disposition: attachment;filename='.$this->options["export"]["filename"]);		
		            $fp = fopen('php://output', 'w');
		            foreach ($arr as $key => $value) 
		            {
		            	fputcsv($fp, $value);
		            }
		            die;			
				}
				else
				{
					include("php-export-data.class.php");
					$excel = new ExportDataExcel('browser');
					
					if (strstr($this->options["export"]["filename"],".xls") === false &&
						strstr($this->options["export"]["filename"],".xlsx") === false )
						$this->options["export"]["filename"] .= ".xls";
										
					$excel->filename = $this->options["export"]["filename"];
					$excel->initialize();
					foreach($arr as $row) 
					{
						$excel->addRow($row);
					}
					$excel->finalize();
					die;
				}
			}
						
			// if defined in on_select event
			if (!empty($this->internal["sql_count"]))
			{
				$sql_count = $this->internal["sql_count"]; 
			}
			else if (!empty($this->select_count))
			{
				$sql_count = $this->select_count.$wh;
			}
			else if (($p = stripos($this->select_command,"GROUP BY")) !== false)
			{
				$sql_count = preg_replace("/SELECT (.*) FROM/i","SELECT 1 as c FROM",$this->select_command);
				$p = stripos($sql_count,"GROUP BY");
				$start_q = substr($sql_count,0,$p);
				$end_q = substr($sql_count,$p);
				$sql_count = "SELECT count(*) as c FROM ($start_q $wh $end_q) o";
			}
			else
			{
				$sql_count = $this->select_command.$wh;
				$sql_count = "SELECT count(*) as c FROM (".$sql_count.") table_count";
			}
			# print_r($sql_count);
			
			$result = $this->execute_query($sql_count);

			if ($this->con)
			{
				$row = $result->FetchRow();
			}
			else
			{
				$row = mysql_fetch_array($result,MYSQL_ASSOC);
			}

			$count = $row['c'];

			// fix for oracle, alias in capitals
			if (empty($count)) 
				$count = $row['C'];

			if( $count > 0 ) {
				$total_pages = ceil($count/$limit);
			} else {
				$total_pages = 0;
			}

			if ($page > $total_pages) $page=$total_pages;
			$start = $limit*$page - $limit; // do not put $limit*($page - 1)
			if ($start<0) $start = 0;

			$responce = new stdClass();
			$responce->page = $page;
			$responce->total = $total_pages;
			$responce->records = $count;

			if (!empty($this->internal["sql"]))
			{
				$SQL = $this->internal["sql"] . " LIMIT $limit OFFSET $start";
			}
			else if (($p = stripos($this->select_command,"GROUP BY")) !== false)
			{
				$start_q = substr($this->select_command,0,$p);
				$end_q = substr($this->select_command,$p);
				$SQL = "$start_q $wh $end_q ORDER BY $sidx $sord LIMIT $limit OFFSET $start";
			}
			else
			{
				$SQL = $this->select_command.$wh." ORDER BY $sidx $sord LIMIT $limit OFFSET $start";
			}

			$SQL = $this->prepare_sql($SQL,$this->db_driver);

			$result = $this->execute_query($SQL);

			if ($this->con)
			{
				$rows = $result->GetRows();

				// simulate artificial paging for mssql
				if (count($rows) > $limit)
					$rows = array_slice($rows,count($rows) - $limit);
			}
			else
			{
				$rows = array();
				while($row = mysql_fetch_array($result,MYSQL_ASSOC))
					$rows[] = $row;
			}

			### P ###
			// custom on_data_display event execution
			if (!empty($this->events["on_data_display"]))
			{
				$func = $this->events["on_data_display"][0];
				$obj = $this->events["on_data_display"][1];
				$continue = $this->events["on_data_display"][2];
				
				if ($obj)
					call_user_func(array($obj,$func),array("params" => &$rows));
				else
					call_user_func($func,array("params" => &$rows));
				
				if (!$continue)
					break;
			}
			
			foreach ($rows as $row)	
			{
				$orig_row = $row;
				// apply php level formatter for image url 30.12.10
				foreach($this->options["colModel"] as $c)
				{
					$col_name = $c["name"];
					
					### P ###
					if (isset($c["default"]) && !isset($row[$col_name]))
						$row[$col_name] = $c["default"];

					// link data in grid to any given url
					if (!empty($c["default"]))
					{
						// replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
						$row[$col_name] = $this->replace_row_data($orig_row,$c["default"]);
					}
					
					// check conditional data
					if (!empty($c["condition"][0]))
					{
						$r = true;

						// replace {} placeholders from connditional data
						$c["condition"][1] = $this->replace_row_data($orig_row,$c["condition"][1]);
						$c["condition"][2] = $this->replace_row_data($orig_row,$c["condition"][2]);

						eval("\$r = ".$c["condition"][0].";");
						$row[$col_name] = ( $r ? $c["condition"][1] : $c["condition"][2]);
					}	

					// check data filter (alternate of grid on_data_display, but for current column)
					if (!empty($c["on_data_display"]))
					{
						$func = $c["on_data_display"][0];
						$obj = $c["on_data_display"][1];
						
						if ($obj)
							$row[$col_name] = call_user_func(array($obj,$func),$row);
						else
							$row[$col_name] = call_user_func($func,$row);
					}
					### P-END ###

					// link data in grid to any given url
					if (!empty($c["link"]))
					{
						// replace any param in link e.g. http://domain.com?id={id} given that, there is a $col["name"] = "id" exist
						// replace_row_data not used due to urlencode work
						foreach($this->options["colModel"] as $link_c)
						{
							// if there is url in data, don't urlencode
							if (strstr($orig_row[$link_c["name"]],"http://"))
								$link_row_data = $orig_row[$link_c["name"]];
							else
								$link_row_data = urlencode($orig_row[$link_c["name"]]);

							$c["link"] = str_replace("{".$link_c["name"]."}", $link_row_data, $c["link"]);
						}
						
						$attr = "";
						if (!empty($c["linkoptions"]))
							$attr = $c["linkoptions"];

						$row[$col_name] = htmlentities($row[$col_name],ENT_QUOTES, "UTF-8");
						
						// if link is made with custom date format
						if (isset($c["formatoptions"]["newformat"]))
						{
							$js_dt_fmt = $c["formatoptions"]["newformat"];
							$js_dt_fmt = str_replace("yy", "Y", $js_dt_fmt);
							$js_dt_fmt = str_replace("mm", "m", $js_dt_fmt);
							$js_dt_fmt = str_replace("dd", "d", $js_dt_fmt);
							$row[$col_name] = date($c["formatoptions"]["newformat"],strtotime($row[$col_name]));
						}

						$row[$col_name] = "<a $attr href='{$c["link"]}'>{$row[$col_name]}</a>";
					}

					// render row data as "src" value of <img> tag
					if (isset($c["formatter"]) && $c["formatter"] == "image")
					{
						$attr = array();
						foreach($c["formatoptions"] as $k=>$v)
							$attr[] = "$k='$v'";
						
						$attr = implode(" ",$attr);
						$row[$col_name] = "<img $attr src='".$row[$col_name] ."'>";
					}
						
					// show masked data in password
					if (isset($c["formatter"]) && $c["formatter"] == "password")
						$row[$col_name] = "*****";			
				}

				foreach($row as $k=>$r)
					$row[$k] = stripslashes($row[$k]);

				$responce->rows[] = $row;
			}

			// fix for mssql utf8 fix
			if (strpos($this->db_driver,"mssql") !== false)
				$responce = array_utf8_encode_recursive($responce);

			echo json_encode($responce);
			die;
		}		
		
		### P ###
		// if loading from array
		if (is_array($this->table))
		{
			$this->options["data"] = json_encode($this->table);
			$this->options["datatype"] = "local";	
			$this->actions["rowactions"] = false;		
			$this->actions["add"] = false;		
			$this->actions["edit"] = false;		
			$this->actions["delete"] = false;		
		}

		// few overides - pagination fixes
		$this->options["pager"] = '#'.$grid_id."_pager";
		$this->options["jsonReader"] = array("repeatitems" => false, "id" => "0");

		// allow/disallow edit,del operations
		if ( ($this->actions["edit"] === false && $this->actions["delete"] === false) || $this->options["cellEdit"] === true)
			$this->actions["rowactions"] = false;
			
		if ($this->actions["rowactions"] !== false)
		{
			// CRUD operation column
			$f = false;
			$defined = false;
			foreach($this->options["colModel"] as &$c)
			{
				if ($c["name"] == "act")
				{
					$defined = &$c;
				}
					
				if (!empty($c["width"]))
				{
					$f = true;
				}
			}
			
			// icon col fix, text links as old behavior (fixed:true, mean exact px)
			if ($this->internal["actionicon"] === true)
				$w = ($this->actions["clone"] === true)?"80":"55";
			else
				$w = ($this->actions["clone"] === true)?"120":"100";
			
			// width adjustment for row actions column
			$action_column = array("name"=>"act", "fixed"=>true, "align"=>"center", "index"=>"act", "width"=>"$w", "sortable"=>false, "search"=>false, "viewable"=>false);

			if (!$defined)
			{
				$this->options["colNames"][] = "Actions";
				$this->options["colModel"][] = $action_column;
			}
			else
				$defined = array_merge($action_column,$defined);			
		}		

		// simulate field access right options
		$str_add_form = '';
		$str_edit_form = '';
		$str_delete_form = '';
		$str_edit_access = '';
		$str_inline_access = '';

		foreach($this->options["colModel"] as &$c)
		{

			// auto reload & edit for link pattern fix
			if (!empty($c["link"]))
			{
				$this->options["reloadedit"] = true;
				$c["formatter"] = "function(cellvalue, options, rowObject){ 

										arr = jQuery(document).data('link_{$c["name"]}');
										if (!arr) arr = {};
										
										if (jQuery(cellvalue).text() != '')
										{
											arr[jQuery(cellvalue).text()] = cellvalue;
											jQuery(document).data('link_{$c["name"]}',arr);
											return arr[jQuery(cellvalue).text()];
										}
										else
										{
											// fix for link text 'undefined'
											if (typeof(arr[cellvalue]) == 'undefined')
												return '';
											else
												return arr[cellvalue];
										}


									}";
				$c["unformat"] = "function(cellvalue, options, cell){return jQuery(cell).text();}";				
			}

			// make readonly field while editing
			if (isset($c["editrules"]["readonly"]))
			{
				if ($c["editrules"]["readonly"] === true)
				{
					$tag = "input";

					if ( !empty($c["edittype"]) )
						$tag = $c["edittype"];

					if (!empty($c["editrules"]["readonly-when"]))
					{
						$cond = $c["editrules"]["readonly-when"];
						if (!is_numeric($cond[1]))
							$cond[1] = '"'.$cond[1].'"';
						
						$str_edit_access .= 'if (jQuery("#tr_'.$c["index"].' .DataTD '.$tag.'",formid).val() '.$cond[0].' '.$cond[1].')';
						$str_inline_access .= 'if (jQuery("'.$tag.'[name='.$c["index"].']:last").val() '.$cond[0].' '.$cond[1].')';
					}

					$str_edit_access .= 'jQuery("#tr_'.$c["index"].' .DataTD",formid).html("&nbsp;" + jQuery("#tr_'.$c["index"].' .DataTD '.$tag.'",formid).val());';
					$str_inline_access .= '{';
					$str_inline_access .= 'jQuery("'.$tag.'[name='.$c["index"].']:last").hide();';
					$str_inline_access .= 'jQuery("'.$tag.'[name='.$c["index"].']:last").parent().append(jQuery("'.$tag.'[name='.$c["index"].']:last").val());';
					$str_inline_access .= '}';
				}

				unset($c["editrules"]["readonly"]);
			}

			if (!empty($c["show"]))
			{
				if ($c["show"]["list"] === false)
					$c["hidden"] = true;
				else
					$c["hidden"] = false;

				if ($c["show"]["edit"] === false)
				{
					$str_edit_access .= 'jQuery("#tr_'.$c["index"].'",formid).remove();';
				}
				else
					$str_edit_access .= 'jQuery("#tr_'.$c["index"].'",formid).show();';

				if ($c["show"]["add"] === false)
					$str_add_access .= 'jQuery("#tr_'.$c["index"].'",formid).remove();';
				else
					$str_add_access .= 'jQuery("#tr_'.$c["index"].'",formid).show();';

				if ($c["show"]["view"] === false)
					$str_view_access .= 'jQuery("#trv_'.$c["index"].'").hide();';
				else
					$str_view_access .= 'jQuery("#trv_'.$c["index"].'").show();';

				unset($c["show"]);
			}
		}

		// set before show form events

		if (!empty($this->internal["add_options"]["beforeShowForm"]))
			$str_add_form = $str_add_access . $this->internal["add_options"]["beforeShowForm"];
		else
			$str_add_form = $str_add_access;

		if (!empty($this->internal["edit_options"]["beforeShowForm"]))
			$str_edit_form = $str_edit_access . $this->internal["edit_options"]["beforeShowForm"];
		else
			$str_edit_form = $str_edit_access;

		if (!empty($this->internal["delete_options"]["beforeShowForm"]))
			$str_delete_form = $str_delete_access . $this->internal["delete_options"]["beforeShowForm"];
		else
			$str_delete_form = $str_delete_access;

		if (!empty($this->internal["view_options"]["beforeShowForm"]))
			$str_view_form = $str_view_access . $this->internal["view_options"]["beforeShowForm"];
		else
			$str_view_form = $str_view_access;

		### P ###
		$this->options["add_options"]["beforeShowForm"] = 'function(formid) { '.$str_add_form.' }';
		$this->options["edit_options"]["beforeShowForm"] = 'function(formid) { '.$str_edit_form.' }';
		$this->options["delete_options"]["beforeShowForm"] = 'function(formid) { '.$str_delete_form.' }';
		$this->options["view_options"]["beforeShowForm"] = 'function(formid) { '.$str_view_form.' }';
		// event for dialog < > navigation
		$this->options["view_options"]["afterclickPgButtons"] = 'function(formid) { '.$str_view_access.' }';
		### P-END ###
		
		### P ###
		if (empty($this->options["add_options"]["success_msg"]))
			$this->options["add_options"]["success_msg"] = "Record added";
		if (empty($this->options["edit_options"]["success_msg"]))
			$this->options["edit_options"]["success_msg"] = "Record edited";
		if (empty($this->options["delete_options"]["success_msg"]))
			$this->options["delete_options"]["success_msg"] = "Record deleted";


		if (empty($this->options["add_options"]["afterSubmit"]))	
		$this->options["add_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					fx_success_msg("'.$this->options["add_options"]["success_msg"].'",1);
																			      	return [true,""];
																				} 
																			}';

		if (empty($this->options["edit_options"]["afterSubmit"]))
		$this->options["edit_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					fx_success_msg("'.$this->options["edit_options"]["success_msg"].'",1);
																			      	return [true,""];
																				} 
																			}';

		if (empty($this->options["delete_options"]["afterSubmit"]))
		$this->options["delete_options"]["afterSubmit"] = 'function(response) { if(response.status == 200)
																				{ 
																					fx_success_msg("'.$this->options["delete_options"]["success_msg"].'",1);
																			      	return [true,""];
																				} 
																			}';
		### P-END ###

		// search options for templates
		$this->options["search_options"]["multipleSearch"] = ($this->actions["search"] == "advance")?true:false;
		$this->options["search_options"]["sopt"] = array('eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc','nu','nn');

		$out = json_encode_jsfunc($this->options);
		$out = substr($out,0,strlen($out)-1);

		if ($this->options["reloadedit"] === true)
			$reload_after_edit = "jQuery('#$grid_id').jqGrid().trigger('reloadGrid',[{jqgrid_page:1}]);";

		// create Edit/Delete - Save/Cancel column in grid
		if ($this->actions["rowactions"] !== false)
		{
			$act_links = array();
			
			if ($this->internal["actionicon"] === true) // icons as action links
			{
				if ($this->actions["edit"] !== false)
					$act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-pencil\" title=\"Edit this row\" href=\"javascript:void(0);\" onclick=\"jQuery(this).dblclick();\"></a>";
				
				### P ###
				if ($this->actions["clone"] === true)
					$act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-copy\" title=\"Clone this row\" href=\"javascript:void(0);\" onclick=\"fx_clone_row(\'$grid_id\',\''+cl+'\'); \"></a>";
					### P-END ###
				
				if ($this->actions["delete"] !== false)
					$act_links[] = "<a class=\"ui-custom-icon ui-icon ui-icon-trash\" title=\"Delete this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#$grid_id\').delGridRow(\''+cl+'\'); \"></a>";
				
				$act_links = implode("", $act_links);
			
				$out .= ",'gridComplete': function()
							{
								var ids = jQuery('#$grid_id').jqGrid('getDataIDs');
								for(var i=0;i < ids.length;i++)
								{
									var cl = ids[i];
						
									be = '$act_links';
						
									// il_save, ilcancel, iledit are clicked for inlineNav button reset
									se = '<a class=\"ui-custom-icon ui-icon ui-icon-disk\" title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"if (jQuery(\'#$grid_id\').saveRow(\''+cl+'\') || jQuery(\'.editable\').length==0) { jQuery(this).parent().hide(); jQuery(this).parent().prev().show(); ". addslashes($reload_after_edit)." }\"></a>';
									ce = '<a class=\"ui-custom-icon ui-icon ui-icon-cancel\" title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilcancel\').click(); jQuery(\'#$grid_id\').restoreRow(\''+cl+'\'); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\"></a>';
						
									// for inline add option
									if (ids[i] == 'new_row')
									{
										se = '<a class=\"ui-custom-icon ui-icon ui-icon-disk\" title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilsave\').click(); \">Save</a>';
										ce = '<a class=\"ui-custom-icon ui-icon ui-icon-cancel\" title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilcancel\').click(); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>';
										jQuery('#$grid_id').jqGrid('setRowData',ids[i],{act:'<span style=display:none id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});
									}
									else
										jQuery('#$grid_id').jqGrid('setRowData',ids[i],{act:'<span id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span style=display:none id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});
								}
							}";						
			}
			else // text based action links
			{
				if ($this->actions["edit"] !== false)
					$act_links[] = "<a title=\"Edit this row\" href=\"javascript:void(0);\" onclick=\"jQuery(this).dblclick();\">Edit</a>";
	
				### P ###
				if ($this->actions["clone"] === true)
					$act_links[] = "<a title=\"Clone this row\" href=\"javascript:void(0);\" onclick=\"fx_clone_row(\'$grid_id\',\''+cl+'\'); \">Clone</a>";
				### P-END ###

				if ($this->actions["delete"] !== false)
					$act_links[] = "<a title=\"Delete this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#$grid_id\').delGridRow(\''+cl+'\'); \">Delete</a>";
	
				$act_links = implode(" | ", $act_links);
	
				$out .= ",'gridComplete': function()
							{
								var ids = jQuery('#$grid_id').jqGrid('getDataIDs');
								for(var i=0;i < ids.length;i++)
								{
									var cl = ids[i];
									
									be = '$act_links'; 
		
									// il_save, ilcancel, iledit are clicked for inlineNav button reset
									se = ' <a title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"if (jQuery(\'#$grid_id\').saveRow(\''+cl+'\') || jQuery(\'.editable\').length==0) { jQuery(this).parent().hide(); jQuery(this).parent().prev().show(); ". addslashes($reload_after_edit)." }\">Save</a>'; 
									ce = ' | <a title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilcancel\').click(); jQuery(\'#$grid_id\').restoreRow(\''+cl+'\'); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>'; 
		
									// for inline add option							
									if (ids[i] == 'new_row')
									{
										se = ' <a title=\"Save this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilsave\').click(); \">Save</a>'; 
										ce = ' | <a title=\"Restore this row\" href=\"javascript:void(0);\" onclick=\"jQuery(\'#{$grid_id}_ilcancel\').click(); jQuery(this).parent().hide(); jQuery(this).parent().prev().show();\">Cancel</a>'; 
										jQuery('#$grid_id').jqGrid('setRowData',ids[i],{act:'<span style=display:none id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});
									}
									else
										jQuery('#$grid_id').jqGrid('setRowData',ids[i],{act:'<span id=\"edit_row_{$grid_id}_'+cl+'\">'+be+'</span>'+'<span style=display:none id=\"save_row_{$grid_id}_'+cl+'\">'+se+ce+'</span>'});
								}	
							}";
			}		
		}					
		
		// double click editing option
		if ($this->actions["rowactions"] !== false && $this->actions["edit"] !== false && $this->options["cellEdit"] !== true)
		{
			$out .= ",'ondblClickRow': function(id) 
						{
							if(id && id!==lastSel)
							{ 
								jQuery('#$grid_id').restoreRow(lastSel); 
								
								// disabled previously edit icons
								jQuery('#edit_row_{$grid_id}_'+lastSel).show();
								jQuery('#save_row_{$grid_id}_'+lastSel).hide();								
								
								lastSel=id; 								
							}

							jQuery('#$grid_id').editRow(id, true, function(){}, function()
																				{
																					jQuery('#edit_row_{$grid_id}_'+id).show();
																					jQuery('#save_row_{$grid_id}_'+id).hide();

																					return true;
																				},null,null,
																				function()
																				{
																					// force reload grid after inline save
																					$reload_after_edit
																				},null,
																				function()
																				{
																					jQuery('#edit_row_{$grid_id}_'+id).show();
																					jQuery('#save_row_{$grid_id}_'+id).hide();

																					return true;
																				}
														); 
							
							// for inlineNav edit button fix
							jQuery('#{$grid_id}').setSelection(id, true);
							jQuery('#{$grid_id}_iledit').click();

							jQuery('#edit_row_{$grid_id}_'+id).hide();
							jQuery('#save_row_{$grid_id}_'+id).show();

							$str_inline_access
						}";
		}
		
		### P ###
		// if subgrid is there, enable subgrid feature
		if (isset($this->options["subgridurl"]) && $this->options["subgridurl"] != '') 
		{
			// we pass two parameters
			// subgrid_id is a id of the div tag created within a table
			// the row_id is the id of the row
			// If we want to pass additional parameters to the url we can use
			// the method getRowData(row_id) - which returns associative array in type name-value
			// here we can easy construct the following
					
			$pass_params = "false";
			if (!empty($this->options["subgridparams"]))
				$pass_params = "true";
				
			$out .= ",'subGridRowExpanded': function(subgridid, id) 
											{ 
												var data = {subgrid:subgridid, rowid:id};
												
												if('$pass_params' == 'true') {
													var anm= '".$this->options["subgridparams"]."';
													anm = anm.split(',');
													var rd = jQuery('#".$grid_id."').jqGrid('getRowData', id);
													if(rd) {
														for(var i=0; i<anm.length; i++) {
															if(rd[anm[i]]) {
																data[anm[i]] = rd[anm[i]];
															}
														}
													}
												}
												jQuery('#'+jQuery.jgrid.jqID(subgridid)).load('".$this->options["subgridurl"]."',data);
											}";				
		}

		// on error
		$out .= ",'loadError': function(xhr,status, err) { 
					try 
					{
						jQuery.jgrid.info_dialog(jQuery.jgrid.errors.errcap,'<div class=\"ui-state-error\">'+ xhr.responseText +'</div>', 
													jQuery.jgrid.edit.bClose,{buttonalign:'right'});

					} 
					catch(e) { alert(xhr.responseText);}
				}
				";

		// on row selection operation
		$out .= ",'onSelectRow': function(ids) { ";

				### P ###
				if (isset($this->options["detail_grid_id"]) && $this->options["detail_grid_id"] != '') 
				{
					$detail_grid_id	= $this->options["detail_grid_id"];
					$d_grids = explode(",", $detail_grid_id);

					foreach($d_grids as $detail_grid_id) 
					{
						$detail_url = $this->options["url"];
						
						$s = (strstr($this->options["url"], "?")) ? "&":"?";
						$detail_url .= $s."grid_id=". $detail_grid_id;
						
						$out .= "
		
						var data = '';
						if ('{$this->options["subgridparams"]}'.length > 0)
						{
							var anm = '".$this->options["subgridparams"]."';
							anm = anm.split(',');
							var rd = jQuery('#".$grid_id."').jqGrid('getRowData', ids);
							if(rd) {
								for(var i=0; i<anm.length; i++) {
									if(rd[anm[i]]) {
										data += '&' + anm[i] + '=' + rd[anm[i]];
									}
								}
							}
						}	
							
						if(ids == null) 
						{
							ids=0;
							if(jQuery('#".$detail_grid_id."').jqGrid('getGridParam','records') >0 )
							{
								jQuery('#".$detail_grid_id."').jqGrid('setGridParam',{url:'".$detail_url."&rowid='+ids+data,editurl:'".$detail_url."&rowid='+ids,jqgrid_page:1});
								jQuery('#".$detail_grid_id."').trigger('reloadGrid',[{jqgrid_page:1}]);
							}
						} 
						else 
						{
							jQuery('#".$detail_grid_id."').jqGrid('setGridParam',{url:'".$detail_url."&rowid='+ids+data,editurl:'".$detail_url."&rowid='+ids,jqgrid_page:1});
							jQuery('#".$detail_grid_id."').trigger('reloadGrid',[{jqgrid_page:1}]);			
						}

						jQuery('#".$detail_grid_id."').data('jqgrid_detail_grid_params','&rowid='+ids+data);
						";
					}
				};

				### P ###
				if (!empty($this->events["js_on_select_row"])) 
				{
					$out .= "if (typeof({$this->events["js_on_select_row"]}) != 'undefined') {$this->events["js_on_select_row"]}(ids);";
				}	
		// closing of select row events
		$out .= "}";
		
		// fix for formatting, to apply on only new records of virtual scroll
		if($this->options["scroll"] == true)
		{		
			$out .= ",'beforeRequest': function() {";
				$out .= "jQuery('#$grid_id').data('jqgrid_rows',jQuery('#$grid_id tr.jqgrow').length);";
			$out .= "}";
		}

		// on load complete operation
		$out .= ",'loadComplete': function(ids) {";

				// In case 'All' param is used in pager
				$out .= "jQuery('#{$grid_id}_pager option[value=\"All\"]').val(99999);";

				if (isset($this->options["detail_grid_id"]) && $this->options["detail_grid_id"] != '') 
				{
					$detail_grid_id	= $this->options["detail_grid_id"];
					$d_grids = explode(",", $detail_grid_id);

					foreach($d_grids as $detail_grid_id) 
					{
						$detail_url = $this->options["url"];
						$s = (strstr($this->options["url"], "?")) ? "&":"?";
						$detail_url .= $s."grid_id=". $detail_grid_id;

						$out .= "
								jQuery('#".$detail_grid_id."').jqGrid('setGridParam',{url:'".$detail_url."&rowid=',editurl:'".$detail_url."&rowid=',jqgrid_page:1});
								jQuery('#".$detail_grid_id."').trigger('reloadGrid',[{jqgrid_page:1}]);";
					}

				}		

			// formatting fix for virtual scrolling
			$fix_format = "";
			if($this->options["scroll"] == true)
			{
				$fix_format = " var last_rows = 0;
								if (typeof(jQuery('#$grid_id').data('jqgrid_rows')) != 'undefined')
									i = i + jQuery('#$grid_id').data('jqgrid_rows');
								";
			}

			$out .= "if(ids.rows) jQuery.each(ids.rows,function(i){
						$fix_format
						";
				
					### P ###
					if (count($this->conditional_css))
					{
						foreach ($this->conditional_css as $value) 
						{
							if ($value["op"] == "cn")
							{
								$out .= "
									if (this.{$value[column]}.toLowerCase().indexOf('{$value[value]}'.toLowerCase()) != -1)
								 	{
								 		if ('".$value["class"]."' != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+')').addClass('".$value["class"]."');
								 		else if (\"".$value["css"]."\" != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+')').css('background','inherit').css({{$value[css]}});
								 		else if ('".$value["cellclass"]."' != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('".$value["cellclass"]."');
								 		else if (\"".$value["cellcss"]."\" != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});
								 	}";
							}
							else if ($value["op"] == "eq" || $value["op"] == "=")
							{
								$out .= "
									if (this.{$value[column]}.toLowerCase() == '{$value[value]}'.toLowerCase())
								 	{
								 		if ('".$value["class"]."' != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+')').addClass('".$value["class"]."');
								 		else if (\"".$value["css"]."\" != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+')').css('background','inherit').css({{$value[css]}});
								 		else if ('".$value["cellclass"]."' != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('".$value["cellclass"]."');
								 		else if (\"".$value["cellcss"]."\" != '')
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});
								 	}";
							}
							else if ($value["op"] == "<" || $value["op"] == "<=" || $value["op"] == ">" || $value["op"] == ">=" || $value["op"] == "!=")
							{
								$out .= "
									if (this.{$value[column]} {$value["op"]} {$value[value]})
								 	{
								 		if ('".$value["class"]."' != '')
								 		{
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+')').addClass('".$value["class"]."');
								 		}
								 		else if (\"".$value["css"]."\" != '')
								 		{
									 		jQuery('#$grid_id tr.jqgrow:eq('+i+')').css('background','inherit').css({{$value[css]}});
									 		jQuery('#$grid_id tr.jqgrow:eq('+i+') a').css('background','inherit').css({{$value[css]}});
								 		}
								 		else if ('".$value["cellclass"]."' != '')
								 		{
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').addClass('".$value["cellclass"]."');
								 		}
								 		else if (\"".$value["cellcss"]."\" != '')
								 		{
								 			jQuery('#$grid_id tr.jqgrow:eq('+i+') td[aria-describedby={$grid_id}_{$value[column]}]').css('background','inherit').css({{$value[cellcss]}});
								 		}
								 	}";
							}
							// column formatting
							else if (empty($value["op"]) && !empty($value["column"]) && !empty($value["css"]))
							{
								$out .= "
								 	{
								 		if (jQuery.browser.msie)
								 			jQuery('#$grid_id td[aria-describedby={$grid_id}_{$value["column"]}]').css('background','inherit').css({{$value[css]}});
								 		else
								 			jQuery('#$grid_id td[aria-describedby={$grid_id}_{$value["column"]}]').removeClass('.ui-widget-content').css({{$value[css]}});
								 	}";							
							}
						}
					}
					### P-END ###

			$out .= "});";

			### P ###
			if (!empty($this->events["js_on_load_complete"])) 
			{
				$out .= "if (typeof({$this->events["js_on_load_complete"]}) != 'undefined') {$this->events["js_on_load_complete"]}(ids);";
			}


		// closing of load complete events
		$out .= "}";

		// closing of param list
		$out .= "}";

		// Navigational grid params
		if (!isset($this->navgrid["param"]))
		{
			$this->navgrid["param"]["edit"] = ($this->actions["edit"] === false) ? false:true;
			$this->navgrid["param"]["add"] = ($this->actions["add"] === false) ? false:true;
			$this->navgrid["param"]["del"] = ($this->actions["delete"] === false) ? false:true;
			$this->navgrid["param"]["view"] = ($this->actions["view"] === true) ? true:false;
			$this->navgrid["param"]["refresh"] = ($this->actions["refresh"] === false) ? false:true;
			### P ### -- turn false
			$this->navgrid["param"]["search"] = ($this->actions["search"] === false) ? false : true;

			// fix for del and delete text
			if (!empty($this->navgrid["param"]["delete"]))
				$this->navgrid["param"]["del"] = $this->navgrid["param"]["delete"];
		}

		// Generate HTML/JS code
		ob_start();
		?>
			<table id="<?php echo $grid_id?>"></table> 
			<div id="<?php echo $grid_id."_pager"?>"></div> 
			<script>
			var phpgrid = jQuery("#<?php echo $grid_id?>");
			var phpgrid_pager = jQuery("#<?php echo $grid_id."_pager"?>");
			var fx_ajax_file_upload;
			var fx_replace_upload;
			var fx_bulk_update;
			var fx_get_dropdown;

			jQuery(document).ready(function(){
				<?php echo $this->render_js($grid_id,$out);?>
			});	

			</script>	
		<?php
		return ob_get_clean();
	}