diff --git a/BaseButton.php b/BaseButton.php index f144148..fc64d91 100644 --- a/BaseButton.php +++ b/BaseButton.php @@ -239,11 +239,29 @@ public function handleClick($token, $uniqueId = null) */ protected function createButton($row = null) { + $button = Html::el('a')->href($this->getLink($row)); + $button->class[] = 'gridito-button'; + if ($this->icon && $this->showText) { + $button->class[] = 'button-icon-text'; + } elseif ($this->icon) { + $button->class[] = 'button-icon'; + $button->class[] = 'gridito-hide-text'; + $button->title($this->label); + } else { + $button->class[] = 'button-text'; + } + + if ($this->icon) { + $button->create('span')->class(array('gridito-icon', $this->icon)); + } + $button->create('span class="gridito-text"')->setText($this->label); + return $button; + return Html::el("a") ->href($this->getLink($row)) ->data("gridito-icon", $this->icon) - ->class(array("gridito-button", $this->showText ? null : "gridito-hide-text")) - ->setText($this->label); + ->class(array("gridito-button js-disabled", $this->showText ? null : "gridito-hide-text")) + ->add(Html::el('span')->setText($this->label)); } @@ -259,4 +277,4 @@ public function render($row = null) } } -} \ No newline at end of file +} diff --git a/Button.php b/Button.php index 248de05..a9f86e0 100644 --- a/Button.php +++ b/Button.php @@ -52,7 +52,7 @@ public function getConfirmationQuestion($row) if (is_callable($this->confirmationQuestion)) { return call_user_func($this->confirmationQuestion, $row); } else { - return $this->confirmationQuestion; + return Grid::formatRecordString($row, $this->confirmationQuestion); } } @@ -103,4 +103,4 @@ protected function createButton($row = null) return $el; } -} \ No newline at end of file +} diff --git a/Column.php b/Column.php index 03874bf..11de479 100644 --- a/Column.php +++ b/Column.php @@ -1,6 +1,8 @@ // public function setCellClass($class) { - $this->cellClass = $class; + $this->cellClass = $class; return $this; } @@ -98,7 +109,65 @@ public function setRenderer($cellRenderer) return $this; } + /** + * Set maximal length of cell + * @param $maxlen + * @return Column + */ + public function setLength($maxlen) + { + $this->maxlen = $maxlen; + return $this; + } + /** + * Get maximal length of cell + * @return int + */ + public function getLength() + { + return $this->maxlen; + } + + /** + * Set the type of cell + * @param string type + * @return Column + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * Get the type of cell + * @return string type + */ + public function getType($type) + { + return $this->type; + } + + /** + * Set format of the cell + * @param mixed format + * @return Column + */ + public function setFormat($format) + { + $this->format = $format; + return $this; + } + + /** + * Get the format + * @return mixed + */ + public function getFormat() + { + return $this->format; + } /** * Is sortable? @@ -192,6 +261,36 @@ public static function renderDateTime($value, $format) echo $value->format($format); } + /** + * Render the text, takes care of length + * @param string $text text to render + * @param int $maxlen maximum length of text + */ + public static function renderText($text, $maxlen) + { + if (is_null($maxlen) || Strings::length($text) < $maxlen) { + echo htmlspecialchars($text, ENT_NOQUOTES); + } else { + echo Html::el('span')->title($text) + ->setText(Strings::truncate($text, $maxlen)); + } + } + + /** + * Render the email address, takes care of length + * @param string $email email address + * @param int $maxlen maximum length of text + */ + public static function renderEmail($email, $maxlen) + { + $el = Html::el('a')->href('mailto:' . $email); + if (is_null($maxlen) || Strings::length($email) < $maxlen) { + echo $el->setText($email); + } else { + echo $el->title($email) + ->setText(Strings::truncate($email, $maxlen)); + } + } /** @@ -204,16 +303,23 @@ public function defaultCellRenderer($record, $column) { $value = $record->$name; // boolean - if (is_bool($value)) { + if (in_array($this->type, array('bool', 'boolean')) || is_bool($value)) { self::renderBoolean($value); // date } elseif ($value instanceof \DateTime) { self::renderDateTime($value, $this->dateTimeFormat); + // email + } elseif ($this->type == 'email') { + self::renderEmail($value, $this->maxlen); + // other } else { - echo $value; + if (!is_null($this->format)) { + $value = Grid::formatRecordString($record, $this->format); + } + self::renderText($value, $this->maxlen); } } @@ -227,4 +333,4 @@ public function renderCell($record) { call_user_func($this->renderer ?: array($this, "defaultCellRenderer"), $record, $this); } -} \ No newline at end of file +} diff --git a/Grid.php b/Grid.php index cc7b52e..00ec0e3 100644 --- a/Grid.php +++ b/Grid.php @@ -3,6 +3,7 @@ namespace Gridito; use Nette\ComponentModel\Container, Nette\Environment, Nette\Utils\Paginator; +use Nette\Utils\Strings; /** * Grid @@ -66,6 +67,15 @@ public function __construct(\Nette\ComponentModel\IContainer $parent = null, $na $this->paginator->setItemsPerPage($this->defaultItemsPerPage); } + public static function formatRecordString($record, $formatString) + { + return Strings::replace($formatString, '#%[^%]*%#u', + function ($m) use ($record) { + $m = Strings::trim($m[0], '%'); + return $m != '' ? $record[$m] : "%"; + }); + } + // // @@ -401,4 +411,4 @@ protected function setOptions($object, $options) } } -} \ No newline at end of file +} diff --git a/css/_gridito.scss b/css/_gridito.scss new file mode 100644 index 0000000..d1340c6 --- /dev/null +++ b/css/_gridito.scss @@ -0,0 +1,132 @@ +@import '_jquery.ui.scss'; +/** + * Gridito CSS + */ + +/* flashes */ +div.gridito-flash { + padding: 0.5em; + margin: 1em 0; +} +div.gridito-flash .ui-icon { + float: left; + margin-right: 0.5em; +} + +/* toolbar */ +.gridito-toolbar { + margin-bottom: 1em; +} +.gridito-toolbar .ui-button { + margin-right: 0.5em; +} + +/* table */ +.gridito-table { + border-collapse: collapse; + width: 100%; + @extend .ui-widget; + @extend .ui-widget-content; + th { + padding: 0.5em; + text-align: left; + @extend .ui-widget-header; + .gridito-sorting { + float:right; + margin-left: 0.5em; + position: relative; + top: 0.2em; + .sorting-no, .sorting-asc, .sorting-desc { + @extend .ui-icon; + } + .sorting-no { + opacity: 0.5; + &:hover { + opacity: 1; + } + } + .sorting-no, .sorting-desc:hover { + @extend .ui-icon-carat-2-n-s; + } + .sorting-asc, .sorting-no:hover { + @extend .ui-icon-triangle-1-n; + } + .sorting-desc, .sorting-asc:hover { + @extend .ui-icon-triangle-1-s; + } + } + &:hover .gridito-sorting .sorting-no { + opacity: 1; + } + } + tbody tr:hover { + @extend .ui-state-hover; + } +} +.gridito-table th { +} +.gridito-table td { + padding: 0.5em; + border: 1px solid #BBB; + &.highlight { + @extend .ui-state-highlight; + } +} + +.gridito-table tr { + max-height: 2ex; +} + +.gridito-button { + @extend .ui-button; + @extend .ui-widget; + @extend .ui-state-default; + @extend .ui-corner-all; + + &.button-text { + @extend .ui-button-text-only; + } + &.button-icon { + @extend .ui-button-icon-only; + } + &.button-icon-text { + @extend .ui-button-text-icon-primary; + } + &.disabled { + @extend .ui-button-disabled; + @extend .ui-state-disabled; + } + &:hover { + @extend .ui-state-hover; + } + &:active { + @extend .ui-state-active; + } + &:focus { + @extend .ui-state-focus; + } +} +span.gridito-icon { + @extend .ui-button-icon-primary; + @extend .ui-icon; +} +span.gridito-text { + @extend .ui-button-text; +} +.gridito-table .ui-state-hover .gridito-cell { +font-weight: normal; +} +.gridito-actioncell .ui-button { +margin: 0 0.5em 0 0; +} +.gridito-actioncell .ui-button:first-child { +margin-left: 0; +} +.gridito-actioncell { +text-align: center; +} + +/* paginator */ +.gridito-paginator { + margin-top: 1em; +} diff --git a/css/gridito.css b/css/gridito.css deleted file mode 100644 index 6591fcd..0000000 --- a/css/gridito.css +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Gridito CSS - */ - -/* flashes */ -div.gridito-flash { - padding: 0.5em; - margin: 1em 0; -} -div.gridito-flash .ui-icon { - float: left; - margin-right: 0.5em; -} - -/* toolbar */ -.gridito-toolbar { - margin-bottom: 1em; -} -.gridito-toolbar .ui-button { - margin-right: 0.5em; -} - -/* table */ -.gridito-table { - border-collapse: collapse; - width: 100%; -} -.gridito-table th { - padding: 0.5em; - text-align: left; -} -.gridito-table td { - padding: 0.5em; - border: 1px solid #BBB; -} -.gridito-table .ui-state-hover .gridito-cell { - font-weight: normal; -} -.gridito-actioncell .ui-button { - margin: 0 0.5em 0 0; -} -.gridito-actioncell .ui-button:first-child { - margin-left: 0; -} -.gridito-actioncell { - text-align: center; -} - -/* th */ -.gridito-table th .gridito-sorting { - float:right; - margin-left: 0.5em; - position: relative; - top: 0.2em; -} -.gridito-table th .gridito-sorting .ui-icon { - opacity: 0.5 -} -.gridito-table th:hover .gridito-sorting .ui-icon, .gridito-table th .gridito-sorting .ui-icon.ui-icon-triangle-1-s, .gridito-table th .gridito-sorting .ui-icon.ui-icon-triangle-1-n { - opacity: 1 -} - -/* paginator */ -.gridito-paginator { - margin-top: 1em; -} \ No newline at end of file diff --git a/js/jquery.ui.gridito.js b/js/jquery.ui.gridito.js index f1ebe19..94ace2a 100644 --- a/js/jquery.ui.gridito.js +++ b/js/jquery.ui.gridito.js @@ -2,46 +2,14 @@ $.widget("ui.gridito", { - options: { - - }, - + options: {}, _create: function () { var _this = this; - this.table = this.element.find("table.gridito-table"); - this.table.addClass("ui-widget ui-widget-content"); - this.table.find("th").addClass("ui-widget-header"); - this.table.find("tbody tr").hover(function () { - $(this).addClass("ui-state-hover"); - }, function () { - $(this).removeClass("ui-state-hover"); - }); - - // sorting icons - function initSortingIcons(normalClass, hoverClass) { - _this.table.find("thead th ." + normalClass).hover(function () { - $(this).removeClass(normalClass).addClass(hoverClass); - }, function () { - $(this).removeClass(hoverClass).addClass(normalClass); - }); - }; - - initSortingIcons("ui-icon-carat-2-n-s", "ui-icon-triangle-1-n"); - initSortingIcons("ui-icon-triangle-1-n", "ui-icon-triangle-1-s"); - initSortingIcons("ui-icon-triangle-1-s", "ui-icon-carat-2-n-s"); - // buttons this.element.find("a.gridito-button").each(function () { var el = $(this); - el.button({ - icons: { - primary: el.attr("data-gridito-icon") - }, - text: !el.hasClass("gridito-hide-text"), - disabled: el.hasClass("disabled") - }); // window button if (el.hasClass("gridito-window-button")) { @@ -73,4 +41,4 @@ $.widget("ui.gridito", { }); -})(jQuery); \ No newline at end of file +})(jQuery); diff --git a/models/NetteModel.php b/models/NetteModel.php new file mode 100644 index 0000000..565197d --- /dev/null +++ b/models/NetteModel.php @@ -0,0 +1,56 @@ +selection = $selection; + } + + public function getItemByUniqueId($uniqueId) + { + $select = clone $this->selection; + return $select->where($this->getPrimaryKey(), $uniqueId) + ->fetch(); + } + + public function getItems() + { + $select = clone $this->selection; + + list($sortColumn, $sortType) = $this->getSorting(); + if ($sortColumn) { + $select->order("$sortColumn $sortType"); + } + return $select->limit($this->getLimit(), $this->getOffset()) + ->fetchPairs($this->getPrimaryKey()); + } + + + /** + * Item count + * @return int + */ + protected function _count() + { + return $this->selection->count(); + } + +} diff --git a/templates/grid.phtml b/templates/grid.phtml index 0777c1e..3a7b579 100644 --- a/templates/grid.phtml +++ b/templates/grid.phtml @@ -41,9 +41,9 @@ {block tableheadercontent} - - - + + + {$column->getLabel()} {/block} @@ -55,7 +55,7 @@ {block tablebody} - + {control $column:cell $item} @@ -76,17 +76,17 @@ {block paginator} {var $paginator = $control->getPaginator()} - Previous + Previous {for $i = 1; $i <= $paginator->pageCount; $i++} - {$i} + {$i} {/for} - Next + Next {/block} {/block} {/if} -{/snippet} \ No newline at end of file +{/snippet}