1
\$\begingroup\$

I am creating a Website with different boxes being displayed to the user, and he can filter them by their Status (the dates are stored on a Django database). The possible statuses are "Active", "Upcoming" and "Ended".

The filtering works with Radio buttons, so he clicks whichever he likes and all other elements that don't match that description will be hidden.

I am not sure to how elegant this solution is overall. It seems as if I should aim to remove the repetitive structure at the end.

$(function(){

  // Radio buttons functionality
  var displayAllOption = $('#display-all-infos');
  var displayActiveOption = $('#display-active-infos');
  var displayUpcomingOption = $('#display-upcoming-infos');
  var displayEndedOption = $('#display-ended-infos');

  function showAllInfos(){
    $('.info-box').parent().show();
  }

  function hideInfosThatDontMatchOption(selectedOption){

    var infos = $('.info-box').parent();

    [].forEach.call(infos, function(info){
      var countdownContent = $(info).find('.info-box').find('.card-block').find('.countdown').html();

      // Hide every info that has not started, yet, based on the prefix
      // that is displayed at the beginning of the countdown timer
      if (!countdownContent.startsWith(selectedOption)){
        $(info).hide();
      }
    });
  }

  /*
     First lines change the Color highlighting by toggling the 'active' class

     Filter Logic: Make sure all info boxes are displayed at the beginning, and then
     hide all the info boxes that the User doesn't want to see
  */

  displayAllOption.on('click', function(){
    showAllInfos();
  });

  displayActiveOption.on('click', function(element){

    displayActiveOption.addClass('active')
    displayUpcomingOption.removeClass('active')
    displayEndedOption.removeClass('active')

    showAllInfos();
    hideInfosThatDontMatchOption('Time Left')
  });

  displayUpcomingOption.on('click', function(element){

    displayUpcomingOption.addClass('active')
    displayActiveOption.removeClass('active')
    displayEndedOption.removeClass('active')

    showAllInfos();
    hideinfosThatDontMatchOption('Starts In')
  });

  displayEndedOption.on('click', function(element){

    displayEndedOption.addClass('active') 
    displayActiveOption.removeClass('active')
    displayUpcomingOption.removeClass('active')

    showAllInfos();
    hideInfosThatDontMatchOption('Ended')
  });

});

Here is the Radio Button HTML snippet:

<div class="container" style="display: block; margin: 0 auto;">
    <div class="btn-group" data-toggle="buttons">
      <label id="display-all-infos" class="btn btn-warning">
        <input type="radio" name="options" autocomplete="off" checked> All
      </label>
      <label id="display-active-infos" class="btn btn-success">
        <input type="radio" name="options" autocomplete="off" checked> Active
      </label>
      <label id="display-upcoming-infos" class="btn btn-primary">
        <input type="radio" name="options" autocomplete="off"> Upcoming
      </label>
      <label id="display-ended-infos" class="btn btn-danger">
        <input type="radio" name="options" autocomplete="off"> Ended
      </label>
    </div>
  </div>

I'd appreciate all feedback telling me how I can improve it.

Thanks in Advance!

\$\endgroup\$
2
\$\begingroup\$

I find that these all radio buttons are of same group , so you can use same name for all the radio button with different values .

<input type="radio" name="displayOption" value="1" checked> All
<input type="radio" name="displayOption" value="2"> Active....

Now in this case you dont have to add and remove active class for the radio buttons. It will handle it by itself.

and write a common function like

$("input[name='displayOption']").change(function(){
 if ($(this).val() === '1') {
      myFunction();
    } else if ($(this).val() === '2') {
      myOtherFunction();
    } 
});
\$\endgroup\$
  • \$\begingroup\$ I am using labels around the inputs, and it doesn't seem to work for some reason (I use the bootstrap 4 radio button component from the website). \$\endgroup\$ – OhMad Oct 10 '17 at 12:27
  • \$\begingroup\$ You are using label around the input or with the input? Can you share your code for that as well for better understanding. \$\endgroup\$ – Viplock Oct 10 '17 at 12:44
  • \$\begingroup\$ and one more thing , you can use container and keep all the radio buttons inside that container. if your container have some id you can use code like this. $('#radioButtonContainerId input:radio').click(function() { if ($(this).val() === '1') { myFunction(); } else if ($(this).val() === '2') { myOtherFunction(); } }); \$\endgroup\$ – Viplock Oct 10 '17 at 12:48
  • 1
    \$\begingroup\$ good answer! a switch/case might be more suitable than a stack of if/elseif's tho \$\endgroup\$ – I wrestled a bear once. Oct 10 '17 at 18:38
  • \$\begingroup\$ @Rechunk Use it like <input type="radio" name="options" autocomplete="off"> <label id="display-ended-infos" class="btn btn-danger"> Ended </label> \$\endgroup\$ – Viplock Oct 11 '17 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.