Публикация

Проверка обязательных строковых полей

Проблема:
При сохранении карточки редактирования в обязательном строковом поле хранится некоторое значение. Однако иногда это значение неизвестно и для того что бы его заполнить клиент использует значение 00000000. И (внимание на экран) система не позволяет ему это сделать с сообщением, что это поле является обязательным. Естественно клиента это очень расстраивает.

Исправление:
В скрипте scr_BaseDBEditUtils изменить функцию CheckRequiredDataControl и сделать отдельную проверку для строковых полей. Готовый пример

function CheckRequiredDataControl(Control, DatasetLink) {
 var DataField = DatasetLink.Dataset.DataFields(Control.DataFieldName); 
 if ((Assigned(DataField)) && (DataField.IsRequired)) {
  var FieldType = DataField.FieldType;
  if ((FieldType != dftBool) && (FieldType != dftEnum)) {
   if (FieldType == dftString){
    var Condition = !IsEmptyValue(DataField.Value) &&
     !IsEmptyStr(DataField.Value); 
   } else {
    var Condition = !IsEmptyValue(DataField.Value) &&
     (DataField.Value != 0);   
   }
  } else {
   var Condition = (DataField.Value != null);
  }
  var FieldName = DataField.Caption;  
  return CheckRequiredControlCondition(Control, Condition, FieldName);
 } else {
  return true;
 }
}

Нравится

Поделиться

17 комментариев

По-моему достаточно в оригинальной версии заменить

DataField.Value != 0 

на

DataField.Value !== 0

И вот это сравнение для строк избыточно

var Condition = !IsEmptyValue(DataField.Value) &&
     !IsEmptyStr(DataField.Value);

Достаточно

var Condition = !IsEmptyValue(DataField.Value); 

Для сравнения строк логичнее было бы делать:

var Condition = !IsEmptyStr(DataField.ValAsStr);

И я бы рекомендовал еще и Trim делать, дружелюбнее :) :

var Condition = !IsEmptyStr(Trim(DataField.ValAsStr));

Очень приятно, что тема вызвала такое живое обсуждение. Предложение к Александру: может стоит изменить поведение CheckRequiredDataControl в базовой версии?

Разрешаю:)

Проснулся во мне сегодня дух противоречия :)

"Осауленко Александр" написал:Для сравнения строк логичнее было бы делать

IsEmptyStr(null) возвращает false. Так что в данном контексте привильнее все таки использовать IsEmptyValue.
"Осауленко Александр" написал: я бы рекомендовал еще и Trim делать

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

"Underscore a.k.a. _" написал:
IsEmptyStr(null) возвращает false

DataField.ValAsStr не может вернуть null
"Underscore a.k.a. _" написал:
Если есть строка ' ' является ли она пустой

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

"Осауленко Александр" написал:DataField.ValAsStr не может вернуть null

Согласен, просто в приведенном решении было DataField.Value.

Upd: у Вас было ValAsStr, извините, не заметил.

"Осауленко Александр" написал:Для пользователя да. Для программиста - нет конечно.

Так я как раз о пользователе говорю, фиг с ними с программистами :)

"Underscore a.k.a. _" написал:
Согласен, просто в приведенном решении было DataField.Value.

Не понял:) В моем вроде написано ValAsStr
"Underscore a.k.a. _" написал:
Так я как раз о пользователе говорю, фиг с ними с программистами :)

Так и я о пользователях. Пользователь не видит, что в поле Name он случайно нажал пробел, и вместо того чтобы система выдала предупреждение "Заполните поле Name", дала ему сохранить карточку.

"Осауленко Александр" написал: В моем вроде написано ValAsStr

Да, я уже заметил и пост свой подправил, но Вы оказались проворнее :)
"Underscore a.k.a. _" написал:Так и я о пользователях.

Нет, после обеда придумать пример где пробел несет смысловую нагрузку... я пас :) Единственный аргумент кторый приходит в голову это то что во всех известных мне СУБД в поле not null пробел вставить можно. Но мне он самому особо убедительным не кажется :)

Послушал я тут Вас и решил что нужно это перенести в базовую версию. :)

Вот окончательный вариант:

function CheckRequiredDataControl(Control, DatasetLink) {
	var DataField = DatasetLink.Dataset.DataFields(Control.DataFieldName);	
	if (Assigned(DataField) && DataField.IsRequired) {
		var FieldType = DataField.FieldType;
		var Condition;
		if ((FieldType == dftBool) || (FieldType == dftEnum)) {
			Condition = (DataField.Value != null);
		} else
		if (FieldType == dftString) {
			 Condition = !IsEmptyStr(Trim(DataField.ValAsStr));		
		} else {
			Condition = !IsEmptyValue(DataField.Value) && (DataField.Value != 0);						
		}		
		var FieldName = DataField.Caption;		
		return CheckRequiredControlCondition(Control, Condition, FieldName);
	} else {
		return true;
	}
}

Появиться в сборках 3.3.0.50 и 3.3.1.20.

Вот и замечательно :)

Так уже тогда бы switch использовали вместо if else.

"Underscore a.k.a. _" написал:Так уже тогда бы switch использовали вместо if else.

Это уже не важно. Есть еще как минимум 5 способов как это можно сделать. Но суть от этого не поменяеться.

Кстати, не заметили, ошибку: какой смысл делать, а потом еще и проверять обязательное логическое поле?

Тут скорее ошибка в том что чекбокс не поддерживает третье состояние.

"Осауленко Александр" написал:Кстати, не заметили, ошибку: какой смысл делать, а потом еще и проверять обязательное логическое поле?

Ты прав! Вот учел все пожелания :)

function CheckRequiredDataControl(Control, DatasetLink) {
	var DataField = DatasetLink.Dataset.DataFields(Control.DataFieldName);	
	if (!Assigned(DataField) || !DataField.IsRequired) {
		return true;
	}
	var Condition;
	switch (DataField.FieldType) {
		case dftEnum:
			Condition = (DataField.Value != null);
			break;
		case dftString:
			Condition = !IsEmptyStr(Trim(DataField.ValAsStr));		
			break;
		default:
			Condition = !IsEmptyValue(DataField.Value) && (DataField.Value != 0);						
	}		
	return CheckRequiredControlCondition(Control, Condition, DataField.Caption);
}

Поменял в базовых версиях 3.3.0 и 3.3.1.

А зачем вообще DatasetLink?

var DataField = Control.DataField;

Тем более что в общем случае Control может быть не привязан к DatasetLink и

var DataField = DatasetLink.Dataset.DataFields(Control.DataFieldName);

выглядит просто не логично без проверки того что Control привязан к DatasetLink.

Показать все комментарии