contributte / datagrid

:muscle: DataGrid for Nette Framework: filtering, sorting, pagination, tree view, table view, translator, etc
https://contributte.org/packages/contributte/datagrid/
MIT License
287 stars 189 forks source link

Doctrine & TreeView #826

Open xpackal5 opened 4 years ago

xpackal5 commented 4 years ago

Hi treeview does not work with doctrine

My Entity

class MaterialCategory implements IEntity
{
    use SmartObject;
    use TId;
    use TName;
    use TSlug;

    /**
     * @var MaterialCategory|null
     * @ORM\ManyToOne(targetEntity="MaterialCategory", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
     */
    private $parent;

    /**
     * @var Collection
     * @ORM\OneToMany(targetEntity="MaterialCategory", mappedBy="parent")
     */
    private $children;

    /**
     * @ORM\OneToMany(targetEntity="Material", mappedBy="category",cascade={"all"})
     */
    private $material;

    /**
     * MaterialCategory constructor.
     */
    public function __construct()
    {
        $this->children = new ArrayCollection();
        $this->material = new ArrayCollection();
    }

    /**
     * @return MaterialCategory|null
     */
    public function getParent(): ?MaterialCategory
    {
        return $this->parent;
    }

    /**
     * @param MaterialCategory|null $parent
     * @return $this
     */
    public function setParent(?MaterialCategory $parent)
    {
        $this->parent = $parent;
        return $this;
    }

    /**
     * @return Collection
     */
    public function getChildren(): Collection
    {
        return $this->children;
    }
}

DQL

SELECT MaterialMaterialCategory FROM app\modules\Materials\entities\MaterialCategory MaterialMaterialCategory WHERE MaterialMaterialCategory.parent IS NULL

Datagrid show only root rows. hasChildrenCallback and getChildrenCallback never run (callbacks use $entity->getChildren()

mabezdek commented 4 years ago

@xpackal5 Can you add your presenter code, where you inicializing the tree view?

xpackal5 commented 4 years ago

Hi i update ublaboo/datagrid and have different problem. Datasource of grid js QueryBuilder but getChildrenCallback returns Collection of children entities and hasChildrenCallback returns true/false if entity has children or not. My DQL of QueryBuilder is "SELECT InventoryLocation FROM app\modules\Inventory\entities\Location InventoryLocation WHERE InventoryLocation.parent IS NULL". Root row os show, but if I click to open arrow (to show children row), root row disapear and only children row shown, but without closin arrow.

I think, thaht missing left join i problem but if i create query builder with join (playground inspired) doctrine throws query exception and tell me that subquery are not allowed (DQL: SELECT InventoryLocation FROM app\modules\Inventory\entities\Location InventoryLocation LEFT JOIN (SELECT COUNT(l.id) AS l.count, l.parent FROM app\modules\Inventory\entities\Location l GROUP BY l.parent) ll ON ll.parent = l.id WHERE InventoryLocation.parent IS NULL ORDER BY InventoryLocation.id ASC)...

Česky: Kliknu na otevření potomků v treeview, otevřou se, ale zmizí rodiče a není uzavírací ikonka.

lukyrys commented 6 months ago

4 years old topic but bug still here. I have same problem with doctrine and treeview

L1AMJeL

    public function createComponentGrid(): DataGrid
    {
        $grid = new DataGrid();

        $grid->setDataSource($this->entityManager->getRepository(Stock::class)->createQueryBuilder('er')); // Doctrine query builder

        $grid->setSortable();

        $grid->setTreeView([$this, 'getChildren'], 'hasChildren');

        $grid->addColumnText('name', 'Name');
        $grid->addColumnText('desc', 'Name2', 'desc');
        $grid->addColumnText('id', 'Id')
            ->setAlign('center');

        $columnStatus = $grid->addColumnStatus('status', 'Status');

        $columnStatus
            ->addOption('active', 'Active')
            ->endOption()
            ->addOption('inactive', 'Inactive')
            ->setClass('btn-warning')
            ->endOption()
            ->addOption('deleted', 'Deleted')
            ->setClass('btn-danger')
            ->endOption()
            ->setSortable();
        $columnStatus->onChange[] = [$this, 'changeStatus'];

        $grid->addAction('edit', 'Edit', 'edit!')
            ->setIcon('pencil pencil-alt')
            ->setClass('btn btn-xs btn-default btn-secondary ajax')
            ->setTitle('Edit');

        $grid->addAction('delete', '', 'delete!')
            ->setIcon('trash')
            ->setTitle('Delete')
            ->setClass('btn btn-xs btn-danger ajax')
            ->setConfirmation(
                new StringConfirmation('Do you really want to delete example %s?', 'name')
            );

        return $grid;
    }

    /**
     * @param mixed $parentCategoryId
     */
    public function getChildren($parentCategoryId)
    {
        $stock = $this->entityManager->getRepository(Stock::class)->find($parentCategoryId);
        $o = $this->entityManager->getRepository(StockItem::class)->findBy([
            'stock' => $stock
        ]);

        return $o;
    }