Skip to content

Commit

Permalink
DetailsRow & AjaxDetailsRow components added
Browse files Browse the repository at this point in the history
  • Loading branch information
Nayjest committed Mar 10, 2016
1 parent 7a33941 commit 5c2e50d
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/Component/AjaxDetailsRow.php
@@ -0,0 +1,59 @@
<?php

namespace ViewComponents\Grids\Component;

use ViewComponents\ViewComponents\Component\DataView;
use ViewComponents\ViewComponents\Resource\ResourceManager;

class AjaxDetailsRow extends DetailsRow
{

protected $urlGenerator;

public function __construct(callable $urlGenerator, ResourceManager $resourceManager = null)
{
parent::__construct(new DataView(null, function ($url) {
return "<div data-details-container='1' data-details-url='$url'></div>";
}), $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"));
}
});
';
}
}
92 changes: 92 additions & 0 deletions src/Component/DetailsRow.php
@@ -0,0 +1,92 @@
<?php

namespace ViewComponents\Grids\Component;

use RuntimeException;
use ViewComponents\Grids\Grid;
use ViewComponents\ViewComponents\Base\Compound\PartInterface;
use ViewComponents\ViewComponents\Base\Compound\PartTrait;
use ViewComponents\ViewComponents\Base\DataViewComponentInterface;
use ViewComponents\ViewComponents\Base\Html\TagInterface;
use ViewComponents\ViewComponents\Component\Compound;
use ViewComponents\ViewComponents\Component\DataView;
use ViewComponents\ViewComponents\Resource\ResourceManager;
use ViewComponents\ViewComponents\Service\Services;

class DetailsRow extends SolidRow implements PartInterface
{
use PartTrait {
PartTrait::attachToCompound as private attachToCompoundInternal;
}

const ID = 'details_row';

protected $view;
/** @var ResourceManager */
private $resourceManager;
private $jquery;

public function __construct(DataViewComponentInterface $view, ResourceManager $resourceManager = null)
{
parent::__construct();
$this->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('<tr style="display: none"></tr>'));

}

protected function getScript()
{
$source = $this->getScriptSource();
return new DataView("<script>jQuery(function(){ $source });</script>");
}

protected function getScriptSource()
{
return '
jQuery(\'tr[data-row-with-details="1"]\').click(function() {
jQuery(this).next().toggle(\'slow\');
});
';
}
}
69 changes: 69 additions & 0 deletions tests/webapp/Controller.php
Expand Up @@ -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;
Expand Down Expand Up @@ -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 "<div class='panel panel-default'>
<div class='panel-body'>$grid</div>
</div>";
});
return $layout->render();
}

}

0 comments on commit 5c2e50d

Please sign in to comment.