Условной проверки на двух входных полей, которые зависят друг от друга


Мой код состоит из двух полей ввода и кнопки Отправить. Бизнес-правила требуют следующие правила:

  1. По крайней мере одно поле должно быть заполнено. Оба могут быть заполнены, но оба не может быть пустым.
  2. Если первое поле пустое или 0, тогда второе поле.
  3. Если второе поле пусто или 0, то требуется первое поле.
  4. Поля не должны сломаться, если нечисловые значения входного сигнала.
  5. Если поле не равно 0 или пустой, то их минимальное количество правил.

Я реализовал на jQuery, чтобы получить минимальные суммы от данных правил - в каждом поле в HTML. Эти ценности в конечном счете управляется КМВ. То же самое касается сообщения о проверке.

Мой код ведет себя именно так, как я хочу его и передает Мой модульные тесты, но я интересно, если этот код может быть упрощен. Я вижу, что код, где foo и Bar назначаются повторяется на протяжении всего сценария. Я попытался переместить их в переменных за пределами логики валидатор, но это повлияло на функциональность и больше не вел себя так, как нужно. Мое предположение заключается в том, что переменные не обновляются в то же время, что код проверки запускается. Поэтому я не уверен, где еще я мог бы поместить эти переменные так, чтобы код не повторялся.

Это возможно?

$.validator.addMethod('groterdan', function(value, element, param) {
  return (value >= param);
});

/*
var rauwOorspronkelijkeBedrag = $.trim($('#oorspronkelijkeBedrag').val());
var oorspronkelijkeBedrag = rauwOorspronkelijkeBedrag.length > 0 ? parseInt(rauwOorspronkelijkeBedrag, 10) : 0;
var rauwAanvullendBedrag = $.trim($('#aanvullendBedrag').val());
var aanvullendBedrag = rauwAanvullendBedrag.length > 0 ? parseInt(rauwAanvullendBedrag, 10) : 0;
*/

