0

I am creating a blog page in HTML. In the backend I'm using Django. I have created a general HTML template for every post. In Django admin when I upload the image and other data, I'm getting it in Frontend and setting the id of each post dynamically using an autogenerated id coming from Backend. My HTML template is this

<div class="row">
  {% for blog in blogs_post %}
  <div class="col-sm-3 offset-sm-1 col-12" id="{{ blog.id }}">
    <div class="row">
      <div class="col-12">
        <img src="{{ blog.image }}" alt=" {{ blog.tittle }}" class="img-fluid">
      </div>
      <div class="col-12">
        <h3>{{ blog.tittle }}</h3>
        <p class="d-none" id="card-body">
          <h6>{{ blog.description }}</h6>
        </p>
        {% if blog.url %}
        <a href="{{ blog.url }}" type="submit" role="button" class="btn btn-info">Read more</a> {% endif %}
      </div>
    </div>
  </div>
  {% endfor %}
</div>

I want to use this

id="{{ blog.id }}"
In my CSS file and JS file to uniquely identify each post and apply changes to them. Like if I click one card all the cards should not expand but only the card I clicked will expand. For that I need the dynamically set id to be accessed in my CSS file and JS file. How can I achieve it please help!
  • use 'event.target' in javascript – Rahul Sep 26 '20 at 11:09
  • No need for id at all. Just use a more specific common className like "card" or "post" and toggle another "selected" or "active" type className. Very simple to access selector `".card.active"` to remove the active class and add it to the one you clicked – charlietfl Sep 26 '20 at 11:09
  • @charlietfl can you please elaborate I didn't understand what you said – Soumalya Bhattacharya Sep 26 '20 at 11:17
  • When you click an element you have access to that specific element object in the event handler for the listener you create. So if you click on "card" you set another class on it for the different style when selected. But before doing that you look for other instance(s) of that active/selected class and remove it from prior selections. Your css would be like `.card{ color:blue;} .card.active{color:red}` – charlietfl Sep 26 '20 at 11:23
  • Writing your css for every blog.id is not scalable. You don't want to add a new style rule every time you write a new post. Two class rules will cover the whole collection of posts – charlietfl Sep 26 '20 at 11:28

2 Answers2

1

Expanding on @charlietfl comment.

First of all lets make a common class called each-card. And, give style to active-class. active-class will be added to the clicked element.

Js part taken from here

function changeActive(elem) {
  for (var i = 0; i < elem.length; i++) {
    elem[i].addEventListener("click", function(e) {
      var current = this;
      for (var i = 0; i < elem.length; i++) {
        if (current != elem[i]) {
          elem[i].classList.remove('active-card');
        } else if (current.classList.contains('active') === true) {
          current.classList.remove('active-card');
        } else {
          current.classList.add('active-card')
        }
      }
      e.preventDefault();
    });
  };
}
changeActive(document.querySelectorAll('.each-card'));
.active-card {
    background: teal;
}
<div class="row">
  <div class="each-card col-sm-3 offset-sm-1 col-12" data-id="2">
    <div class="row">
      <div class="col-12">
        <img src="img" alt="Title" class="img-fluid">
      </div>
      <div class="col-12">
        <h3>{{ blog.tittle }}1</h3>
        <p class="d-none" id="card-body">
          <h6>{{ blog.description }}</h6>
        </p>
        <a href="" type="submit" role="button" class="btn btn-info">Read more</a> 
      </div>
    </div>
  </div>
</div>
<div class="row">
  <div class="each-card col-sm-3 offset-sm-1 col-12" data-id="2">
    <div class="row">
      <div class="col-12">
        <img src="img" alt="Title" class="img-fluid">
      </div>
      <div class="col-12">
        <h3>{{ blog.tittle }}</h3>
        <p class="d-none" id="card-body">
          <h6>{{ blog.description }}</h6>
        </p>
        <a href="" type="submit" role="button" class="btn btn-info">Read more</a> 
      </div>
    </div>
  </div>
</div>

Note:- I skipped django part, as it is not actually essentiall. And, added extra card for demonstration.

Biplove Lamichhane
  • 3,995
  • 4
  • 14
  • 30
0

This solution requires jQuery in order to work.

Suppose you have many cards by iteration, use,

  $('.card').on('click',function(event){
      event.target.style.background = red;     //this will change only the background of the card that is clicked    
})

You can do many other things with event.target. just google it.

vmank
  • 773
  • 2
  • 7
  • 22
Rahul
  • 337
  • 2
  • 14