Partage
  • Partager sur Facebook
  • Partager sur Twitter

symfony : boucle twig sur collection

entity Product lier OnTomany avec entity Attachemnt

Sujet résolu
    20 mai 2022 à 13:37:32

    Bonjour à tous,

    J’ai construi un multiUploade d’images, pour telechager plusieur image lier a un product.

    Pour ce faire j’ai utiliser, VichUploaderBundle.

    Tout fonctionne bien dans mon admin les fichier ce telecharge bien dans le fichier choisie.

    Le fichier service.yaml

    parameters:
        attachments : /images/attachments



    le fichier vich_uploader.yaml

    vich_uploader:
        db_driver: orm
    
        mappings:
           attachments:
               uri_prefix: '%attachments%'
               upload_destination: '%kernel.project_dir%/public%attachments%'
               namer: Vich\UploaderBundle\Naming\SmartUniqueNamer



    mon productCrudController

    <?php
    
    namespace App\Controller\Admin;
    
    use App\Entity\Product;
    use App\Form\AttachmentType;
    use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
    use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
    use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
    use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\MoneyField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\SlugField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
    use Vich\UploaderBundle\Form\Type\VichImageType;
    
    class ProductCrudController extends AbstractCrudController
    {
        public static function getEntityFqcn(): string
        {
            return Product::class;
        }
    
    
        public function configureFields(string $pageName): iterable
        {
            $imageFile = ImageField::new('thumbnailFaile')->setFormType(VichImageType::class);
            $image = ImageField::new('thumbnail')->setBasePath('images/thumbnails');
            return [
                TextField::new('name'),
                SlugField::new('slug')->setTargetFieldName('name'),
                ImageField::new('illustration', 'illustration: l : 800px par h : 1200px',)
                    ->setBasePath('uploads/')
                    ->setUploadDir('public/uploads')
                    ->setUploadedFileNamePattern('[randomhash].[extension]')
                    ->setRequired(false),
                CollectionField::new('attachments')
    
                    ->setEntryType(AttachmentType::class)
                    ->setFormTypeOption('by_reference', false)
                    ->onlyOnForms(),
                CollectionField::new('attachments')
                    ->setTemplatePath('images.html.twig')
                    ->onlyOnDetail(),
                TextField::new('subtitle'),
                TextareaField::new('description'),
                BooleanField::new('isBest'),
    
                /*BooleanField::new('isBest'),*/
                MoneyField::new('price')->setCurrency('EUR'),
                AssociationField::new('category')
            ];
    
            if ($pageName == Crud::PAGE_INDEX || $pageName == Crud::PAGE_DETAIL) {
                $fields[] = $image;
            } else {
                $fields[] = $imageFile;
            }
            return $fields;
    
        }
        Public function configureActions(Actions $actions): Actions
        {
            return $actions->add('index','detail');
        }
    
    }
    



    la template lier dans le ProductCrudController

    <div class="form-widget">
        {% for image in field.value %}
    
    
    
    
                <a href="#" class="ea-lightbox-thumbnail" data-ea-lightbox-content-selector="#ea-lightbox-{{ image.id }}">
                    <img src="/images/attachments/{{ image.image }}" class="img-fluid"style="width:150px ">
                </a>
    
                <div id="ea-lightbox-{{ image.id }}" class="ea-lightbox">
                    <img src="/images/attachments/{{ image.image }}">
                </div>
    
    
    
        {% endfor %}
    </div>
    

    entity attachment

    <?php
    
    namespace App\Entity;
    
    use App\Repository\AttachmentRepository;
    use Doctrine\ORM\Mapping as ORM;
    
    
    use Symfony\Component\HttpFoundation\File\File;
    use Symfony\Component\Validator\Constraints as Assert;
    
    use Vich\UploaderBundle\Mapping\Annotation as Vich;
    
    /**
     * @ORM\Entity(repositoryClass=AttachmentRepository::class)
     * @Vich\Uploadable()
     */
    class Attachment
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * @ORM\Column(type="string", length=255)
         *
         */
        private $image;
    
        /**
         *
         * @Vich\UploadableField(mapping="attachments", fileNameProperty="image")
         * @var File
         * @Assert\Image(mimeTypes={"image/png", "image/jpeg", "image/jpg", "image/gif"})
         */
        private $imageFile;
    
        /**
         * @ORM\Column(type="datetime")
         */
        private $createAt;
    
        /**
         * @ORM\Column(type="datetime")
         */
        private $updateAt;
    
    
    
        /**
         * @ORM\ManyToOne(targetEntity=Product::class, inversedBy="attachments")
         */
        private $product;
    
    
    
        public function __construct()
        {
            $this->createAt = new \DateTime();
            $this->updateAt = new \DateTime();
        }
    
        public function getId(): ?int
        {
            return $this->id;
        }
    
    
    
        public function getImageFile(): ?File
        {
            return $this->imageFile;
        }
    
        /**
         * @param File|null $image
         * @return void
         */
        public function setImageFile( File $image = null): void
        {
            $this->imageFile = $image;
    
            if($image){
                $this->updateAt = new \DateTime('now');
            }
        }
    
        public function getCreateAt(): ?\DateTimeInterface
        {
            return $this->createAt;
        }
    
        public function setCreateAt(\DateTimeInterface $createAt): self
        {
            $this->createAt = $createAt;
    
            return $this;
        }
    
        public function getProduct(): ?Product
        {
            return $this->product;
        }
    
        public function setProduct(?Product $product): self
        {
            $this->product = $product;
    
            return $this;
        }
    
        public function getUpdateAt(): ?\DateTimeInterface
        {
            return $this->updateAt;
        }
    
        public function setUdateAt(\DateTimeInterface $updateAt): self
        {
            $this->updateAt = $updateAt;
    
            return $this;
        }
    
        public function getImage(): ?string
        {
            return $this->image;
        }
    
        public function setImage(?string $image): self
        {
            $this->image = $image;
    
            return $this;
        }
    }
    


    Entity Product

    <?php
    
    namespace App\Entity;
    
    use App\Repository\ProductRepository;
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\HttpFoundation\File\File;
    
    
    /**
     * @ORM\Entity(repositoryClass=ProductRepository::class)
     */
    class Product
    {
    
    
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * @ORM\Column(type="string", length=255)
         */
        private $name;
    
        /**
         * @ORM\Column(type="string", length=255)
         */
        private $slug;
    
        /**
         * @ORM\Column(type="string", length=255)
         */
        private $illustration;
    
        /**
         * @ORM\Column(type="string", length=255)
         */
        private $subtitle;
    
        /**
         * @ORM\Column(type="text")
         */
        private $description;
    
        /**
         * @ORM\Column(type="float")
         */
        private $price;
    
        /**
         * @ORM\ManyToOne(targetEntity=Category::class, inversedBy="products")
         * @ORM\JoinColumn(nullable=false)
         */
        private $category;
    
        /**
         * @ORM\OneToMany(targetEntity=ProductDimensionStock::class, mappedBy="product")
         */
        private $productDimensionStocks;
    
        /**
         * @ORM\Column(type="boolean")
         */
        private $isBest;
    
        /**
         *
         * @var string
         * @ORM\OneToMany(targetEntity=Attachment::class, mappedBy="product", cascade={"all","persist", "remove"})
         *
         */
        private $attachments;
    
    
    
        public function __construct()
        {
            $this->productDimensionStocks = new ArrayCollection();
            $this->attachments = new ArrayCollection();
    
        }
    
        public function getId(): ?int
        {
            return $this->id;
        }
    
        public function getName(): ?string
        {
            return $this->name;
        }
    
        public function setName(string $name): self
        {
            $this->name = $name;
    
            return $this;
        }
    
        public function getSlug(): ?string
        {
            return $this->slug;
        }
    
        public function setSlug(string $slug): self
        {
            $this->slug = $slug;
    
            return $this;
        }
    
        public function getIllustration(): ?string
        {
            return $this->illustration;
        }
    
        public function setIllustration(string $illustration): self
        {
            $this->illustration = $illustration;
    
            return $this;
        }
    
        public function getSubtitle(): ?string
        {
            return $this->subtitle;
        }
    
        public function setSubtitle(string $subtitle): self
        {
            $this->subtitle = $subtitle;
    
            return $this;
        }
    
        public function getDescription(): ?string
        {
            return $this->description;
        }
    
        public function setDescription(string $description): self
        {
            $this->description = $description;
    
            return $this;
        }
    
        public function getPrice(): ?float
        {
            return $this->price;
        }
    
        public function setPrice(float $price): self
        {
            $this->price = $price;
    
            return $this;
        }
    
        public function getCategory(): ?Category
        {
            return $this->category;
        }
    
        public function setCategory(?Category $category): self
        {
            $this->category = $category;
    
            return $this;
        }
    
    
        public function __toString(){
            return $this->getName();
    
    
        }
    
    
        /**
         * @return Collection|ProductDimensionStock[]
         */
        public function getProductDimensionStocks(): Collection
        {
            return $this->productDimensionStocks;
        }
    
        public function addProductDimensionStock(ProductDimensionStock $productDimensionStock): self
        {
            if (!$this->productDimensionStocks->contains($productDimensionStock)) {
                $this->productDimensionStocks[] = $productDimensionStock;
                $productDimensionStock->setProduct($this);
            }
    
            return $this;
        }
    
        public function removeProductDimensionStock(ProductDimensionStock $productDimensionStock): self
        {
            if ($this->productDimensionStocks->removeElement($productDimensionStock)) {
                // set the owning side to null (unless already changed)
                if ($productDimensionStock->getProduct() === $this) {
                    $productDimensionStock->setProduct(null);
                }
            }
    
            return $this;
        }
    
        public function getIsBest(): ?bool
        {
            return $this->isBest;
        }
    
        public function setIsBest(bool $isBest): self
        {
            $this->isBest = $isBest;
    
            return $this;
        }
    
        /**
         *
         * @return Collection<int, Attachment>
         */
        public function getAttachments(): Collection
        {
            return $this->attachments;
        }
    
        public function addAttachment(Attachment $attachment): self
        {
            if (!$this->attachments->contains($attachment)) {
                $this->attachments[] = $attachment;
                $attachment->setProduct($this);
            }
    
            return $this;
        }
    
        public function removeAttachment(Attachment $attachment): self
        {
            if ($this->attachments->removeElement($attachment)) {
                // set the owning side to null (unless already changed)
                if ($attachment->getProduct() === $this) {
                    $attachment->setProduct(null);
                }
            }
    
            return $this;
        }
    
    
    
    
    
    
    
    
    }
    



    Et mon problème ce citue losque j’affiche le produit seule, je veux faire une boucle dans un carrousel bootstrap pour faire défiler les images lier a ce produit :

    ma page twig (show.html.twig)

    {% extends 'base.html.twig' %}
    
    {% block title %}{{ product.name }} - Yggdrasil{% endblock %}
    
    {% block content %}
    
    </div>
    <div class="hero-wrap hero-bread" style="background-image: url({{ asset('assets/images/bg_6.jpg') }});margin-top: -10px;">
        <div class="container">
            <div class="row no-gutters slider-text align-items-center justify-content-center">
                <div class="col-md-9 ftco-animate text-center">
                    <p class="breadcrumbs"><span class="mr-2"><a href="  {{ path('home') }}">Home</a></span> <span>Boutique</span></p>
                    <h1 class="mb-0 bread">Nos produits</h1>
                </div>
            </div>
        </div>
    </div>
    
    
        <style>
            input{
                border:none;
                width: 100%;
            }
            input.titre{
                width: 100%;
            }
            textarea{
                border:none;
                resize : none;
    
            }
            select{
                position: relative;
                width: 350px;
                height: 45px;
                overflow: hidden;
                border-radius: 5px;
                border: 1px solid #CED4DA;
                cursor: pointer;
            }
    
        </style>
    
        <section class="ftco-section">
            <div class="container">
                {% if app.session.flashBag.has('success') %}
                    <div class="alert alert-success">
                        {% for msg in app.session.flashBag.get('success') %}
                            {{ msg }}
                        {% endfor %}
                    </div>
                {% endif %}
                <div class="row">
                    {% for message in  app.flashes('notice')%}
                        <div class=" alert alert-info">{{ message }}</div>
                    {% endfor %}
                    <div class="col-lg-6 mb-5 ftco-animate">
    
                        <div id="carouselExampleFade" class="carousel slide carousel-fade" data-bs-ride="carousel">
                            <div class="carousel-inner">
                                {% for attachment in product.attachments %}
                                    {{ dump (attachment) }}
                                <div class="carousel-item active">
    
                                    <img src="/images/attachments/{{ attachment.image }}" class="img-fluid"">
                                </div>
                                {% endfor %}
    
                            </div>
                            <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="prev">
                                <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                <span class="visually-hidden">Previous</span>
                            </button>
                            <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="next">
                                <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                <span class="visually-hidden">Next</span>
                            </button>
                        </div>
                        <a href="/uploads/{{ product.illustration }}" class="image-popup"><img src="/uploads/{{ product.illustration }}" class="img-fluid" alt="{{ product.name }}"></a>
                    </div>
                    <div class="col-lg-6 product-details pl-md-5 my-auto ftco-animate">
                            <h3> {{ product.name }}</h3>
                        <p>{{ product.subtitle }}</p>
                        <p class="price"><span>{{ (product.price / 100)|number_format(2,',', '.')}} €</span></p>
                        <hr>
                        <p>
    
                                      {{ product.description }}
    
                        </p>
    
                           <h5> Choisir la dimension de votre bracelet :</h5>
                        {{ form_start(form, {'attr': {'class': 'mt-4 p-4 bg-light'}}) }}
                        <div class="form-group">
                            {{ form_label(form.dimension) }}
                            {{ form_widget(form.dimension, {
                                'attr': {
                                    'class': 'form-control ' ~ (form.dimension.vars.valid ? '' : 'is-invalid')
                                }
                            }) }}
                            <div class="invalid-feedback">
                                {{ form_errors(form.dimension) }}
                            </div>
                        </div>
                        <div class="form-group">
                            {{ form_label(form.quantity) }}
                            {{ form_widget(form.quantity, {
                                'attr': {
                                    'class': 'form-control ' ~ (form.quantity.vars.valid ? '' : 'is-invalid')
                                }
                            }) }}
                            <div class="invalid-feedback">
                                {{ form_errors(form.quantity) }}
                            </div>
                        </div>
    
                        {{ form_end(form) }}
    
    
    
    
    
                    </div>
                </div>
            </div>
        </section>
        <section class="ftco-section bg-light">
            <div class="container">
                <div class="row justify-content-center mb-3 pb-3">
                    <div class="col-md-12 heading-section text-center ftco-animate">
                        <h2 class="mb-4">Best Sellers</h2>
                        <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia</p>
                    </div>
                </div>
            </div>
            <div class="container">
                <div class="row">
                    {% for product in products %}
                        <div class="col-sm-6 col-md-6 col-lg-3 ftco-animate">
                            {% include 'product/single_product.html.twig' %}
                        </div>
                    {% endfor %}
    
                </div>
            </div>
        </section>
    {% endblock %}
    

    le résultat :

    j'ai les deux boutons précedent et suivent et l'image placer dans illustration du product mais j'ai aucune images lier a attachment qui aparaissent.

    je pense que ma boucle n'est pas bonne mais je trouve pas ce qui ne vas pas.

    Merci pour votre aide  ;)

    • Partager sur Facebook
    • Partager sur Twitter
      20 mai 2022 à 13:40:37

      Salut

      Il serait très intéressant de voir le HTML généré (accessible avec Ctrl + U depuis le navigateur sur la page qui pose problème) pour le carrousel plutôt que le Twig.

      Je note néanmoins que là, toutes les images auront la classe active, il faudrait ajouter un test if loop.first pour qu'elle ne soit que sur la première image.

      • Partager sur Facebook
      • Partager sur Twitter
        20 mai 2022 à 14:03:45

        Ymox a écrit:

        Salut

        Il serait très intéressant de voir le HTML généré (accessible avec Ctrl + U depuis le navigateur sur la page qui pose problème) pour le carrousel plutôt que le Twig.

        Je note néanmoins que là, toutes les images auront la classe active, il faudrait ajouter un test if loop.first pour qu'elle ne soit que sur la première image.


        Bonjour Ymox,

        Effectivement le code html génégé pour le carrousel est vide :

        <div id="carouselExampleFade" class="carousel slide carousel-fade" data-bs-ride="carousel">
                                <div class="carousel-inner">
                                    
                                </div>
                                <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="prev">
                                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                    <span class="visually-hidden">Previous</span>
                                </button>
                                <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="next">
                                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                    <span class="visually-hidden">Next</span>
                                </button>
                            </div>

        Du coup je comprend encore moins lol ! help



        • Partager sur Facebook
        • Partager sur Twitter
          20 mai 2022 à 14:08:43

          Du coup je comprend encore moins lol !

          lol peut vouloir désigner League of Legends ou Laughing Out Loud.


          Manifestement, les images que tu uploades avec le formulaire admin ne sont pas liées à ton produit. Regarde ce qu'il en est en base, je ne serais pas surpris que la colonne qui devrait contenir l'ID du produit est vide, je me trompe ?

          • Partager sur Facebook
          • Partager sur Twitter
            20 mai 2022 à 14:55:15

            Alors la je suis une nouille ! J' ai cliquer sur les produits que j'avais rentrer quand le multiUpload ne fonctionner pas. du coup lorsque je choisie le bon produit qui lui a bien des images lier avec attachment tada... ça marche !

            <div class="carousel-item active">
            
                                            <img src="/images/attachments/1236w-yw5az13m5ns-628678477d6eb238803064.webp" class="img-fluid"">
                                        </div>
                                        
                                    </div>
                                    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="prev">
                                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                        <span class="visually-hidden">Previous</span>
                                    </button>
                                    <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="next">
                                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                        <span class="visually-hidden">Next</span>
                                    </button>
                                </div>

            je fait parfois des erreur stupide sniff !

            Juste si quelqu'un peu m'aider pour la condition ? mici

            Ymox a écrit:

            Salut

            Il serait très intéressant de voir le HTML généré (accessible avec Ctrl + U depuis le navigateur sur la page qui pose problème) pour le carrousel plutôt que le Twig.

            Je note néanmoins que là, toutes les images auront la classe active, il faudrait ajouter un test if loop.first pour qu'elle ne soit que sur la première image.


            Merci ;)





            • Partager sur Facebook
            • Partager sur Twitter
              20 mai 2022 à 15:16:27

              Heu, je t'ai donné directement la condition, il faut simplement l'ajouter dans Twig autour de cette classe active. C'est un "simple" if … endif autour. Tu ne veux pas faire d'essai avant, et nous montrer ce que tu as essayé ?

              • Partager sur Facebook
              • Partager sur Twitter
                20 mai 2022 à 17:43:02

                Ymox a écrit:

                Heu, je t'ai donné directement la condition, il faut simplement l'ajouter dans Twig autour de cette classe active. C'est un "simple" if … endif autour. Tu ne veux pas faire d'essai avant, et nous montrer ce que tu as essayé ?


                Voici ma page show.html.twig

                {% extends 'base.html.twig' %}
                
                {% block title %}{{ product.name }} - Yggdrasil{% endblock %}
                
                {% block content %}
                
                </div>
                <div class="hero-wrap hero-bread" style="background-image: url({{ asset('assets/images/bg_6.jpg') }});margin-top: -10px;">
                    <div class="container">
                        <div class="row no-gutters slider-text align-items-center justify-content-center">
                            <div class="col-md-9 ftco-animate text-center">
                                <p class="breadcrumbs"><span class="mr-2"><a href="  {{ path('home') }}">Home</a></span> <span>Boutique</span></p>
                                <h1 class="mb-0 bread">Nos produits</h1>
                            </div>
                        </div>
                    </div>
                </div>
                
                
                    <style>
                        input{
                            border:none;
                            width: 100%;
                        }
                        input.titre{
                            width: 100%;
                        }
                        textarea{
                            border:none;
                            resize : none;
                
                        }
                        select{
                            position: relative;
                            width: 350px;
                            height: 45px;
                            overflow: hidden;
                            border-radius: 5px;
                            border: 1px solid #CED4DA;
                            cursor: pointer;
                        }
                
                    </style>
                
                    <section class="ftco-section">
                        <div class="container">
                            {% if app.session.flashBag.has('success') %}
                                <div class="alert alert-success">
                                    {% for msg in app.session.flashBag.get('success') %}
                                        {{ msg }}
                                    {% endfor %}
                                </div>
                            {% endif %}
                            <div class="row">
                                {% for message in  app.flashes('notice')%}
                                    <div class=" alert alert-info">{{ message }}</div>
                                {% endfor %}
                                <div class="col-lg-6 mb-5 ftco-animate">
                                    {% if product.attachments is not empty %}
                                         <div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="true">
                
                                                    <ol class="carousel-indicators">
                
                                                            {% for key,attachment in product.attachments %}
                                                                <li data-bs-target="#carouselExampleIndicators" data-slide-to="{{ key }}" {% if key == 0 %} class="active" {% endif%}></li>
                
                
                                                            {% endfor %}
                                                    </ol>
                                             <div class="carousel-inner">
                
                                                    {% for key,attachment in product.attachments %}
                
                                                    <div class="carousel-item {% if key == 0 %}active{% endif %}">
                
                                                        <img src="/images/attachments/{{ attachment.image }}" class="img-fluid"">
                                                    </div>
                                                    {% endfor %}
                                             </div>
                
                                                <a class="carousel-control-prev" role="button" href="#carouselExampleIndicators"  data-bs-slide="prev">
                                                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                
                                                </a>
                                                <a class="carousel-control-next" role="button" href="#carouselExampleIndicators"  data-bs-slide="next">
                                                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                
                                                </a>
                                            </div>
                                    {% else %}
                                        <a href="/uploads/{{ product.illustration }}" class="image-popup"><img src="/uploads/{{ product.illustration }}" class="img-fluid" alt="{{ product.name }}"></a>
                                    {% endif %}
                                </div>
                                <div class="col-lg-6 product-details pl-md-5 my-auto ftco-animate">
                                        <h3> {{ product.name }}</h3>
                                    <p>{{ product.subtitle }}</p>
                                    <p class="price"><span>{{ (product.price / 100)|number_format(2,',', '.')}} €</span></p>
                                    <hr>
                                    <p>
                
                                                  {{ product.description }}
                
                                    </p>
                
                                       <h5> Choisir la dimension de votre bracelet :</h5>
                                    {{ form_start(form, {'attr': {'class': 'mt-4 p-4 bg-light'}}) }}
                                    <div class="form-group">
                                        {{ form_label(form.dimension) }}
                                        {{ form_widget(form.dimension, {
                                            'attr': {
                                                'class': 'form-control ' ~ (form.dimension.vars.valid ? '' : 'is-invalid')
                                            }
                                        }) }}
                                        <div class="invalid-feedback">
                                            {{ form_errors(form.dimension) }}
                                        </div>
                                    </div>
                                    <div class="form-group">
                                        {{ form_label(form.quantity) }}
                                        {{ form_widget(form.quantity, {
                                            'attr': {
                                                'class': 'form-control ' ~ (form.quantity.vars.valid ? '' : 'is-invalid')
                                            }
                                        }) }}
                                        <div class="invalid-feedback">
                                            {{ form_errors(form.quantity) }}
                                        </div>
                                    </div>
                
                                    {{ form_end(form) }}
                
                
                
                
                
                                </div>
                            </div>
                        </div>
                    </section>
                    <section class="ftco-section bg-light">
                        <div class="container">
                            <div class="row justify-content-center mb-3 pb-3">
                                <div class="col-md-12 heading-section text-center ftco-animate">
                                    <h2 class="mb-4">Best Sellers</h2>
                                    <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia</p>
                                </div>
                            </div>
                        </div>
                        <div class="container">
                            <div class="row">
                                {% for product in products %}
                                    <div class="col-sm-6 col-md-6 col-lg-3 ftco-animate">
                                        {% include 'product/single_product.html.twig' %}
                                    </div>
                                {% endfor %}
                
                            </div>
                        </div>
                    </section>
                {% endblock %}
                


                Voila ce que cela donne niveau html généré :

                            <div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="true">
                
                                        <ol class="carousel-indicators">
                
                                                                            <li data-bs-target="#carouselExampleIndicators" data-slide-to="0"  class="active" ></li>
                
                
                                                                            <li data-bs-target="#carouselExampleIndicators" data-slide-to="1" ></li>
                
                
                                                                            <li data-bs-target="#carouselExampleIndicators" data-slide-to="2" ></li>
                
                
                                                                    </ol>
                                        <div class="carousel-inner">
                
                                            
                                                <div class="carousel-item active">
                
                                                    <img src="/images/attachments/product-9-6287a889859ae986543190.png" class="img-fluid"">
                                                </div>
                                            
                                                <div class="carousel-item ">
                
                                                    <img src="/images/attachments/product-8-6287a8898e47b361637837.png" class="img-fluid"">
                                                </div>
                                            
                                                <div class="carousel-item ">
                
                                                    <img src="/images/attachments/product-13-6287a8898ec50193970284.png" class="img-fluid"">
                                                </div>
                                                                    </div>
                
                                        <a class="carousel-control-prev" role="button" href="#carouselExampleIndicators"  data-bs-slide="prev">
                                            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                
                                        </a>
                                        <a class="carousel-control-next" role="button" href="#carouselExampleIndicators"  data-bs-slide="next">
                                            <span class="carousel-control-next-icon" aria-hidden="true"></span>
                
                                        </a>
                                    </div>

                Me reste un souci : quand j'appuis sur les bouton prev next rien ne bouge !!

                Si quelqu'un a une idée ? j'ai peut-être fait une erreur mais je ne vois pas !? Merci ;)

                • Partager sur Facebook
                • Partager sur Twitter
                  20 mai 2022 à 18:18:40

                  Bonjour,

                  Pour info ce qui fonctionne chez moi avec bootstrap 5.x

                  <button class="carousel-control-prev" type="button" data-bs-target="#carouselIndicators" data-bs-slide="prev">
                  	<span class="carousel-control-prev-icon" aria-hidden="true"></span>
                  	<span class="visually-hidden">{{ 'app.button.previous' | trans }}</span>
                  </button>
                  <button class="carousel-control-next" type="button" data-bs-target="#carouselIndicators" data-bs-slide="next">
                  	<span class="carousel-control-next-icon" aria-hidden="true"></span>
                  	<span class="visually-hidden">{{ 'app.button.next' | trans }}</span>
                  </button>

                  Et le data-bs-target doit correspondre à l'id de la div de la modale dont je donne l'exemple ci-dessous :

                  <div id="carouselIndicators" class="carousel slide" data-bs-ride="carousel">

                  En espérant que cela te serve.

                  A+

                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 mai 2022 à 23:55:30

                    Tu pouvais, comme je te l'avais dit avoir fourni, utiliser directement if loop.first, sans avoir besoin d'ajouter cette variable key.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 mai 2022 à 10:42:47

                      monkey3d a écrit:

                      Bonjour,

                      Pour info ce qui fonctionne chez moi avec bootstrap 5.x

                      <button class="carousel-control-prev" type="button" data-bs-target="#carouselIndicators" data-bs-slide="prev">
                      	<span class="carousel-control-prev-icon" aria-hidden="true"></span>
                      	<span class="visually-hidden">{{ 'app.button.previous' | trans }}</span>
                      </button>
                      <button class="carousel-control-next" type="button" data-bs-target="#carouselIndicators" data-bs-slide="next">
                      	<span class="carousel-control-next-icon" aria-hidden="true"></span>
                      	<span class="visually-hidden">{{ 'app.button.next' | trans }}</span>
                      </button>

                      Et le data-bs-target doit correspondre à l'id de la div de la modale dont je donne l'exemple ci-dessous :

                      <div id="carouselIndicators" class="carousel slide" data-bs-ride="carousel">

                      En espérant que cela te serve.

                      A+
                      Bonjour

                      Effectivement c'était un petit souci de version de Bootstrap

                      Voici ma page show :

                      {% extends 'base.html.twig' %}
                      
                      {% block title %}{{ product.name }} - Yggdrasil{% endblock %}
                      
                      {% block content %}
                      
                      </div>
                      <div class="hero-wrap hero-bread" style="background-image: url({{ asset('assets/images/bg_6.jpg') }});margin-top: -10px;">
                          <div class="container">
                              <div class="row no-gutters slider-text align-items-center justify-content-center">
                                  <div class="col-md-9 ftco-animate text-center">
                                      <p class="breadcrumbs"><span class="mr-2"><a href="  {{ path('home') }}">Home</a></span> <span>Boutique</span></p>
                                      <h1 class="mb-0 bread">Nos produits</h1>
                                  </div>
                              </div>
                          </div>
                      </div>
                      
                      
                          <style>
                              input{
                                  border:none;
                                  width: 100%;
                              }
                              input.titre{
                                  width: 100%;
                              }
                              textarea{
                                  border:none;
                                  resize : none;
                      
                              }
                              select{
                                  position: relative;
                                  width: 350px;
                                  height: 45px;
                                  overflow: hidden;
                                  border-radius: 5px;
                                  border: 1px solid #CED4DA;
                                  cursor: pointer;
                              }
                      
                          </style>
                      
                          <div class="container">
                              {% if app.session.flashBag.has('success') %}
                                  <div class="alert alert-success">
                                      {% for msg in app.session.flashBag.get('success') %}
                                          {{ msg }}
                                      {% endfor %}
                                  </div>
                              {% endif %}
                              <div class="row">
                                  {% for message in  app.flashes('notice')%}
                                      <div class=" alert alert-info">{{ message }}</div>
                                  {% endfor %}
                                  <div class="col-lg-6 mb-5 ftco-animate" style="margin-top: 3%">
                      
                                      {% if product.attachments is not empty %}
                                      <div id="myCarousel" class="carousel slide " data-ride="carousel">
                                          <ol class="carousel-indicators">
                                              {% for key,attachment in product.attachments %}
                                              <li data-target="#myCarousel" data-slide-to="{{ key }}" {% if key == 0 %} class="active" {% endif%}></li>
                                              {% endfor %}
                      
                                          </ol>
                                          <div class="carousel-inner">
                                              {% for key,attachment in product.attachments %}
                                              <div class="carousel-item {% if key == 0 %}active{% endif %}">
                                                  <a href="/images/attachments/{{ attachment.image }}" class="image-popup"><img src="/images/attachments/{{ attachment.image }}" class="img-fluid" alt="{{ product.name }}"></a>
                      
                      
                      
                                              </div>
                      
                                              {% endfor %}
                                          </div>
                                          <a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
                                              <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                              <span class="sr-only">Previous</span>
                                          </a>
                                          <a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
                                              <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                              <span class="sr-only">Next</span>
                                          </a>
                                      </div>
                                      {% else %}
                                          <a href="/uploads/{{ product.illustration }}" class="image-popup"><img src="/uploads/{{ product.illustration }}" class="img-fluid" alt="{{ product.name }}"></a>
                                      {% endif %}
                                  </div>
                                  <div class="col-lg-6 product-details pl-md-5 my-auto ftco-animate">
                                      <h3> {{ product.name }}</h3>
                                      <p>{{ product.subtitle }}</p>
                                      <p class="price"><span>{{ (product.price / 100)|number_format(2,',', '.')}} €</span></p>
                                      <hr>
                                      <p>
                      
                                          {{ product.description }}
                      
                                      </p>
                      
                                      <h5> Choisir la dimension de votre bracelet :</h5>
                                      {{ form_start(form, {'attr': {'class': 'mt-4 p-4 bg-light'}}) }}
                                      <div class="form-group">
                                          {{ form_label(form.dimension) }}
                                          {{ form_widget(form.dimension, {
                                              'attr': {
                                                  'class': 'form-control ' ~ (form.dimension.vars.valid ? '' : 'is-invalid')
                                              }
                                          }) }}
                                          <div class="invalid-feedback">
                                              {{ form_errors(form.dimension) }}
                                          </div>
                                      </div>
                                      <div class="form-group">
                                          {{ form_label(form.quantity) }}
                                          {{ form_widget(form.quantity, {
                                              'attr': {
                                                  'class': 'form-control ' ~ (form.quantity.vars.valid ? '' : 'is-invalid')
                                              }
                                          }) }}
                                          <div class="invalid-feedback">
                                              {{ form_errors(form.quantity) }}
                                          </div>
                                      </div>
                      
                                      {{ form_end(form) }}
                      
                      
                      
                      
                      
                                  </div>
                              </div>
                          </div>
                          <section class="ftco-section bg-light">
                              <div class="container">
                                  <div class="row justify-content-center mb-3 pb-3">
                                      <div class="col-md-12 heading-section text-center ftco-animate">
                                          <h2 class="mb-4">Best Sellers</h2>
                                          <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia</p>
                                      </div>
                                  </div>
                              </div>
                              <div class="container">
                                  <div class="row">
                                      {% for product in products %}
                                          <div class="col-sm-6 col-md-6 col-lg-3 ftco-animate">
                                              {% include 'product/single_product.html.twig' %}
                                          </div>
                                      {% endfor %}
                      
                                  </div>
                              </div>
                          </section>
                      
                      {% endblock %}

                       Un grand merci a vous deux ;)





                      • Partager sur Facebook
                      • Partager sur Twitter

                      symfony : boucle twig sur collection

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown