La forma correcta de hacer esto, es hacer una validación asincrónica.
Para hacer esto, se declara la función de validación tradicional en el presentation PHP. El cambio viene en la parte de Javascript.
Para hacer que el framework interprete que la validación es asincrónica, la función DEBE retornar el string "async". Si retorna OTRA COSA, se lo considera un mensaje de error de una función de validación sincrónica.
Veamos un ejemplo sencillo, donde simulamos un evento asincrónico mediante un setTimeout().
En el constructor del presentation ponemos:
$fld = $parent;
$fld->m_js_validate = "organizaciones.validate";
Esto indica que para validar, vamos a buscar un objeto "organizaciones" que implementa un método "validate".
El javascript es este:
function organizaciones_validate() {
this.fieldID = "";
this.callback = null;
this.validate = function(fieldID,FieldLabel,callback) {
this.fieldID = fieldID;
this.callback = callback;
setTimeout(this.async_validate, 1000);
return "async";
};
this.async_validate = function () {
organizaciones.callback(organizaciones.fieldID, false, "Un error simulado");
};
}
var organizaciones = new organizaciones_validate();
La función "validate" recibe como parámetros, el ID del campo, el Label y una función de callback para informar, cuando sea oportuno del resultado de la validación.
En el ejemplo, salvamos los datos del ID del campo que vamos a necesitar cuando tengamos la respuesta, y la función de callback. Disparamos un timer que ejecutará la función "async_validate" un segundo mas tarde.
Al ejecutar "async_validate", vamos a llamar a la función de callback, pasando como parámetros el ID del campo, si la validación terminó bien (true) o mal (false) y un mensaje de error.
La ejecución del proceso de validación va a esperar que todas las funciones de validación asincrónicas terminen de ejecutar, antes de mostrar el mensaje de error o bien continuar y salvar el formulario.
Exactamente igual es el caso de un editor de un tabla.
Si vamos a usar un ajax, seguramente vamos a reemplazar a setTimeout por $.ajax() pero el resto del código es idéntico.