I am working with Symfony2 and Twig: I have a table that is set up to handle hierarchical data with Doctrine. It is a list of categories with parent->children->sub_children->sub_sub_children etc... Many many variations.
I am able to display them on the page like so, but the issue is there is no "indentation" to show which element belongs to what parent or child or child child etc etc.
<table class="table" id="tableList">
<thead>
<tr>
<th>Category Name</th>
</tr>
</thead>
<tbody>
{% for productCategory in productCategories %}
<tr>
<td>{{ productCategory.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
I'd like the list to look something like this:
Parent
Child
Child
Parent
Child
Parent
Child
Child
Child
Instead of like this:
Parent
Child
Child
Child
Parent
Child
Parent
etc.
etc.
Original Entity:
<?php
namespace WIC\ProductCategoryBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use WIC\CommonBundle\DoctrineExtensions\Mapping\Annotation as Common;
use Symfony\Component\Validator\Constraints as Assert;
/**
* ProductCategory
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
* @Gedmo\Tree(type="nested")
* @Common\Loggable(logEntryClass="WIC\ProductCategoryBundle\Entity\ProductCategoryLog")
* @Common\Accountable
* @Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class ProductCategory
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
* @Common\Versioned
* @Assert\NotBlank(message="Location Name Cannot Be Left Blank.")
*/
protected $name;
/**
* @Gedmo\TreeLeft
* @ORM\Column(name="lft", type="integer")
*/
protected $lft;
/**
* @Gedmo\TreeLevel
* @ORM\Column(name="lvl", type="integer")
*/
protected $lvl;
/**
* @Gedmo\TreeRight
* @ORM\Column(name="rgt", type="integer")
*/
protected $rgt;
/**
* @Gedmo\TreeRoot
* @ORM\Column(name="root", type="integer", nullable=true)
*/
protected $root;
/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="ProductCategory", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $parent;
/**
* @ORM\OneToMany(targetEntity="ProductCategory", mappedBy="parent")
* @ORM\OrderBy({"lft" = "ASC"})
*/
protected $children;
/**
* @ORM\ManyToMany(targetEntity="WIC\ProductBundle\Entity\Product", mappedBy="productCategories", cascade={"persist"})
*/
protected $products;
/**
* @ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
* @ORM\JoinColumn(name="created_by", referencedColumnName="id")
* @Common\Blameable(on="create")
*/
private $createdBy;
/**
* @ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
* @ORM\JoinColumn(name="updated_by", referencedColumnName="id")
* @Common\Blameable(on="update")
*/
private $updatedBy;
/**
* @ORM\ManyToOne(targetEntity="WIC\AccountBundle\Entity\Account", inversedBy="productCategorys", cascade={"remove","persist"})
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
* @Common\Versioned
* @Common\Blameable(on="create")
*/
protected $account;
/**
* @var datetime $created
*
* @Common\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @var datetime $updated
*
* @Common\Timestampable(on="update")
* @ORM\Column(type="datetime", nullable=true)
*/
protected $updated;
/**
* @ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
private $deletedAt;
public function __construct()
{
$this->products = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return ProductCategory
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
public function setLvl(ProductCategory $lvl = null)
{
$this->lvl = $lvl;
}
public function getLvl()
{
return $this->lvl;
}
public function setParent(ProductCategory $parent = null)
{
$this->parent = $parent;
}
public function getParent()
{
return $this->parent;
}
/**
* Set account
*
* @param \WIC\AccountBundle\Entity\Account $account
* @return User
*/
public function setAccount(\WIC\AccountBundle\Entity\Account $account = null)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* @return \WIC\AccountBundle\Entity\Account
*/
public function getAccount()
{
return $this->account;
}
/**
* Add product
*
* @param \WIC\ProductBundle\Entity\Product $product
* @return Product
*/
public function addProduct(\WIC\ProductBundle\Entity\Product $product)
{
$this->products[] = $product;
return $this;
}
/**
* Remove product
*
* @param \WIC\ProductBundle\Entity\Product $product
*/
public function removeProduct(\WIC\ProductBundle\Entity\Product $product)
{
$this->products->removeElement($product);
}
/**
* Set products
*
* @return Product
*/
public function setProducts($products)
{
$this->products = $products;
return $this;
}
/**
* Get products
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
/**
* Set updated
*
* @param \DateTime $updated
* @return User
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* @return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Set deletedAt
*
* @param \DateTime $deletedAt
* @return User
*/
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* Get deletedAt
*
* @return \DateTime
*/
public function getDeletedAt()
{
return $this->deletedAt;
}
public function getOptionLabel()
{
return str_repeat(
html_entity_decode(' ', ENT_QUOTES, 'UTF-8'),
($this->getLvl() + 0 ) * 3
) . $this->getName();
}
}
Anyone know how to accomplish this?
Thanks so much!
Just a little upgrade to previous answer.
This would build better-looking html.
The indentation will be much easier using an unordered list because they automatically get indented by the browser's default user-agent stylesheet. This should do it:
Add this method to your ProductCategory entity:
and this in your twig template