Kevin Grant
Kevin Grant

Reputation: 138

How to individually manage state within objects that have the same tag or class

I have 3 boxes, each has a toggle button. I want to toggle the 'open' state of each individually. However, I do not know how to scope the open state to each box.

I have tried creating an object with various properties and methods but the main issue I keep running into is not being able re-access the open property. have a feeling that may be overkill anyway.

const serviceImages13 = () => {

    const $openBtn = $('.hollow-service-images-13 .toggle')
    let open = false

    $openBtn.on('mousedown', function() {
        if (!open) {
            $(this).css('transform', 'rotate(-45deg)')
        } else {
            $(this).css('transform', 'rotate(450deg)')
        }
    })

    $openBtn.on('mouseup', function() {
        if (!open) {
            $(this).css('transform', 'rotate(405deg)')
            open = true
            console.log('open', open)
        } else {
            $(this).css('transform', 'rotate(0)')
            open = false
            console.log('open', open)
        }
    })

}
serviceImages13()

<section class="hollow-service-images-13">
  <div class="flex-container">
    <figure>
      <img src="" alt="">
      <figcaption>
        <h3>First <span>Service</span></h3>
        <p>This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated. This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated.</p>
        <a href="#">Learn More</a>
      </figcaption>
      <i class="toggle fa fa-plus"></i>
    </figure>
    <figure>
      <img src="" alt="">
      <figcaption>
        <h3>Second <span>Service</span></h3>
        <p>This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated. This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated.</p>
        <a href="#">Learn More</a>
      </figcaption>
      <i class="toggle fa fa-plus"></i>
    </figure>
    <figure>
      <img src="" alt="">
      <figcaption>
        <h3>Third <span>Service</span></h3>
        <p>This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated. This is filler content. The text in this area will be replaced when copy from your site becomes available. This paragraph will be updated.</p>
        <a href="#">Learn More</a>
      </figcaption>
      <i class="toggle fa fa-plus"></i>
    </figure>
  </div>
</section>

Currently, any button you click will toggle the open state. The expected result would have all 3 boxes with an independent open state;

Upvotes: 1

Views: 34

Answers (1)

Shidersz
Shidersz

Reputation: 17190

One solution is to use JQuery.data() to save the open state of each element inside an HTML attribute.

Example:

const serviceImages13 = () =>
{
    const $openBtn = $('.hollow-service-images-13 .toggle');
    $openBtn.data("isOpen", false);

    $openBtn.on('mousedown', function()
    {
        if ( !$(this).data("isOpen") )
            $(this).css('transform', 'rotate(-45deg)');
        else
            $(this).css('transform', 'rotate(450deg)');
    });

    $openBtn.on('mouseup', function()
    {
        if ( !$(this).data("isOpen") )
        {
            $(this).css('transform', 'rotate(405deg)');
            $(this).data("isOpen", true);
        }
        else
        {
            $(this).css('transform', 'rotate(0)');
            $(this).data("isOpen", false);
        }

        console.log('open', $(this).data("isOpen"));
    });
}

Upvotes: 1

Related Questions