<?php
/**
* @version $Id: grid.class.php 2440 2022-03-05 16:54:34Z IOS $
* @package Elxis
* @subpackage Grid
* @copyright Copyright (c) 2006-2022 Elxis CMS (https://www.elxis.org). All rights reserved.
* @license Elxis Public License ( https://www.elxis.org/elxis-public-license.html )
* @author Elxis Team ( https://www.elxis.org )
* @description Elxis CMS is free software. Read the license for copyright notices and details
*/
defined('_ELXIS_') or die ('Direct access to this location is not allowed');
class elxisGrid {
private $element = 'elxisgrid';
private $title = 'Elxis grid';
private $url = '';
private $dataType = 'xml';
private $sortname = '';
private $sortorder = 'asc';
private $usepager = true;
private $useRp = true;
private $rp = 10;
private $newp = 1;
private $width = '100%';
private $height = 'auto';
private $resizable = false;
private $showTableToggleBtn = false;
private $showToggleBtn = false;
private $singleSelect = false;
private $percentage = 'auto';//false:use pixels, true: use percentage column widths, 'auto': auto (calculate on render)
private $dir = 'ltr';
private $i18n = array();
private $columns = array();
private $buttons = array();
private $searchitems = array();
private $filteritems = array();
private $hiddenitems = array();
private $errors = array();
/*********************/
/* MAGIC CONSTRUCTOR */
/*********************/
public function __construct($element='', $title='') {
$eLang = eFactory::getLang();
if (trim($element) != '') { $this->element = $element; }
if (trim($title) != '') { $this->title = $title; }
$this->dir = $eLang->getinfo('DIR');
$this->i18n['pagetext'] = $eLang->get('PAGE');
$this->i18n['outof'] = $eLang->get('OF');
$this->i18n['pagestat'] = sprintf($eLang->get('DISPLAY_FROM_TO_TOTAL'), '{from}', '{to}', '{total}');
$this->i18n['findtext'] = $eLang->get('SEARCH');
$this->i18n['procmsg'] = $eLang->get('PLEASE_WAIT');
$this->i18n['nomsg'] = $eLang->get('NO_RESULTS');
$this->i18n['errormsg'] = $eLang->get('CONNECT_ERROR');
$this->i18n['submittext'] = $eLang->get('SUBMIT');
}
/*************************/
/* SET A GRID'S PROPERTY */
/*************************/
public function setOption($option, $value) {
switch (strtolower($option)) {
case 'element': $this->element = $value; break;
case 'title': if (trim($value) != '') { $this->title = $value; } break;
case 'url': $this->url = $value; break;
case 'datatype':
$value = strtolower($value);
$this->dataType = ($value == 'json') ? 'json' : 'xml';
break;
case 'sortname': $this->sortname = $value; break;
case 'sortorder':
$value = strtolower($value);
$this->sortorder = ($value == 'desc') ? 'desc' : 'asc';
break;
case 'usepager':
case 'userp':
case 'resizable':
case 'showtabletogglebtn':
case 'showtogglebtn':
case 'singleselect':
$this->$option = (bool)$value;
break;
case 'rp':
$value = (int)$value;
$this->rp = ($value > 0) ? $value : 10;
break;
case 'newp'://start page
$value = (int)$value;
$this->newp = ($value > 0) ? $value : 1;
break;
case 'width':
case 'height':
if (is_int($value)) {
$this->$option = ($value > 0) ? $value : (($option == 'height') ? 'auto' : '100%');
} else if ($value == 'auto') {
$this->$option = 'auto';
} else {
if (preg_match('/(\%)$/', $value)) { $this->$option = $value; }
}
break;
case 'dir': $this->dir = ($value == 'rtl') ? 'rtl' : 'ltr'; break;
case 'percentage': $this->$option = (bool)$value; break;
default: break;
}
}
/****************************/
/* ADD A COLUMN TO THE GRID */
/****************************/
public function addColumn($title, $name='', $width=140, $sortable=true, $align='auto', $filteroptions=array(), $initvalue='') {
if (trim($name) == '') { $n = count($this->columns) + 1; $name = 'col'.$n; }
$width = (int)$width;
if ($width < 1) { $width = 140; }
$sortable = (bool)$sortable;
switch ($align) {
case 'left': case 'right': case 'center'; break;
case 'auto': default: $align = ($this->dir == 'rtl') ? 'right' : 'left'; break;
}
$this->columns[$name] = array(
'title' => $title,
'width' => $width,
'sortable' => $sortable,
'align' => $align
);
if (is_array($filteroptions) && (count($filteroptions) > 0)) {
$this->addFilter($title, $name, $filteroptions, $initvalue);
}
}
/****************************/
/* ADD A BUTTON TO THE GRID */
/****************************/
public function addButton($title, $task='', $class='', $onpress='') {
$this->buttons[] = array(
'type' => 'button',
'title' => $title,
'task' => $task,
'class' => $class,
'onpress' => $onpress,
'sepbool' => false
);
}
/***************************/
/* ADD A SEPARATOR BUTTTON */
/***************************/
public function addSeparator($bool=true) {
$this->buttons[] = array(
'type' => 'separator',
'title' => '',
'task' => '',
'class' => '',
'onpress' => '',
'sepbool' => (bool)$bool
);
}
/*************************/
/* ADD A SEARCHABLE ITEM */
/*************************/
public function addSearch($title, $name, $isdefault=false) {
if (trim($name) == '') {
$this->errors[] = 'A Search item must have a name!';
return false;
}
$this->searchitems[$name] = array(
'title' => $title,
'isdefault' => (bool)$isdefault
);
}
/*********************/
/* ADD A FILTER ITEM */
/*********************/
public function addFilter($title, $name, $options=array(), $value='') {
$name = trim($name);
if ($name == '') {
$this->errors[] = 'A Filter item must have a name!';
return false;
}
if (in_array(strtolower($name), array('page', 'rp', 'sortname', 'sortorder', 'query', 'qtype'))) {
$this->errors[] = 'A Filter item can not be named '.$name.'!';
return false;
}
if (!is_array($options) || (count($options) == 0)) { return false; }
$this->filteritems[$name] = array(
'title' => $title,
'options' => $options,
'value' => $value
);
}
/***********************/
/* ADD A HIDDEN COLUMN */
/***********************/
public function addHidden($name, $value) {
$name = trim($name);
if ($name == '') {
$this->errors[] = 'A hidden item must have a name!';
return false;
}
if (in_array(strtolower($name), array('page', 'rp', 'sortname', 'sortorder', 'query', 'qtype'))) {
$this->errors[] = 'A hidden item can not be named '.$name.'!';
return false;
}
$this->hiddenitems[$name] = $value;
}
/*******************/
/* SHOW GRID ERROR */
/*******************/
private function showError($msg) {
echo '<div class="elx_error"><strong>'.eFactory::getLang()->get('ERROR').'</strong> '.$msg.'</div>'."\n";
}
/*****************/
/* GENERATE GRID */
/*****************/
public function render() {
$eDoc = eFactory::getDocument();
$elxis = eFactory::getElxis();
if ($this->errors) {
$errortxt = implode('<br />', $this->errors);
$this->showError($errortxt);
return;
}
if (!$this->columns) {
$this->showError('The grid has no columns!');
return;
}
$sfx = ($this->dir == 'rtl') ? '-rtl' : '';
$eDoc->addJQuery();
$eDoc->addScriptLink($elxis->secureBase().'/includes/js/jquery/flexigrid/flexigrid.js');
$eDoc->addStyleLink($elxis->secureBase().'/includes/js/jquery/flexigrid/css/flexigrid'.$sfx.'.css');
if ($this->sortname == '') {
foreach ($this->columns as $name => $col) {
$this->sortname = $name;
break;
}
}
//percentage calculator
$total_width = 0;
$last_col = '';
foreach ($this->columns as $name => $col) {
$total_width += $col['width'];
$last_col = $name;
}
if ($this->percentage == 'auto') {
if ($total_width < 700) {
$this->percentage = false;
} else {
$this->percentage = true;
}
}
if ($this->percentage == true) {
echo '<table id="'.$this->element.'" style="display: none; width:100%;"></table>'."\n";
} else {
echo '<table id="'.$this->element.'" style="display: none"></table>'."\n";
}
echo '<script>'."\n";
echo '$(\'#'.$this->element.'\').flexigrid({'."\n";
echo 'url: \''.$this->url.'\','."\n";
echo 'dataType: \''.$this->dataType.'\','."\n";
echo 'colModel: ['."\n";
$n = count($this->columns);
$i = 1;
foreach ($this->columns as $name => $col) {
$stxt = ($col['sortable'] === true) ? 'true' : 'false';
if ($this->percentage == true) {//percentage columns
if ($last_col == $name) {
echo "\t".'{ display:\''.addslashes($col['title']).'\', name:\''.$name.'\', width:\'auto\', sortable:'.$stxt.', align:\''.$col['align'].'\'}';
} else {
$pcw = intval((100 * $col['width']) / $total_width);
echo "\t".'{ display:\''.addslashes($col['title']).'\', name:\''.$name.'\', width:\''.$pcw.'%\', sortable:'.$stxt.', align:\''.$col['align'].'\'}';
}
} else {
echo "\t".'{ display:\''.addslashes($col['title']).'\', name:\''.$name.'\', width:'.$col['width'].', sortable:'.$stxt.', align:\''.$col['align'].'\'}';
}
echo ($i < $n) ? ",\n" : "\n";
$i++;
}
echo "],\n";
$n = count($this->buttons);
if ($n > 0) {
$i = 1;
echo 'buttons: ['."\n";
foreach ($this->buttons as $btn) {
if ($btn['type'] == 'separator') {
$stxt = ($btn['sepbool'] === true) ? 'true' : 'false';
echo "\t{separator: ".$stxt.'}';
} else {
echo "\t{name: '".$btn['title'].'\'';
if ($btn['task'] != '') { echo ', task: \''.$btn['task'].'\''; }
if ($btn['class'] != '') { echo ', bclass: \''.$btn['class'].'\''; }
if ($btn['onpress'] != '') { echo ', onpress: '.$btn['onpress']; }
echo '}';
}
echo ($i < $n) ? ",\n" : "\n";
$i++;
}
echo "],\n";
}
$n = count($this->searchitems);
if ($n > 0) {
$i = 1;
echo 'searchitems: ['."\n";
foreach ($this->searchitems as $name => $item) {
$stxt = ($item['isdefault'] === true) ? 'true' : 'false';
echo "\t".'{display:\''.addslashes($item['title']).'\', name:\''.$name.'\', isdefault:'.$stxt.'}';
echo ($i < $n) ? ",\n" : "\n";
$i++;
}
echo "],\n";
}
$n = count($this->filteritems);
if ($n > 0) {
$i = 1;
echo 'filteritems: ['."\n";
foreach ($this->filteritems as $name => $item) {
$optstr = '';
$t = count($item['options']);
$x = 1;
foreach ($item['options'] as $k => $v) {
$optstr .= '{oval:\''.$k.'\', otxt:\''.addslashes($v).'\'}';
$optstr .= ($x < $t) ? ',' : '';
$x++;
}
echo "\t".'{display:\''.addslashes($item['title']).'\', name:\''.$name.'\', opts:['.$optstr.'], value:\''.addslashes($item['value']).'\'}';
echo ($i < $n) ? ",\n" : "\n";
$i++;
}
echo "],\n";
}
$n = count($this->hiddenitems);
if ($n > 0) {
$i = 1;
echo 'hiddenitems: ['."\n";
foreach ($this->hiddenitems as $name => $value) {
echo "\t".'{name:\''.$name.'\', value:\''.$value.'\'}';
echo ($i < $n) ? ",\n" : "\n";
$i++;
}
echo "],\n";
}
echo 'sortname: \''.$this->sortname."',\n";
echo 'sortorder: \''.$this->sortorder."',\n";
if ($this->newp > 1) { echo 'newp: '.$this->newp.",\n"; }
$stxt = ($this->usepager === true) ? 'true' : 'false';
echo 'usepager: '.$stxt.",\n";
$stxt = ($this->useRp === true) ? 'true' : 'false';
echo 'useRp: '.$stxt.",\n";
echo 'rp: '.$this->rp.",\n";
$stxt = ($this->showTableToggleBtn === true) ? 'true' : 'false';
echo 'showTableToggleBtn: '.$stxt.",\n";
$stxt = ($this->showToggleBtn === true) ? 'true' : 'false';
echo 'showToggleBtn: '.$stxt.",\n";
$stxt = ($this->resizable === true) ? 'true' : 'false';
echo 'resizable: '.$stxt.",\n";
$stxt = ($this->singleSelect === true) ? 'true' : 'false';
echo 'singleSelect: '.$stxt.",\n";
if (is_int($this->width)) {
echo 'width: '.$this->width.",\n";
} else {
echo 'width: \''.$this->width."',\n";
}
if (is_int($this->height)) {
echo 'height: '.$this->height.",\n";
} else {
echo 'height: \''.$this->height."',\n";
}
$stxt = ($this->percentage == true) ? 'true' : 'false';
echo 'percentage: '.$stxt.",\n";
echo 'title: \''.addslashes($this->title)."',\n";
foreach ($this->i18n as $k => $v) {
echo $k.': \''.addslashes($v)."',\n";
}
echo 'dir: \''.$this->dir."'\n";
echo '});'."\n";
echo "</script>\n";
}
}
?>