2

I'm new to symfony and web development in general. I need to retrieve my entity information and iterate my table instead of the statically added list "items" and I don't know how to get it inside JavaScript block. This is in order to implement a dynamic pagination. I hope I was clear.

This is the code that I want to change:

const list_items = [
    "Item 1",
    "Item 2",
    "Item 3",
    "Item 4",
    "Item 5",
    "Item 6",
    "Item 7",
    "Item 8",
    "Item 9",
    "Item 10",
    "Item 11",
    "Item 12",
    "Item 13",
    "Item 14",
    "Item 15",
    "Item 16",
    "Item 17",
    "Item 18",
    "Item 19",
    "Item 20",
    "Item 21",
    "Item 22"
];

const list_element = document.getElementById('list');
const pagination_element = document.getElementById('pagination');

let current_page = 1;
let rows = 5;

function DisplayList (items, wrapper, rows_per_page, page) {
    wrapper.innerHTML = "";
    page--;

    let start = rows_per_page * page;
    let end = start + rows_per_page;
    let paginatedItems = items.slice(start, end);

    for (let i = 0; i < paginatedItems.length; i++) {
        let item = paginatedItems[i];

        let item_element = document.createElement('div');
        item_element.classList.add('item');
        item_element.innerText = item;
        
        wrapper.appendChild(item_element);
    }
}

function SetupPagination (items, wrapper, rows_per_page) {
    wrapper.innerHTML = "";

    let page_count = Math.ceil(items.length / rows_per_page);
    for (let i = 1; i < page_count + 1; i++) {
        let btn = PaginationButton(i, items);
        wrapper.appendChild(btn);
    }
}

function PaginationButton (page, items) {
    let button = document.createElement('button');
    button.innerText = page;

    if (current_page == page) button.classList.add('active');

    button.addEventListener('click', function () {
        current_page = page;
        DisplayList(items, list_element, rows, current_page);

        let current_btn = document.querySelector('.pagenumbers button.active');
        current_btn.classList.remove('active');

        button.classList.add('active');
    });

    return button;
}

DisplayList(list_items, list_element, rows, current_page);
SetupPagination(list_items, pagination_element, rows);

and this is my Entity:

<?php

namespace App\Entity;

use App\Repository\TeamsRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass=TeamsRepository::class)
 */