$('#beleggingsForm').validate({
  rules: {
    oorspronkelijkeBedrag: {
      required: function(element) {
        var rauwAanvullendBedrag = $.trim($('#aanvullendBedrag').val());
        var aanvullendBedrag = rauwAanvullendBedrag.length > 0 ? parseInt(rauwAanvullendBedrag, 10) : 0;
        return aanvullendBedrag === 0;
      },
      groterdan: {
        param: $('#oorspronkelijkeBedrag').data('rule-groterdan'),
        depends: function(element) {
          var rauwOorspronkelijkeBedrag = $.trim($('#oorspronkelijkeBedrag').val());
          var oorspronkelijkeBedrag = rauwOorspronkelijkeBedrag.length > 0 ? parseInt(rauwOorspronkelijkeBedrag, 10) : 0;
          var rauwAanvullendBedrag = $.trim($('#aanvullendBedrag').val());
          var aanvullendBedrag = rauwAanvullendBedrag.length > 0 ? parseInt(rauwAanvullendBedrag, 10) : 0;
          return oorspronkelijkeBedrag !== 0 || aanvullendBedrag === 0;
        }
      }
    },
    aanvullendBedrag: {
      required: function(element) {
        var rauwOorspronkelijkeBedrag = $.trim($('#oorspronkelijkeBedrag').val());
        var oorspronkelijkeBedrag = rauwOorspronkelijkeBedrag.length > 0 ? parseInt(rauwOorspronkelijkeBedrag, 10) : 0;
        return oorspronkelijkeBedrag === 0;
      },
      groterdan: {
        param: $('#aanvullendBedrag').data('rule-groterdan'),
        depends: function(element) {
          var rauwOorspronkelijkeBedrag = $.trim($('#oorspronkelijkeBedrag').val());
          var oorspronkelijkeBedrag = rauwOorspronkelijkeBedrag.length > 0 ? parseInt(rauwOorspronkelijkeBedrag, 10) : 0;
          var rauwAanvullendBedrag = $.trim($('#aanvullendBedrag').val());
          var aanvullendBedrag = rauwAanvullendBedrag.length > 0 ? parseInt(rauwAanvullendBedrag, 10) : 0;
          return oorspronkelijkeBedrag === 0 || aanvullendBedrag !== 0;
        }
      }
    },
    submitHandler: function() {
      //Update(); /* function that contains ajax code for the actual functionality but is not relevant to this post. Using "return false" for demonstration purposes instead */
      return false;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<form id="beleggingsForm">
  <input id="oorspronkelijkeBedrag" name="oorspronkelijkeBedrag" type="text" data-rule-groterdan="500" data-msg-groterdan="Oorspronkelijke bedrag moet >= 500 zijn" data-msg-required="Oorspronkelijke bedrag is verplicht" />
  <br/>
  <input id="aanvullendBedrag" name="aanvullendBedrag" type="text" data-rule-groterdan="50" data-msg-groterdan="Aanvullend bedrag moet >= 50 zijn" data-msg-required="Aanvullend bedrag is verplicht" />
  <br/>
  <input type="submit" />
</form>



4752
5
задан 13 февраля 2018 в 01:02 Источник Поделиться
Комментарии
2 ответа

Некоторые предложения

Использовать element вместо новых jQuery элемент отбора

Почему бы не использовать element параметр может быть входным выбирается через jQuery в любом случае. Один менее жестко переменной, вы должны беспокоиться.

Минимизировать дублирование кода

В depends,required функции обоих похожие. Что произойдет, если добавить еще одно правило? Сейчас было бы 6 одинаковых функций. Либо сделать функцию отовсюду или упростить выражение.

Уменьшить переменную зависимостям

depends и required трудно передать, потому что вы зависит от переменных для селектора и логическое выражение для возвращения. Может быть поставить переменные в качестве параметров функции?

function simplified(element, otherelement) {
// Your job
}

...
depends: simplified(element, otherelement)

Гибкий параметр/переменную count

Если вы добавить больше переменных поздно, используйте новое распространение оператор ... или аргументы, чтобы получить любое количество аргументов в функции.

function simplified(element) {
for (let argument in arguments){
//.val(), measure length, etc.
}
}

function simplified(element, ...args) {
for (let argument in args){
//.val(), measure length, etc.
}
}

Попробуйте использовать let/const вместо var

ВАР не приносит никакой пользы в вашем случае, а так как мы в современном ЕС6 возраст вы могли бы также использовать const в вашем случае, поскольку вы не переназначить переменные.

Вот некоторые (не черный делюкс) предложения, которые должны дать вам некоторое вдохновение.

Правка # 1

Как @Ротора правильно указал значения вычисляются несколько раз таким же образом. Вот что я придумал первую очистку кода. Пожалуйста, не рассматриваем это как комплексное решение, а скорее доказательство концепции того, как можно реально минимизировать/очистка ваш код, когда вы думаете об этом. Она далека от совершенства и не рассчитывать, когда вы находитесь в зависимости от более, чем 2 разных поля ввода.



$.validator.addMethod('groterdan', function(value, element, param) {
return (value >= param);
});

/*
var rauwOorspronkelijkeBedrag = $.trim($('#oorspronkelijkeBedrag').val());
var oorspronkelijkeBedrag = rauwOorspronkelijkeBedrag.length > 0 ? parseInt(rauwOorspronkelijkeBedrag, 10) : 0;
var rauwAanvullendBedrag = $.trim($('#aanvullendBedrag').val());
var aanvullendBedrag = rauwAanvullendBedrag.length > 0 ? parseInt(rauwAanvullendBedrag, 10) : 0;
*/

const getValue = function(target){
const value = $.trim($('#' + target).val())
return value.length > 0 ? parseInt(value, 10) : 0
}

const dependsCheck = function(element){
return getValue(element.id) === 0;
};

const requiredCheck = function(element) {
const otherTarget = element.id === "oorspronkelijkeBedrag" ? "aanvullendBedrag" : "oorspronkelijkeBedrag";

return getValue(otherTarget) === 0;
};

$('#beleggingsForm').validate({
rules: {
oorspronkelijkeBedrag: {
required: requiredCheck,
groterdan: {
param: $(this).data('rule-groterdan'),
depends: dependsCheck
}
},
aanvullendBedrag: {
required: requiredCheck,
groterdan: {
param: $(this).data('rule-groterdan'),
depends: dependsCheck
}
},
submitHandler: function() {
//Update(); /* function that contains ajax code for the actual functionality but is not relevant to this post. Using "return false" for demonstration purposes instead */
return false;
}
}
});


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<form id="beleggingsForm">
<input id="oorspronkelijkeBedrag" name="oorspronkelijkeBedrag" type="text" data-rule-groterdan="500" data-msg-groterdan="Oorspronkelijke bedrag moet >= 500 zijn" data-msg-required="Oorspronkelijke bedrag is verplicht" />
<br/>
<input id="aanvullendBedrag" name="aanvullendBedrag" type="text" data-rule-groterdan="50" data-msg-groterdan="Aanvullend bedrag moet >= 50 zijn" data-msg-required="Aanvullend bedrag is verplicht" />
<br/>
<input type="submit" />
</form>


При добавлении в этом примере я заметил несколько областей для улучшения:

Наименования / язык

Я сам лично борюсь с этим регулярно. Одна вещь, которую я привык писать все мои код на английском, а не мой родной язык. Это дает вам хорошую практику и другие разработчики не знакомы с вашим языком можете легко Поиск, что вы на самом деле делаете в коде. Код вроде сама документация. Когда вы не можете прочитать его, нужна документация.

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

4
ответ дан 14 февраля 2018 в 10:02 Источник Поделиться

Во-первых, два вопроса:

1) верно ли, что обрабатывается пустое поле как поле, содержащее ноль? Это, кажется, противоречит требованиям.

2) нет определенных требований, если оба поля заполнены, даже не, что они должны быть числами. Это правильно?


Повторяющегося кода

У вас есть много повторяющегося кода, особенно:

var tempbar = $.trim($('#bar').val());
var bar = tempbar.length > 0 ? parseInt(tempbar, 10) : 0;

Это относится к функции:

function parseIntegerValue(selector) {
var value = $.trim($(selector).val());
return value.length > 0 ? parseInt(value, 10) : 0;
}

Также во второй строке может быть упрощена с помощью унитарного + оператор, который преобразует строку в число и возвращает 0 на пустую строку:

function parseIntegerValue(selector) {
var value = $.trim($(selector).val());
return +value;
}


Игнорирование ошибочных чисел

Вы игнорируете случае недопустимых значений. parseInt возвращает NaN если строка не содержит действительный номер. И так NaN === 0 возвращает значение false, поле не будет по сравнению с его минимальным количеством, если другие подали содержит недопустимое количество.


Зависит от функции

В зависимости от функции вы излишне проверка текущего поля. Если другие поля не пустое, то неважно, что текущее поле содержит.

Так foo он может быть упрощен до

 depends: function(element) {
var tempbar = $.trim($('#bar').val());
var bar = tempbar.length > 0 ? parseInt(tempbar, 10) : 0;
return bar === 0;
}

2
ответ дан 14 февраля 2018 в 10:02 Источник Поделиться