Home > database >  Animate/transition content smoothly when it appears (after click) with jQuery
Animate/transition content smoothly when it appears (after click) with jQuery

Time:09-04

I have a 'form' that displays text feedback (2 options) depending on how many checkboxes are selected. In principle this works however I would like to improve the animation/transition of how the text is displayed.

If you select all checkboxes, a p is slide into view. Any other amount you get a separate message which functions the same way. Currently this is 'hardcoded' to 5 checkboxes. Dunno if it's possible to make this more flexible based on a data attribute or something so if in future there's 6 - it's not a whole new block of JS?

But the main goal is when the message is displayed, it slides into view. However if you alter your answer and click 'submit' again, the animation is janky.

So I'd like to improve the transition between the update. I've done this elsewhere where it just slides open the first time (if that's easier) but I can't get it to work on this version.

Other implementation here: https://codepen.io/moy/pen/LYdoEBG

But I'd like both to be consistent if possible. So just a refresh/update/fade will be fine rather than both sliding. Unless it's possible to at least make the page/content below slide/push don't gracefully?

$(".form-feedback .btn").click(function () {
            let checkboxes = $(this).parents(".form-feedback").find('input:checked').length
            $(this).parents(".form-feedback").find(".form-feedback__reveal p").hide()
            if(checkboxes == 5){
              $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='all']").slideDown(200)
            }else{
              $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='some']").slideDown(200)
            }
        });
.hide {
  display: none;
}

.label {
  display: block;
  margin-bottom: 24px;
}

.checkbox {
  display: block;
  margin-bottom: 12px;
}

.btn {
  background: black;
  border-radius: 24px;
  color: white;
  display: inline-flex;
  padding: 12px 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <label >HACCP helps a food business to...</label>
    <label ><input type="checkbox">Minimise risks in areas of food safety</label>
    <label ><input type="checkbox">Identify critical control points</label>
    <label ><input type="checkbox">Decide on actions to take if something goes wrong</label>
    <label ><input type="checkbox">Ensure procedures are followed and are effective</label>
    <label ><input type="checkbox">Ensure appropriate record keeping</label>
    <a href="#" >Submit</a>
    <div >
      <p  data-feedback="all">That’s right, HACCP supports a business in all of the areas listed.</p>
      <p  data-feedback="some">That’s incorrect, HACCP actually supports a business in all of these areas.</p>
    </div>
  </div>
</div>

<div >
  <h4>Content below to check it gets pushed down smoothly</h4>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

CodePudding user response:

$(".form-feedback .btn").click(async function () {
            let checkboxes = $(this).parents(".form-feedback").find('input:checked').length
            $(this).parents(".form-feedback").find(".form-feedback__reveal p").slideUp(200)
            await new Promise(res => { setTimeout(res, 200); });
            $(this).parents(".form-feedback").find(".form-feedback__reveal p").hide()
            if(checkboxes == 5){
              $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='all']").slideDown(200)
            }else{
              $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='some']").slideDown(200)
            }
        });
.hide {
  display: none;
}

.label {
  display: block;
  margin-bottom: 24px;
}

.checkbox {
  display: block;
  margin-bottom: 12px;
}

.btn {
  background: black;
  border-radius: 24px;
  color: white;
  display: inline-flex;
  padding: 12px 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <label >HACCP helps a food business to...</label>
    <label ><input type="checkbox">Minimise risks in areas of food safety</label>
    <label ><input type="checkbox">Identify critical control points</label>
    <label ><input type="checkbox">Decide on actions to take if something goes wrong</label>
    <label ><input type="checkbox">Ensure procedures are followed and are effective</label>
    <label ><input type="checkbox">Ensure appropriate record keeping</label>
    <a href="#" >Submit</a>
    <div >
      <p  data-feedback="all">That’s right, HACCP supports a business in all of the areas listed.</p>
      <p  data-feedback="some">That’s incorrect, HACCP actually supports a business in all of these areas.</p>
    </div>
  </div>
</div>

<div >
  <h4>Content below to check it gets pushed down smoothly</h4>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

This is getting toward the right direction I think. I've added an animation to close the slideDown. You could also add a check to make sure it doesn't slide up and back down if the text isn't going to change

CodePudding user response:

I think Jess' animation is what you're looking for, so this solution is based on

If you select all checkboxes, a p is slide into view. Any other amount you get a separate message which functions the same way. Currently this is 'hardcoded' to 5 checkboxes. Dunno if it's possible to make this more >flexible based on a data attribute or something so if in future there's 6 - it's not a whole new block of JS?

To ensure the onclick eventlistener on the .btn-element is handled properly, use target.preventDefault(). Seeing as the element is an <a>-element, clicking it will force your screenview to jump to the top. preventDefault() makes sure the viewport stays in place when you click on the link (although making it a <button> or <input type="submit"> is correct semantically and accessibility wise, unless it actually IS a link that will redirect the user)

When you say you want a "dynamic solution", I'm going to assume you want the message that appears when 5 inputs are selected to be shown if all inputs are selected, no matter the amount of input-elements there are.

You already have the variable checkboxes which contains the length of the amount of checkboxes that are checked. Just make a new, very similiar variable that holds the length of the total amount of checkboxes in the form, and in your if-statement, set those two variables to be equal to each other. This way, your message will always show if all of the checkboxes are checked.

$(".form-feedback .btn").click(function(e) {
  // remove default behaviour of the <a>
  e.preventDefault();
  // variables that hold the length of checkboxes
  let checkedCheckboxes = $(this).parents(".form-feedback").find('input:checked').length;
  let checkboxes = $(this).parents(".form-feedback").find('input').length;
  $(this).parents(".form-feedback").find(".form-feedback__reveal p").hide()
  if (checkedCheckboxes === checkboxes) {
    $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='all']").slideDown(200)
  } else {
    $(this).parents(".form-feedback").find(".form-feedback__reveal p[data-feedback='some']").slideDown(200);
  }


});
.hide {
  display: none;
}

.label {
  display: block;
  margin-bottom: 24px;
}

.checkbox {
  display: block;
  margin-bottom: 12px;
}

.btn {
  background: black;
  border-radius: 24px;
  color: white;
  display: inline-flex;
  padding: 12px 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <label >HACCP helps a food business to...</label>
    <label ><input type="checkbox">Minimise risks in areas of food safety</label>
    <label ><input type="checkbox">Identify critical control points</label>
    <label ><input type="checkbox">Decide on actions to take if something goes wrong</label>
    <label ><input type="checkbox">Ensure procedures are followed and are effective</label>
    <label ><input type="checkbox">Ensure appropriate record keeping</label>
    <a href="#" >Submit</a>
    <div >
      <p  data-feedback="all">That’s right, HACCP supports a business in all of the areas listed.</p>
      <p  data-feedback="some">That’s incorrect, HACCP actually supports a business in all of these areas.</p>
    </div>
  </div>
</div>

<div >
  <h4>Content below to check it gets pushed down smoothly</h4>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

  • Related