class Teams
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $teamName;

    /**
     * @ORM\Column(type="string", length=3)
     * @Assert\NotBlank
     * @Assert\Length(
     *      min = 3,
     *      max = 3,
     *      minMessage = "Your team tag must be at least {{ limit }} characters long",
     *      maxMessage = "Your team tag cannot be longer than {{ limit }} characters"
     * )
     */
    private $teamTag;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Email(
     *     message = "The email '{{ value }}' is not a valid email."
     * )
     */
    private $teamMail;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $teamReg;


    /**
     * @ORM\OneToMany(targetEntity=TeamMates::class, mappedBy="team", orphanRemoval=true)
     */
    private $teamMates;

    /**
     * @ORM\OneToMany(targetEntity=Matches::class, mappedBy="team1")
     */
    private $matches;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $teamLogo;

    public function __construct()
    {
        $this->matches = new ArrayCollection();
        $this->teamMates = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTeamName(): ?string
    {
        return $this->teamName;
    }



    public function setTeamName(string $teamName): self
    {
        $this->teamName = $teamName;

        return $this;
    }

    public function getTeamTag(): ?string
    {
        return $this->teamTag;
    }

    public function setTeamTag(string $teamTag): self
    {
        $this->teamTag = $teamTag;

        return $this;
    }

    public function getTeamMail(): ?string
    {
        return $this->teamMail;
    }

    public function setTeamMail(string $teamMail): self
    {
        $this->teamMail = $teamMail;

        return $this;
    }

    public function getTeamReg(): ?string
    {
        return $this->teamReg;
    }

    public function setTeamReg(string $teamReg): self
    {
        $this->teamReg = $teamReg;

        return $this;
    }

    /**
     * @return Collection<int, Matches>
     */
    public function getMatches(): Collection
    {
        return $this->matches;
    }

    public function addMatch(Matches $match): self
    {
        if (!$this->matches->contains($match)) {
            $this->matches[] = $match;
            $match->addTeam($this);
        }

        return $this;
    }

    public function removeMatch(Matches $match): self
    {
        if ($this->matches->removeElement($match)) {
            $match->removeTeam($this);
        }

        return $this;
    }

    /**
     * @return Collection<int, TeamMates>
     */
    public function getTeamMates(): Collection
    {
        return $this->teamMates;
    }

    public function addTeamMate(TeamMates $teamMate): self
    {
        if (!$this->teamMates->contains($teamMate)) {
            $this->teamMates[] = $teamMate;
            $teamMate->setTeam($this);
        }

        return $this;
    }

    public function removeTeamMate(TeamMates $teamMate): self
    {
        if ($this->teamMates->removeElement($teamMate)) {
            // set the owning side to null (unless already changed)
            if ($teamMate->getTeam() === $this) {
                $teamMate->setTeam(null);
            }
        }

        return $this;
    }

    public function getTeamLogo(): ?string
    {
        return $this->teamLogo;
    }

    public function setTeamLogo(string $teamLogo): self
    {
        $this->teamLogo = $teamLogo;

        return $this;
    }
}
2
  • 1
    Are you making a request to the PHP file from somewhere in your JavaScript? Commented Apr 24, 2022 at 20:11
  • What is the difference between doing this vs just using Twig with Symfony's forms? Also, where are you making a call to Symfony from your JS? You need a way to get your actual data to Javascript. Commented Apr 24, 2022 at 20:28

1 Answer 1

1

Doing this with JS:

The first thing that you're going to need to do is somehow get your data from Symfony to your Javascript front-end. There are many ways to do this and typically people use front-end frameworks. If we're going to be going Vanilla with it you could look into use XMLHTTPRequest to make a request to your Symfony backend.

For your Symfony side, since you're using JS you're going to want to convert the data you want to give your front-end into something that Javascript can understand. This is accomplished by using what is called JSON. You could do this by doing something like this:

<?php 

namespace App\Controller; 

use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

Class YourController extends AbstractController {

        /**
         * @Route("/my-route", methods={"GET"})
         */
        public function IndexAction(Request $request){
            $myDataFromSomewhere = ....; 
            $response = new Response(json_encode($myDataFromSomewhere), 200);
            return $response; 
        }
}

From there you await for the result from your XMLHttpRequest and convert it into Javascript objects by doing something like:


JSON.parse(myDataFromTheGreatBeyond);

With that you'll be able to work with it within your Javascript code.

Please note that I haven't actually tested any of this code. It's just something I've spitball together to give you the general concept of getting you data from point A to Point B. Also that with pagination this gets much more intricate by creating your own queries with the Query Builder built into doctrine.

For example, I built an entire QueryHelper class to help put my queries together when I send request from my front-end to Symfony. My pagination method looks something like this:

        public function paginationQuery($qb, $request){
            if($request->query->has("page") && $request->query->has("show")){
                //Convert to integer value to protect from SQL Injection
                $sanPage = intval($request->get("page")) ?: 1;
                $sanShow = intval($request->get("show")) ?: 10;
                $first = 0;
                if($sanPage > 1 ){
                    $sanPage --;
                    $first = $sanShow * $sanPage;
                }
                $qb->setFirstResult($first);
                $qb->setMaxResults($sanShow);
            };
            return $qb;
        }

The reason why we have things like pagination is to reduce load time for heavier records that we would need to call. Not all data should be called all the time, or really usually never. It's more of a back-end task rather than the front-end. The front-end just needs to specify what page it wants and how many records to show. The real magic happens on the Symfony side.

Pagination is a good performance booster when you start working with records that have thousands of relationships that turn into thousands of records being returned by the database with more complex queries.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.