How to style checkboxes to look like icons

Hello there guys. In my current Laravel project, I had to implement a functionality to mark a user with a checkbox but the checkbox must look like an icon. I found two challenges:

  • How can I transform a checkbox into an icon?
  • How can I make a dynamic ID for that checkbox?

Today I will show you how to implement this by using jQuery to get dynamic IDs and using Axios to update the DB.

Let’s get started

Step 1:

  • Add a checkbox and an Icon element.
{!! Form::checkbox('super', true, null, ['class' => 'super-user-check']) !!}
<i class="fa fa-star super-user-icon" aria-hidden="true"></i>

  • Add a dynamic ID on the checkbox and the icon (for my case I will use a user id)
<div class="super-user">
  {!! Form::checkbox('super', true, null, ['id' => "super-checkbox-$user->id", 'class' => 'form-check-input super-user-check']) !!}
  <i id="super-star-user-{{ $user->id }}" class="fa fa-star super-user-icon" aria-hidden="true"></i>
</div>

Step: 2

  • Define two different icons for the checkbox state (checked/unchecked)
  • (In my case I  will define an icon depending on the value of user DB field starred)
<div class="super-user">
    {!! Form::checkbox('super', $user->starred, $user->starred, ['id' => "super-checkbox-$user->id", 'class' => 'form-check-input super-user-check',
    'data-user' => $user->id ]) !!}
    <i id="super-star-user-{{ $user->id }}" class="fa {{ $user->starred ? 'fa-star' : 'fa-star-o' }} super-user-icon" aria-hidden="true"></i>
</div>

Step: 3

  • Add styles for both elements.
.super-user {
  position: relative;
}

.super-user-check {
  opacity: 0;
  height: 3rem;
  width: 3rem;
  position: absolute;
  z-index: 2;
  margin: 0;
  cursor: pointer;
}

Step: 4

On our .js file we need to identify the dynamics id of the checkbox and the icon.

const starredCheckbox = $("[id^='super-checkbox-']");
const starredIcon = $("[id^='super-star-user-']");

Then, we need to know the state of the checkbox (checked/unchecked) to change the icon classes (colored/uncolored)

const starredCheckbox = $("[id^='super-checkbox-']");
const starredIcon = $("[id^='super-star-user-']");
starredCheckbox.change(function () {
  if ($(this).prop('checked')) {
    $(this).next(starredIcon).removeClass('fa-star-o');
    $(this).next(starredIcon).addClass('fa-star');
  } else {
    $(this).next(starredIcon).removeClass('fa-star');
    $(this).next(starredIcon).addClass('fa-star-o');
  }
});

Finally, when you click on the icon we will update the DB field using Axios.

const starredCheckbox = $("[id^='super-checkbox-']");
const starredIcon = $("[id^='super-star-user-']");
starredCheckbox.change(function () {
  if ($(this).prop('checked')) {
    $(this).next(starredIcon).removeClass('fa-star-o');
    $(this).next(starredIcon).addClass('fa-star');
  } else {
    $(this).next(starredIcon).removeClass('fa-star');
    $(this).next(starredIcon).addClass('fa-star-o');
  }

  const user = $(this).data('user');

  const payload = {
    starred: this.checked,
  };

  axios.put(`/users/${user}/starred`, payload)
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
});

And at the end looks like this

I hope you find this information useful. If you can make any contribution, please comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.