JQuery, чтобы показать/скрыть обязательное поле пароля

У меня есть форма для изменения личных данных пользователя. В этой форме я разрешаю пользователю изменить свой адрес электронной почты и/или пароль. С jQuery я хочу показать поле «Текущий пароль», когда он обнаружит, что одно из этих полей изменено.

Для поля электронной почты это означает, что при его изменении появляется поле пароля, но при повторном правильном вводе электронной почты оно снова скрывается.

Для поля пароля это означает, что оно просто показывает, когда что-либо вводится в поле.

У меня работают основы, но я не могу заставить их работать друг с другом. Поэтому, когда я меняю оба и меняю один обратно, поле «Текущий пароль» скрывается.

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

Мне бы очень хотелось помочь с этим, так как я так долго застрял ... Заранее спасибо!

Не принимайте решения по отдельным полям. Думайте шире, принимайте решения на основе всех областей. Используйте поля только для запуска функции, которая решает, показывать поле пароля или нет.

Nawed Khan 20.03.2019 21:06

Добро пожаловать в сообщество StackOverflow!

Máxima Alekz 20.03.2019 21:12
jsfiddle.net/dqp7njea
Void Spirit 20.03.2019 21:13
jsfiddle.net/pranavcbalan/dznq36jg/8
Pranav C Balan 20.03.2019 21:15

Спасибо всем! Я чувствую, что @doberkofler действительно преуспел в своем ответе. Поэтому я отметил это как правильный ответ. Но те, что указаны выше, также отлично работают, поэтому я дал всем положительный голос.

Mathijs 20.03.2019 21:39
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
5
561
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте атрибут, чтобы указать, что входное значение было изменено, а затем используйте этот атрибут для переключения видимости элемента ввода.

$('.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>

Большое спасибо за ответ! Изучение этого действительно заставило меня щелкнуть, что я делаю неправильно. Спасибо!

Mathijs 20.03.2019 21:36
Ответ принят как подходящий

РЕДАКТИРОВАТЬ: Вот описание работы кода:

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
});

Если я правильно понял ваш вариант использования, следующий код должен выполнить эту работу:

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]();
});

Ух ты, это работает отлично, и с 5 строками кода вместо 30! Должен признать, что я не понимаю и половины из этого, но я собираюсь провести остаток дня, чтобы понять это. Спасибо!

Mathijs 20.03.2019 21:35

Извиняюсь. Я старался быть кратким, чтобы подчеркнуть решение. Если я правильно понял, он просто делает 2 вещи. Сначала он сохраняет исходный пароль, чтобы мы могли позже сравнить его. Затем в обработчике событий я просто получаю значения электронной почты и пароля и проверяю, изменился ли адрес электронной почты или пароль не пуст. Что может показаться необычным, так это, скорее всего, [f](), но это лишь один из многих трюков JavaScript, который позволяет мыслить кратко. В конце [f]() only executes the method show` или hide на элементе, возвращенном $('.js-show-target-on-change__target').

doberkofler 20.03.2019 21:44

Это именно то, что я предложил в своем комментарии. Молодец!

Nawed Khan 20.03.2019 21:45

Не нужно извиняться @doberkofler, вы попали в цель, и это объяснение делает это на 100% ясным для меня, так что еще раз спасибо!

Mathijs 20.03.2019 21:49

@NawedKhan Я собирался ответить на ваш первоначальный комментарий, вы, конечно, совершенно правы. Я новичок в javascript, поэтому я обязательно учту ваш комментарий на будущее :)

Mathijs 20.03.2019 21:50

Другие вопросы по теме