BPM, Workflow, and Case

Recipe: Validate IBM BPM or BAW Coach Data in a General Way (without boundary event)

By HUGO HERNANDEZ MORA posted Mon September 13, 2021 04:52 PM

  

Use the properties of the spark controls and utilities such as getters and setters to validate the input values through a general function.


Overview

Skill Level: Intermediate

This recipe shows how to use the properties of the Spark controls to perform the validation in a general way using a set of objects to provide information to the function, which may be generic for many business scenarios.

Ingredients

  • IBM BPM / IBM BAW
  • Spark UI

Step-by-step

  1. This demo is based on registering an applicant's data, for example, for a student scholarship process

     

    • First, we create a business object that contains attributes of types text, integer and dates

     

    1

     

    • Create a Client Side Human Service to be used for validation demo

     

    1. 2

     

    • In Initialization script we initiate and set defaults

     

    3

     

    • And create a Coach View for Register the applicant. Using the grid to distribute the controls

     

    4

     

    5

     

    The control types for the attributes of the BO are:

    • Text for Name, Last Name and e-mail
    • Integer for Years of Experience
    • Single Select for Level of Stud
    • Date Picker for Birth Date

     

     

    Each control is assigned binding and, very importantly, the coach view id should be set as part of the functionality

     

    6

     

     

    • For control single select put a static list

     

    7

     

     

     

  2. Now we perform the behavior

     

    Definitions

     

    • To activate the validation we put the function call in the button click event, remember that the boundary event will not be performed if the function returns false

     

    9

     

     

    Next, we create objects (getter) to hold the information for the function

    Each attribute should be the name of each property of the object

    (this definition may be in the Load section and must go first in the sequence)

     

    OBJECTS FOR THE DEFINITION OF FUNCTIONALITY

     


    //The usual
    var _this = this;


    // TO GET THE VALUES


    this.ambit = {
    get name(){
    return _this.context.binding.get("value").get("name");
    },
    get lastName(){
    return _this.context.binding.get("value").get("lastName");
    },
    get birthDate(){
    return _this.context.binding.get("value").get("birthDate");
    },
    get yearsOfExpeience(){
    return _this.context.binding.get("value").get("yearsOfExpeience");
    },
    get levelOfStudy(){
    return _this.context.binding.get("value").get("levelOfStudy");
    },
    get email(){
    return _this.context.binding.get("value").get("email");
    }
    }



    // TO GET THE INSTANCE OR CLASS OF EACH CONTROL (1)



    this.interfaz = {
    get name(){
    return _this.ui.get('name');
    },
    get lastName(){
    return _this.ui.get('lastName');
    },
    get birthDate(){
    return _this.ui.get('birthDate');
    },
    get yearsOfExpeience(){
    return _this.ui.get('yearsOfExpeience');
    },
    get levelOfStudy(){
    return _this.ui.get('levelOfStudy');
    },
    get email(){
    return _this.ui.get('email');
    }
    }


    // VALIDATION MESSAGES


    this.messages = {
    get name(){
    return 'Name in Requiered';
    },
    get lastName(){
    return 'LastName is Requiered';
    },
    get birthDate(){
    return 'Birth of Date is Requiered';
    },
    get yearsOfExpeience(){
    return 'Years of Experience Must be Greater Than 0';
    },
    get levelOfStudy(){
    return 'A Level of Study Must be Selected';
    },
    get email(){
    return 'e-Mail is Required and it Must be Valid';
    }
    }



    // AND THE VALUES TO PERFORM THE VALIDATION (beyond the presence of value)


    this.verification = {
    get yearsOfExpeience(){
    var mapa = new Map();
    mapa.set('minimo', 1);
    return mapa;
    },
    get email(){
    var mapa = new Map();
    mapa.set('expresionRegular', /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/i);
    return mapa;
    },
    get levelOfStudy(){
    var mapa = new Map();
    mapa.set('valorInicial', '_NA');
    return mapa;
    }
    }

     

     

     

    THE FUNCTION TO VALIDATE

     

    In this function concepts of ‘closure’ and objects such as maps are used for greater functionality (2)

    This function is in in-line script

     

     

     



    // MAIN FUNCTION




    this.Validation = function(ambito, interfaz, mensajes, verificacion) {
    this.ambito = ambito;
    this.interfaz = interfaz;
    this.mensajes = mensajes;
    this.verificacion = verificacion;
    this.item = '';
    this.relacion = new Map;
    this.validated = false;
    this.aviso = '';
    this.tipos = ['Text', 'Integer', 'Single_Select', 'Date_Picker'];
    this.verificar = function() {
    var ok = true;
    if (this.relacion.size > 0) {
    ok = false;
    }
    this.validated = ok;
    }
    this.resultado = function() {
    var mensajeResultado = this.mensajes['mensajeResultado'];
    var elementos = '';
    for (var elemento of this.relacion.keys()) {
    elementos += this.relacion.get(elemento) + '\n\n';
    }
    this.aviso = mensajeResultado + '\n\n\n' + elementos
    }
    this.valido = function() {
    this.control.setValid(true);
    if (this.relacion.has(this.item)) {
    this.relacion.delete(this.item)
    }
    }
    this.invalido = function() {
    var mensaje = this.mensajes[this.item];
    this.control.setValid(false, mensaje);
    if (!this.relacion.has(this.item)) {
    var etiqueta = this.control.context.options._metadata.label.get("value");
    this.relacion.set(this.item, etiqueta);
    }
    }

    this.validaExpresion = function(valor) {
    var ok = true;
    var expresion = null;
    var verificacion = this.verificacion[this.item];
    if (verificacion.has('expresionRegular')) {
    expresion = verificacion.get('expresionRegular');
    ok = expresion.test(valor);
    }
    return ok;
    }
    this.texto = function() {
    var path = this.control.context.binding.boundObject._objectPath;
    var propiedad = this.control.context.binding.property;
    var valor = this.control.context.binding.boundObject[propiedad];
    var ok = true;
    if (this.verificacion[this.item] && this.verificacion[this.item].has('expresionRegular')) {
    ok = this.validaExpresion(valor);
    }
    if (valor && ok) {
    this.valido();
    } else {
    this.invalido();
    }
    }
    this.entero = function() {
    var path = this.control.context.binding.boundObject._objectPath;
    var propiedad = this.control.context.binding.property;
    var valor = this.control.context.binding.boundObject[propiedad];
    var verificacion = this.verificacion[this.item];
    var valorMinimo = 0;
    if (verificacion && verificacion.has('minimo')) {
    valorMinimo = verificacion.get('minimo');
    }
    if (valor >= valorMinimo) {
    this.valido();
    } else {
    this.invalido();
    }
    }
    this.fecha = function() {
    var path = this.control.context.binding.boundObject._objectPath;
    var propiedad = this.control.context.binding.property;
    var valor = this.control.context.binding.boundObject[propiedad];
    var ok = true;
    if (valor && ok) {
    this.valido();
    } else {
    this.invalido();
    }
    console.log(path, propiedad, valor, 'fecha');
    }
    this.seleccion = function() {
    var propiedad = this.control.context.binding.property;
    var valor = this.control.context.binding.boundObject[propiedad];
    var par = (Object.getOwnPropertyDescriptor(valor, 'name') && Object.getOwnPropertyDescriptor(valor, 'value'));
    if (par) {
    var verificacion = this.verificacion[this.item];
    var valorInicial = '';
    if (verificacion.has('valorInicial')) {
    valorInicial = verificacion.get('valorInicial');
    }
    if (valor.value != '' && valor.value != valorInicial) {
    this.valido();
    } else {
    this.invalido();
    }
    }
    }
    this.revisar = function() {
    var propiedades = Object.keys(this.ambito);
    for (propiedad in this.ambito) {
    var valor = this.ambito[propiedad];
    if (!valor) {
    this.interfaz[propiedad].setValid(false, 'AA');
    }
    }
    }
    this.findClase = function() {
    var clase = '';
    for (var i = 0; i < this.control.context.element.classList.length; i++) {
    if (this.tipos.indexOf(this.control.context.element.classList[i]) >= 0) {
    clase = this.control.context.element.classList[i];
    }
    }
    return clase;
    }
    this.validate = function(itemRevisar) {
    for (item in this.interfaz) {
    this.item = item;
    if (itemRevisar && this.item != itemRevisar) {
    continue;
    }
    this.control = this.interfaz[item];

    function findClase(clase) {
    return this.tipos.indexOf(clase) > -1;
    }
    var clase = this.findClase();
    if (clase == 'Text') {
    this.texto();
    }
    if (clase == 'Integer') {
    this.entero();
    }
    if (clase == 'Single_Select') {
    this.seleccion();
    }
    if (clase == 'Date_Picker') {
    this.fecha();
    }
    }
    this.verificar();
    this.resultado();
    }
    }




    // THE FUNCTION TO PERFORM THE VALIDATION




    this.validate = function(){

    this.validation = new this.Validation(this.ambit, this.interfaz, this.messages, this.verification);
    this.validation.validate();

    return this.validation.validated;

    }
    this.revision = function(elemento){

    if (!this.validation){
    this.validation = new this.Validation(this.ambit, this.interfaz, this.messages, this.verification);
    }
    this.validation.validate(elemento.context.viewid);

    }
  3. And run the human service and click on the button

    Controls that have not been filled or do not meet the validation values will be shown in validation mode

     

    10

    The validation message will be displayed

     

    11

     

     

    For validation to be performed when the user writes to a control the revision function is called which invokes the validation function for the control

     

    12

  4. Conclusion

     

    So, in this recipe we can know the properties that allow us to carry out the validation in a general way and, for example, if we had to add a control, it would be enough to add the entry in the objects (getters) and set then name to the control appropriately.

     

     

    References

    1) https://support.salientprocess.com/docs/enterprise/bpmext.ui.html

    2) https://javascript.info/map-set

     


#BusinessAutomationWorkflow(BAW)
#BusinessProcessManager(BPM)
#baw
#BPM
#Coaches

Permalink