Публикация

Хакинг BPMonline: отмена валидации объекта

Допустим у вас стоит задача : не выполнять валидацию обязательности полей при определённом условии.

Валидация обязательности полей объекта происходит на нескольких уровнях:
1) на клиенте
2) на сервере на уровне приложения
3) на сервере на уровне базы

Как справиться с 1) и 2) - читайте ниже
На клиенте в браузере используется механизм Ext.FormValidator.validate(), который вы можете обнаружить в обработчиках событий кнопок ОК и Применить. Соответственно нужно убрать эту проверку из обработчика при данном условии, и восстанавливать, если данное условие не верно.
Для 2) можно либо перекомпилировать объект-схему, либо сделать так, как показано в конце
Для 3) можно только перекомпилировать объект-схему, но тогда поле станет необязательным всегда. Если это не подходит, поле должно быть обязательным на уровне базы и в то же время нужно реализовать задачу выше, то дальше можно не читать.

Сначала создадим глобальные переменные, которые будут указывать на оригинальные функцию нажатия на кнопки ОК и Применить где-то на PageLoadComplete

OKFunctionClientScript = "window.okscript"+Guid.NewGuid().ToString("N");
ApplyFunctionClientScript= "window.applyscript"+Guid.NewGuid().ToString("N");
Page.AddScript( OKFunctionClientScript + " = undefined");
Page.AddScript( ApplyFunctionClientScript + " = undefined");

далее на изменение какого-либо параметра\поля\логики делаем следующие скрипты:
Нижеприведенный скрипт сохранить в глобальные переменные оригинальные функции

string NewOkApplyScript = @"  
if ({1} === undefined){{
  if (typeof {0}.events.click === 'object') {{
    if ({0}.events.click.listeners.length === 1 ) {{
        var okClickFunc = {0}.events.click.listeners[0].fireFn;
        if (okClickFunc !=undefined) {{
        {1} = okClickFunc.toString();
        }}
     }}
   }}
}}"
;
Page.AddScript(string.Format(NewOkApplyScript, Page.OKButton.ClientID, OKFunctionClientScript ));
Page.AddScript(string.Format(NewOkApplyScript, Page.ApplyButton.ClientID, ApplyFunctionClientScript ));

А этот скрипт собственно либо удаляет Ext.FormValidator из текст функции клика, либо возвращает старую функцию из глобальной переменной

NewOkApplyScript = @" if (typeof {0}.events.click === 'object') {{
   if ({0}.events.click.listeners.length === 1 ) {{
     var okClickFunc = {0}.events.click.listeners[0].fireFn;
     if (okClickFunc !=undefined) {{
     var funcOkClickstr = okClickFunc.toString();
     if ({1}) {{
        funcOkClickstr = funcOkClickstr.replace('Ext.FormValidator.validate()', 'true');
        funcOkClickstr = funcOkClickstr.replace('Ext.FormValidator.validate(false)', 'true');
        }} else {{
        funcOkClickstr = {2} ;
        }}
        eval('{0}.events.click.listeners[0].fireFn = ' + funcOkClickstr);
    }}
    }}
}}"
;
                               
if (условие соблюдается>) {
Page.AddScript(string.Format(NewOkApplyScript, Page.OKButton.ClientID , "true", OKFunctionClientScript));
Page.AddScript(string.Format(NewOkApplyScript, Page.ApplyButton.ClientID, "true" , ApplyFunctionClientScript));
} else {
Page.AddScript(string.Format(NewOkApplyScript, Page.OKButton.ClientID , "false", OKFunctionClientScript));
Page.AddScript(string.Format(NewOkApplyScript, Page.ApplyButton.ClientID, "false" , ApplyFunctionClientScript));
}

И ещё по кнопке ОК можно добавить отмену обязательности полей при соблюдении условия

if (условие соблюдается>)
        foreach (var column in Page.DataSource.Schema.Columns){
                column.RequirementType = EntitySchemaColumnRequirementType.None;
        }

Нравится

Поделиться

1 комментарий

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

Page.ScriptManager.AddScript("if (" + Page.DataSource.ClientID + ".activeRow.modifiedValues) {" 
			+ Page.DataSource.ClientID + ".save(); "  +
		"} else { window.close(); }"
	);
IsWindowClose = true;
Показать все комментарии