У меня есть форма для изменения личных данных пользователя. В этой форме я разрешаю пользователю изменить свой адрес электронной почты и/или пароль. С 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;
}
}
});
Мне бы очень хотелось помочь с этим, так как я так долго застрял ... Заранее спасибо!
Добро пожаловать в сообщество StackOverflow!
Спасибо всем! Я чувствую, что @doberkofler действительно преуспел в своем ответе. Поэтому я отметил это как правильный ответ. Но те, что указаны выше, также отлично работают, поэтому я дал всем положительный голос.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Используйте атрибут, чтобы указать, что входное значение было изменено, а затем используйте этот атрибут для переключения видимости элемента ввода.
$('.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>Большое спасибо за ответ! Изучение этого действительно заставило меня щелкнуть, что я делаю неправильно. Спасибо!
РЕДАКТИРОВАТЬ: Вот описание работы кода:
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! Должен признать, что я не понимаю и половины из этого, но я собираюсь провести остаток дня, чтобы понять это. Спасибо!
Извиняюсь. Я старался быть кратким, чтобы подчеркнуть решение. Если я правильно понял, он просто делает 2 вещи. Сначала он сохраняет исходный пароль, чтобы мы могли позже сравнить его. Затем в обработчике событий я просто получаю значения электронной почты и пароля и проверяю, изменился ли адрес электронной почты или пароль не пуст. Что может показаться необычным, так это, скорее всего, [f](), но это лишь один из многих трюков JavaScript, который позволяет мыслить кратко. В конце [f]() only executes the method show` или hide на элементе, возвращенном $('.js-show-target-on-change__target').
Это именно то, что я предложил в своем комментарии. Молодец!
Не нужно извиняться @doberkofler, вы попали в цель, и это объяснение делает это на 100% ясным для меня, так что еще раз спасибо!
@NawedKhan Я собирался ответить на ваш первоначальный комментарий, вы, конечно, совершенно правы. Я новичок в javascript, поэтому я обязательно учту ваш комментарий на будущее :)
Не принимайте решения по отдельным полям. Думайте шире, принимайте решения на основе всех областей. Используйте поля только для запуска функции, которая решает, показывать поле пароля или нет.