Держите отключенные поля отключенными после включения других

Я хочу отключить все поля в форме и после этого включить только те, которые были включены ранее. Но когда я попытаюсь это сделать, все поля (включая предварительно отключенные поля) будут включены.

$('body').on('click', 'input[type="button"]', function() {
    disable_fields(true);

    setTimeout(function() {
        disable_fields(false);
    }, 1000);
});

function disable_fields(t) {
    var fields = $('input,textarea,select,[type="file"]');

    fields.each(function(index, element) {
        if($(this).is(':disabled')) {
            is_disabled = true;
        }

        console.log(fields.attr('name')+' - '+is_disabled);
        $(this).prop('disabled', t);
        console.log(fields.attr('name')+' - '+is_disabled);
    });
}

Как я могу это сделать?

jsFiddle


person Airikr    schedule 15.10.2016    source источник
comment
Невозможно определить, какие поля изначально отключены после запуска функции disable_fields(). Один из способов — сохранить статус disabled каждого поля готового документа в атрибуте/объекте данных, а затем выполнять переключение только для тех полей, которые не имеют исходного отключенного статуса.   -  person Terry    schedule 15.10.2016
comment
Зачем вам намеренно включать поля, которые вы не хотите включать? Всей проблемы можно было бы легко избежать, если бы не активировать эти поля внутри функции enable_all (которая стала бы плохо названа из-за изменения, но это облегчило бы вашу жизнь).   -  person David says reinstate Monica    schedule 15.10.2016
comment
Потому что, когда я нажимаю кнопку в форме, я хочу отключить все поля. Если возникли какие-либо ошибки, я хочу включить те поля, которые были включены до того, как я нажму кнопку.   -  person Airikr    schedule 15.10.2016


Ответы (3)


Согласно моему комментарию, как только вы начнете изменять свойство disabled, нет надежного способа узнать, какой элемент ввода был изначально отключен. Для этого вам нужно будет сохранить «исходный» отключенный статус в какой-либо структуре данных, например, в объекте data() элемента в jQuery. Я решил не хранить его как атрибут данных HTML5, чтобы пользователи не могли легко манипулировать поведением, изменяя разметку.

Преимущество этого подхода, даже несмотря на то, что он кажется довольно запутанным, заключается в том, что вы оставляете за собой возможность вручную обновить поля, которые вы хотите отозвать/восстановить на более позднем этапе, просто изменив атрибут .data('disabled') элементов ввода.

Стратегия:

  1. Сохранять отключенные состояния всех элементов ввода при загрузке страницы
  2. При выполнении disable_fields() фильтруйте только те элементы ввода, чей исходный отключенный статус равен false. Нам не нужно трогать элементы, которые изначально уже отключены.

$(document).ready(function() {

  // Store the original disabled status of all input elements
  var $fields = $('input,textarea,select,[type="file"]');
  $fields.each(function() {
    $(this).data('disabled', $(this).prop('disabled'));
  });

  $('body').on('click', 'input[type="button"]', function() {
    disable_fields(true);

    setTimeout(function() {
      disable_fields(false);
    }, 1000);
  });

  function disable_fields(t) {
    // Perform toggling only on fields that have data attribute of disabled set to false
    // i.e. not disabled on page load
    $fields.filter(function() {
      return !$(this).data('disabled');
    }).prop('disabled', t);
  }

});
input[name="first"] {
  width: 250px;
}
input[name="second"] {
  width: 90px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="first" value="Disabled (and will keep being disabled)" disabled>
<input type="text" name="second" value="Not disabled">
<input type="button" name="button" value="Button">

person Terry    schedule 15.10.2016
comment
Ваше решение отлично работает на jsFiddle :) Большое спасибо! Теперь, чтобы импортировать его на мой веб-сайт, я думаю, что я никогда не захочу отключить другие поля. Ха-ха! Во всяком случае :) Большое спасибо еще раз! - person Airikr; 15.10.2016
comment
@Erik Если вы не хотите изменять подмножество элементов, которые можно изменить с помощью функции disable_fields(), A. Ответ Вольфа более чем достаточен. У меня просто решение на будущее;) также обновил свой вопрос, потому что я забыл загрузить jQuery во фрагменте. - person Terry; 15.10.2016
comment
В порядке. Я хочу надежное решение на будущее ;) - person Airikr; 15.10.2016

Вы можете оставить ссылку на неотключенные поля по умолчанию, установив varibale вне функции disable_fields():

var fields = $('input,textarea,select,[type="file"]').filter(':not([disabled])');

-jsFiddle-

person A. Wolff    schedule 15.10.2016

Вам нужен какой-то другой способ отличить поля, которые никогда не могут быть включены, поскольку простого атрибута отключения недостаточно для их идентификации после того, как все остальные отключены.

Предполагая, что вы заранее знаете, какие это будут поля, самый простой способ, вероятно, — дать им всем один и тот же класс, например. always-disabled.

Затем, когда вы включаете свои поля, вы можете исключить их из списка, который вы просматриваете, чтобы включить:

var fields = $('input,textarea,select,[type="file"]').filter(':not(.always-disabled)');
person ADyson    schedule 15.10.2016