From 5c2e50d5fe4e08e3ada792c20d74e4a12ed2ff96 Mon Sep 17 00:00:00 2001 From: "v.stepanenko" Date: Thu, 10 Mar 2016 21:52:45 +0200 Subject: [PATCH] DetailsRow & AjaxDetailsRow components added --- src/Component/AjaxDetailsRow.php | 59 ++++++++++++++++++++ src/Component/DetailsRow.php | 92 ++++++++++++++++++++++++++++++++ tests/webapp/Controller.php | 69 ++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 src/Component/AjaxDetailsRow.php create mode 100644 src/Component/DetailsRow.php diff --git a/src/Component/AjaxDetailsRow.php b/src/Component/AjaxDetailsRow.php new file mode 100644 index 0000000..02804e9 --- /dev/null +++ b/src/Component/AjaxDetailsRow.php @@ -0,0 +1,59 @@ +"; + }), $resourceManager); + $this->setUrlGenerator($urlGenerator); + } + + /** + * @return callable + */ + public function getUrlGenerator() + { + return $this->urlGenerator; + } + + /** + * @param callable $urlGenerator + * @return $this + */ + public function setUrlGenerator(callable $urlGenerator) + { + $this->urlGenerator = $urlGenerator; + return $this; + } + + public function render() + { + $this->view->setData(call_user_func($this->getUrlGenerator(), $this->getGrid()->getCurrentRow())); + return SolidRow::render(); + } + + protected function getScriptSource() + { + return parent::getScriptSource() . ' + jQuery(\'tr[data-row-with-details="1"]\').click(function() { + var $detailsRow = jQuery(this).next(); + var $detailsContainer; + if (!$detailsRow.data(\'loaded\')) { + $detailsRow.data(\'loaded\', 1); + $detailsContainer = $detailsRow.find(\'[data-details-container="1"]\'); + $detailsContainer.load($detailsContainer.data("details-url")); + } + }); + '; + } +} diff --git a/src/Component/DetailsRow.php b/src/Component/DetailsRow.php new file mode 100644 index 0000000..d9047c4 --- /dev/null +++ b/src/Component/DetailsRow.php @@ -0,0 +1,92 @@ +getRowTag() + ->setAttribute('style', 'display:none;') + ->setAttribute('data-details-row', '1'); + $this->addChild($this->view = $view); + $this->setDestinationParentId(Grid::COLLECTION_VIEW_ID); + $this->setId('details_row'); + $this->resourceManager = $resourceManager ?: Services::resourceManager(); + $this->jquery = $this->resourceManager->js('jquery'); + } + + public function render() + { + $this->view->setData($this->getGrid()->getCurrentRow()); + return parent::render(); + } + + /** + * @return null|Grid + */ + protected function getGrid() + { + return $this->root; + } + + public function attachToCompound(Compound $root, $prepend = false) + { + $isAlreadyAttached = $this->root !== null; + $this->attachToCompoundInternal($root, $prepend); + if ($isAlreadyAttached) { + return; + } + $tr = $this->getGrid()->getRecordView(); + if (!$tr instanceof TagInterface) { + throw new RuntimeException( + "Details row works only with record_view components implementing TagInterface" + ); + } + $tr->setAttribute('data-row-with-details', 1); + $this->getGrid()->children() + ->add($this->jquery, 1) + ->add($this->getScript());; + // fix zebra styled tables + $this->parent()->addChild(new DataView('')); + + } + + protected function getScript() + { + $source = $this->getScriptSource(); + return new DataView(""); + } + + protected function getScriptSource() + { + return ' + jQuery(\'tr[data-row-with-details="1"]\').click(function() { + jQuery(this).next().toggle(\'slow\'); + }); + '; + } +} diff --git a/tests/webapp/Controller.php b/tests/webapp/Controller.php index 9f65f89..8312f13 100644 --- a/tests/webapp/Controller.php +++ b/tests/webapp/Controller.php @@ -3,13 +3,17 @@ use DateTime; +use ViewComponents\Grids\Component\AjaxDetailsRow; use ViewComponents\Grids\Component\ColumnSortingControl; +use ViewComponents\Grids\Component\DetailsRow; use ViewComponents\Grids\Component\TableCaption; use ViewComponents\TestingHelpers\Application\Http\DefaultLayoutTrait; +use ViewComponents\ViewComponents\Component\Container; use ViewComponents\ViewComponents\Component\Control\FilterControl; use ViewComponents\ViewComponents\Component\Control\PageSizeSelectControl; use ViewComponents\ViewComponents\Component\Control\PaginationControl; use ViewComponents\ViewComponents\Component\DataView; +use ViewComponents\ViewComponents\Component\Debug\SymfonyVarDump; use ViewComponents\ViewComponents\Component\Html\Tag; use ViewComponents\ViewComponents\Component\Part; use ViewComponents\ViewComponents\Component\TemplateView; @@ -367,4 +371,69 @@ public function demo12() return $this->page(null, 'Grid Caption'); } + + + public function demo13() + { + + $grid = new Grid($provider = $this->getDataProvider(), + [ + new Column('id'), + new Column('name'), + new DetailsRow(new SymfonyVarDump()) + ] + ); + $grid->attachTo($this->layout()); + + $styling = new BootstrapStyling(); + $styling->apply($this->layout()); + $this->defaultCss->detach(); + return $this->page(null, 'DetailsRow'); + } + + public function demo14() + { + if (isset($_GET['details'])) { + return $this->demo14Details(); + } + $grid = new Grid($provider = $this->getDataProvider(), + [ + new Column('id'), + new Column('name'), + new AjaxDetailsRow(function ($row) { + return "/demo14?details=1&id=" . $row->id; + }) + ] + ); + $grid->attachTo($this->layout()); + + $styling = new BootstrapStyling(); + $styling->apply($this->layout()); + $this->defaultCss->detach(); + return $this->page(null, 'AjaxDetailsRow'); + } + + protected function demo14Details() + { + $provider = $this->getDataProvider(); + $provider->operations()->add(new FilterOperation('id', FilterOperation::OPERATOR_EQ, $_GET['id'])); + $grid = new Grid( + $provider, + [ + + new Column('name'), + new Column('role'), + new Column('birthday'), + ] + ); + $styling = new BootstrapStyling(); + $styling->apply($grid, new Container()); + $layout = new DataView(function() use ($grid){ + return "
+
$grid
+
"; + }); + return $layout->render(); + } + } \ No newline at end of file