Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery to show/hide required password field

I have a form to change the personal details of the user. In this form I allow the user to change their email and/or password. With jQuery I want to show a 'Current Password' field when it detects that one of these fields is changed.

For the email field this means that when it is changed the password field appears, but when the email is re-entered correctly it hides itself again.

For the password field this means it simply shows when anything is typed inside the field.

I got the basics working, but I can't get them to work with each other. So when I change both and change one back, the Current Password field hides itself.

let requiredSet;

$('.js-show-target-on-change').on('input', function() {
  const target = $('.js-show-target-on-change__target');
  let currentValue = $(this).val();

  if ( $(this).data('type') === 'email' ) {
    const emailValue = $(this).data('value');

    if ( currentValue !== emailValue && !requiredSet === true ) {
      target.show();
      target.find('input').prop('required', true);

      requiredSet = true;
    } else if ( currentValue === emailValue ) {
      target.hide();
      target.find('input').prop('required', false);

      requiredSet = false;
    }
  } else {
    if ( !requiredSet === true ) {
      target.show();
      target.find('input').prop('required', true);

      requiredSet = true;
    } else if ( !currentValue.length ) {
      target.hide();
      target.find('input').prop('required', false);

      requiredSet = false;
    }
  }
});

JsFiddle

Would love some help with this since I've been stuck for so long... Thanks in advance!

like image 774
Mathijs Avatar asked Mar 20 '19 19:03

Mathijs


2 Answers

EDIT: Here's a description of how the code works:

cost email = $('#email').val() // get the starting value of the email 
                               // field to check if it has changed
$('.js-show-target-on-change').on('input', function(){

    const f = $('#email').val() !== email 
        // check if the old email value is different than the new email value

        || $('#newPassword').val().length > 0 
        // check if there is text in the new password field

        ? 'show' : 'hide'; 
        // if one of the above statements are true,show the field, else hide it

    $('.js-show-target-on-change__target')[f](); 
    // update the field based on the above condition
});

If I understood your use case correctly the following code should do the job:

const email = $('#email').val();
$('.js-show-target-on-change').on('input', function() {
  const f = $('#email').val() !== email || $('#newPassword').val().length > 0 ? 'show' : 'hide';
  $('.js-show-target-on-change__target')[f]();
});
like image 161
doberkofler Avatar answered Oct 18 '22 03:10

doberkofler


Use an attribute to specify the input value has been changed and later use that attribute to toggle the visibility of the input element.

$('.js-show-target-on-change').on('input', function() {
  const target = $('.js-show-target-on-change__target');
  let currentValue = this.value;

  // if input is email
  if (this.id === 'email') {
    // get default value
    let defValue = $(this).data('value');
    // set attribute value based on old and default value
    $(this).attr('data-changed', defValue !== currentValue);
  } else {
    // if password field then set attribute based on length
    $(this).attr('data-changed', currentValue.length > 0);
  }

  // check number of changed fields 
  let visible = $('input[data-changed="true"]').length > 0;

  // toggle based on the value
  target.toggle(visible);
  target.find('input').prop('required', visible);

});

$('.js-show-target-on-change').on('input', function() {
  const target = $('.js-show-target-on-change__target');
  let currentValue = this.value;

  // if input is email
  if (this.id === 'email') {
    // get default value
    let defValue = $(this).data('value');
    // set attribute value based on old and default value
    $(this).attr('data-changed', defValue !== currentValue);
  } else {
    // if password field then set attribute based on length
    $(this).attr('data-changed', currentValue.length > 0);
  }

  // check number of changed fields 
  let visible = $('input[data-changed="true"]').length > 0;

  // toggle based on the value
  target.toggle(visible);
  target.find('input').prop('required', visible);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" accept-charset="UTF-8" enctype="multipart/form-data" class="c-form">
  <div class="c-form__row">
    <label class="c-form__label" for="email">Email</label>
    <div class="c-form__field">
      <div class="c-input__control">
        <input required class="c-input js-show-target-on-change" data-type="email" type="email" id="email" name="email" value="[email protected]" data-value="[email protected]">
      </div>
    </div>
  </div>

  <div class="c-form__row">
    <label class="c-form__label" for="newPassword">New password</label>
    <div class="c-form__field">
      <div class="c-input__control">
        <input class="c-input js-show-target-on-change" type="password" id="newPassword" name="newPassword">
      </div>
    </div>
  </div>

  <div class="c-form__row js-show-target-on-change__target" style="display: none;">
    <label class="c-form__label" for="currentPassword">
      Current password
      <span class="u-warning">(required to change email or password)</span>
    </label>
    <div class="c-form__field">
      <div class="c-input__control">
        <input class="c-input" type="password" id="currentPassword" name="password">
      </div>
    </div>
  </div>

  <div class="c-form__submit">
    <button class="c-button c-button--fullwidth" type="submit">Save</button>
  </div>
</form>
like image 44
Pranav C Balan Avatar answered Oct 18 '22 01:10

Pranav C Balan