Проверка табличной формы без отправки

#oracle-apex

#oracle-apex

Вопрос:

В APEX 3.2 я хочу иметь возможность запускать проверки JavaScript для проверки введенных данных и отображения соответствующего сообщения над каждой строкой в табличной форме.

Я не уверен, как это будет работать, учитывая, что это табличная форма, и пользователь сможет добавлять / удалять строки.

Ценю любые идеи или предложения.

Спасибо.

Ответ №1:

Хорошо, выполнение некоторых проверок javascript для табличных форм немного сложно, и вам нужно знать, что вы делаете.

Прежде всего, вам нужно будет знать идентификаторы или названия элементов, которые вы хотите проверить. Как вы, возможно, знаете, элементы табличных форм хранятся в массивах в apex при отправке, и доступ к ним осуществляется через apex_application.g_f01/g_f02/... Это отражено в html-коде, и сгенерированные элементы также имеют атрибут ‘name’, установленный для столбца, к которому они принадлежат. Идентификатор также содержит столбец плюс rowindex. Однако внимание, этот идентификатор генерируется подобным образом только тогда, когда элемент создается «неявно», т. Е. вы не писали свой запрос с помощью вызовов apex_item ( apex_item.textbox(...) ).

Другое «но» заключается в том, что столбец массива будет определен только для полей, состояние которых сохранено. Элемент, который вы бы отображали только как «только для отображения», не будет сгенерирован с помощью тега ввода и будет просто сохранен в виде текста в теге td.

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

 <tr class="highlight-row">
<td headers="CHECK$01" class="data"><label for="f01_0003" class="hideMeButHearMe">Select Row</label><input type="checkbox" name="f01" value="3" class="row-selector" id="f01_0003" /></td>
<td headers="EMPNO_DISPLAY" class="data">7782</td>
<td headers="ENAME" class="data"><label for="f03_0003" class="hideMeButHearMe">Ename</label><input type="text" name="f03" size="12" maxlength="2000" value="CLARK"  id="f03_0003" /></td>
<td headers="JOB" class="data"><label for="f04_0003" class="hideMeButHearMe">Job</label><input type="text" name="f04" size="12" maxlength="2000" value="MANAGER"  id="f04_0003" /></td>
<td headers="HIREDATE" class="data"><label for="f05_0003" class="hideMeButHearMe">Hiredate</label><span style="white-space: nowrap;"><input type="text"  id="f05_0003" name="f05" maxlength="2000" size="12" value="09-JUN-81" autocomplete="off"></span></td>
<td headers="SAL" class="data">
   <label for="f06_0003" class="hideMeButHearMe">Sal</label><input type="text" name="f06" size="16" maxlength="2000" value="2450"  id="f06_0003" />
   <input type="hidden" name="f02" value="7782"  id="f02_0003" />
   <input type="hidden" id="fcs_0003" name="fcs" value="19BD045E01D6BA148B4DEF9DDC8B21B7">
   <input type="hidden" id="frowid_0003" name="frowid" value="AAuDjIABFAAAACTAAC" />
   <input type="hidden" id="fcud_0003" name="fcud" value="U" />
</td>
</tr>
  

Затем я добавил следующие 2 функции в раздел javascript страницы.

validate_job выполняет проверку только одного поля, элемента elJob. Проверка, которую я использовал, очень простая, вам решать, насколько сложной она вам нужна.

Если вы хотите ссылаться здесь на другие поля в той же строке, вы можете сделать несколько вещей: извлечь rowindex из идентификатора, если он у вас есть. Если она не содержит it, получите родительский TR, а затем используйте .children("input[name='f##'") для получения элемента ввода в той же строке. Или, если вам нужно значение элемента, состояние которого вообще не сохраняется, вам нужно получить элемент TR, а затем найти TD, содержащий нужный вам элемент, с помощью атрибута headers, который содержит имя столбца.

 function validate_job(elJob){
   var sJob = $v(elJob).toUpperCase();
   $(elJob).val(sJob);

   //do your validations for the field job here
   if(sJob=="MANAGER"){
      $(elJob).css({"border-color":"red"});
      alert("invalid value!");
      //depends what you want to do now:
      //keep the focus on this element? Set a flag an error occured? Store the error?      
      return false;
   } else {
      $(elJob).css({"border-color":""});
      alert("value ok");                
        };
};
  

Вызовите bind_validations onload. Если вы разрешаете создавать строки, привяжите событие click к кнопке addrow и вызовите bind_validations.

 function bind_validations(){
   //f01 : row selector
   //f03 : ename
   //f04 : job
   //f05 : hiredate
   //f06 : sal

    //each input element with attribute name with value f04
   //blur event is when the user leaves the field, fe tab out, or even click apply changes
   //much like how when-validate-item behaved in forms
   $("input[name='f04']").blur(function(){validate_job(this);});
};
  

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

Когда ваша аудитория больше, становится немного сложнее: какой у меня javascript отключен? Что, если они найдут какой-то обходной путь? Wizzkids?

Мне по-прежнему нравится немедленная обратная связь, которую она дает, но в более критичной среде я бы также использовал проверки на стороне сервера. Для этого вам необходима проверка типа «функция, возвращающая текст ошибки». Ознакомьтесь с примером на этой странице или на этой с некоторыми полезными советами (по крайней мере, для версии до версии 4.0!). Также: apex 4.1 действительно значительно улучшает проверку табличной формы! 😉