Refresco de pestaña principal desde opcion de menu o boton de barra


([N4] José A. Martínez) #1

Hola a todos. Tengo un problemilla que “quizá” pueda resolverse con JS, pero yo de JS ni idea, por eso acudo al foro (a propósito, después de un par de horas leyendo cosas sobre JS, theApp, theRoot y no se cuantas cosas mas, me he quedado peor que estaba, no me he enterado de nada). Lo del JS mas me vale tomármelo con calma…

Al grano.

Tengo el típico formulario/menú que abro en una pestaña principal de la aplicación. El objeto principal del formulario es una vista de datos con una rejilla.

En el menú de la aplicación (y en un botón de una barra de botones) tengo una opción que añade un registro a la tabla mostrada en el formulario anterior.

El problema es que al dar el alta desde el menú (o la barra) lógicamente no se refresca al formulario (no hay conexión entre las opciones del menú y la pestaña…). En el formulario tengo un manejador de evento llamado REFRESCAR() que simplemente llama a “Interfaz: Recalcular(VD)”…

Después de dar el alta desde el menú o el botón, me vendría muy bien poder refrescar la rejilla del formulario, SOLO SI ESTA ABIERTO Y ESTA ACTIVO (TIENE EL FOCO). En otro caso no necesito refrescar…

¿Es posible? He logrado código JS muy guarro que me detecta si la pestaña activa es mi formulario de marras, pero a partir de ahí me pierdo… no se que objeto debo referenciar (la vista de datos, supongo), ni como hacerlo, y a tampoco se si una vez referenciado podre refrescarlo, ni como hacerlo…

¿Se puede disparar un manejador de evento de un formulario abierto en una pestaña desde JS? Eso me valdría, creo…

Gracias por anticipado…


([N3] pacosatu) #2

Hola José.

Sería tan fácil como vincular un control del formulario (por ejemplo un checkbox) a una variable global (por ejemplo $REFRESCAR) y en el Evento “Value changed” del checkbox Recalcular la Vista de Datos. Pero lamentablemente e incomprensiblemente esto no funciona.

Así que debes coger otro evento, por ejemplo el Evento “Gana Foco” de la Rejilla. De esta forma no refrescas automáticamente, solo cuando el Usuario selecciona la Rejilla y $REFRESCAR = 1. Aunque en general mi experiencia con los eventos de Velneo está siendo una pesadilla.
Espero que los betatester de la 7.15 hayan dado buena cuenta de este comportamiento tan caótico.

Con JavaScript quizás puedas hacerlo, pero tienes que conocer antes muy bien el modelo de objetos y el API de Velneo. Yo personalmente también considero que hacer cosas tan básicas con JavaScript es ensuciar el código y debería de poder hacerse con comandos Velneo. Ahora mismo no sé si existe el equivalente en JS del comando Recalcular del Interface de Velneo, yo no lo he encontrado.

Saludos
Paco Satué


([N1] wikan) #3

Buenas, si has llegado al formulario de la vista activa, puedes obtener el botón que realiza el refresco y simulador el click.
http://velneo.es/info_v7_714_es/velneo_vdevelop_v7/scripts/clases/vpushbutton/#click


([N3] pacosatu) #4

Hola Manuel.

Me ha gustado mucho lo de usar el click() como intermediario para ejecutar Manejadores de Eventos de los formularios, muy ocurrente.

Entonces el código javascript podría quedar de la siguiente manera:
Proceso JavaScript con la variable FRM_IDREF igual al identificador del formulario que queremos refrescar, por ejem “0PS_Ejercicios_app/FRM_CABECERAS”.


var nNumVistas = theMainWindow.viewsCount();
var oVista = null, oForm = null, oInfo = null, oBoton = null;
var lExiste = false

for (nVista = 0; nVista < nNumVistas; nVista++) {
oVista = theMainWindow.getViewAt(nVista);
if (oVista) {
oInfo = oVista.centralWidget().objectInfo();
if (oInfo.idRef() == theRoot.varToString(“FRM_IDREF”)) {
// Se ha encontrado el formulario
lExiste = true;
break;
};
};
};

if (lExiste) {
oForm = oVista.centralWidget();
// Suponemos que el botón que Recalcula la Vista de Datos se llama REFRESCAR
oBoton = oForm.control(“REFRESCAR”).click();
};

Este proceso se dispararía después de añadir el registro desde la Acción del Menú, asignando previamente el nombre del formulario a la variable FRM_IDREF.
En este caso, mejor usar JavaScript que pelearse con los eventos de Velneo.

Saludos
Paco Satué


([N4] José A. Martínez) #5

Bueno, pues funciona… Segunda vCerveza para Paco (en el ultimo mes). Esta compartida con Manuel… Si os pasáis por Gijón prometo pagarlas gustoso…

Solo he tenido que hacer un retoque en el código de Paco:
donde el ponía
if (oInfo.idRef() == theRoot.varToString(“FRM_IDREF”)) {
tuve que cambiarlo por
if (oInfo.idRef() == “MIAPP/AVISOS_EN_CURSO_MENU”) {

El código de mi script al final queda así:

var nNumVistas = theMainWindow.viewsCount();
var oVista = null, oForm = null, oInfo = null, oBoton = null;
var lExiste = false
for (nVista = 0; nVista < nNumVistas; nVista++) {
oVista = theMainWindow.getViewAt(nVista);
if (oVista) {
oInfo = oVista.centralWidget().objectInfo();
if (oInfo.idRef() == “MIAPP/AVISOS_EN_CURSO_MENU”) {
// Se ha encontrado abierto el formulario AVISOS_EN_CURSO_MENU en MIAPP
lExiste = true;
break;
};
};
};

if (lExiste) {
oForm = oVista.centralWidget();
// Suponemos que el botón que Recalcula la Vista de Datos se llama B_RECALCULAR
oBoton = oForm.control(“B_RECALCULAR”).click();
};

Simplemente lo ejecuto con EjecutarProceso() en 1er plano después de hacer las altas y listo…


([N3] blavan) #6

Este foro empieza a estar vivo y es casi imprescindible su lectura diaria.
Mi aportación a la rutina anterior.
En lugar del botón refrescar continuo con JS

importClass( “VQuery” );

// Se crea el objeto búsqueda
var busqueda = new VQuery(theRoot);
busqueda.setQuery(“aliasproyecto/busqueda”); // aqui pondría la busqueda correspondiente
// Preparamos el control de la rejilla limpiando los datos que tenga);
var controlRejilla = oForm.control(“LST”);// LST es el identf. de la vista

controlRejilla.clear();

// Se ejecuta la búsqueda y los registros encontrados se añaden a la salida
if (busqueda.exec())
{
// Le pasamos los resultados a la rejilla
controlRejilla.append(busqueda.result());
var lista = new VRegisterList( theRoot );
controlRejilla.getList( lista );
// ejemplo de ordenar la rejilla por un campo
var listaOrdenada = lista.sort(“NAME”,0);
controlRejilla.setList( lista );

};


([N4] velavisual) #7

@Hola_a_tod@s

Basándome en el código anterior de Paco intento ejecutar un botón REFRESCAR de un sub-control formulario que pertenece a un separador de formularios, y no doy con la tecla.

¿Alguna pista de cómo obtener el sub-control?

Gracias,


([N3] pacosatu) #8

Hola Antonio.

Prueba de la siguiente manera:


// Manejador JS llamado desde el formulairo principal y desde el que queremos refrescar una Pestaña
// Formulario principal que contiene el Separador 
var oForm = theRoot.dataView()

// Separador de formularios (clase del API VTabWidget)
var oSeparador = oForm.control("SEPARADOR")

// Pestaña que queremos refrescar (suponemos que es la segunda)
var oPestana2 = oSeparador.form(1)

// Botón que se encarga de refrecar la pestaña
var oBoton = oPestana2.control("CMD_REFRESCAR")

// Ejecutamos el evento click() del Botón
oBoton.click()

Pruébalo.
Saludos
Paco Satué


([N4] velavisual) #9

@seh

Gracias Paco.De la forma que lo enfocas está perfecto aún sin haberlo probado.

El caso es que lo necesito para asignarlo a un proceso y ejecutar éste desde cualquier punto mediante un manejador de objetos con los parámetros correspondientes.

He realizado un churro pero no me acaba de funcionar correctamente.No aplico las clases necesarias de forma correcta.


/ Ejecutar Botón de una vista TAB
// FRM_IDREF = formulario a buscar en las vistas activas
// SEP_FORM = Separador de formularios
// SUBFRM = subformulario a buscar
// REFRESCAR = Botón que hay que ejecutar

var nNumVistas = theMainWindow.viewsCount();
var oVista = null, oForm = null, oInfo = null, oBoton = null;
var lExiste = false

for (nVista = 0; nVista < nNumVistas; nVista++) {
  oVista = theMainWindow.getViewAt(nVista);	
  if (oVista) {
    oInfo = oVista.centralWidget().objectInfo();
    if (oInfo.idRef() == theRoot.varToString("FRM_IDREF")) {
      // Se ha encontrado el formulario
      lExiste = true;
	  break;
    };
  };
};

if (lExiste) {
// Separador de formularios (clase del API VTabWidget)	
var oSeparador=theRoot.varToString("SEP_FORM");
	alert(oSeparador);
var oSubform=theRoot.varToString("SUBFRM");
	alert(oSubform);
	
	// A partir de aqui error

	// Buscar subformulario
	oBuscar=oSubform.findForm("SUBFRM");
	oActivar=oSubform.setFormEnabled(oBuscar,1);
	oSubformActivo=oSubform.setFormEnabled(oActivar,1);
		
	alert (oSubformActivo);
	if (oSubformActivo){
	oBoton= oSubformActivo.control("REFRESCAR");
	oBoton.click();
		
	};
	break;
};

Gracias por tu ayuda.


([N3] pacosatu) #10

Hola Antonio.

¡¡Vaya churro!! es imposible que eso funcione.
Bueno, es broma.

Prueba esto:


// Ejecutar Botón de una vista TAB
// FRM_IDREF = formulario a buscar en las vistas activas
// SEP_FORM  = Separador de formularios
// SUBFRM    = Subformulario a buscar
// CMD_REFRESCAR = Id del Botón que hay que ejecutar

var nNumVistas = theMainWindow.viewsCount();
var oVista = null, oInfo = null, oBoton = null;
var oSeparador = null, oSubform = null, oBoton = null;
var lExiste = false, nIndice = -1;

for (nVista = 0; nVista < nNumVistas; nVista++) {
   oVista = theMainWindow.getViewAt(nVista);	
   if (oVista) {
      oInfo = oVista.centralWidget().objectInfo();
      if (oInfo.id() == theRoot.varToString("FRM_IDREF")) {
         // Se ha encontrado el formulario
         lExiste = true;
         break;
      };
   };
};

if (lExiste) {
   // Separador de formularios (clase del API VTabWidget)	
   oSeparador = oVista.centralWidget().control(theRoot.varToString("SEP_FORM"));
   if (oSeparador) {
      // Pestaña a refrescar
      oSubform = oSeparador.form("0PS_Ejercicios_app/" + theRoot.varToString("SUBFRM"));
      if (oSubform) {
         nIndice = oSeparador.findForm(oSubform);
         // Mostramos la pestaña
         oSeparador.setCurrentIndex(nIndice);
         // Ejecutamos evento click
         oBoton= oSubform.control(theRoot.varToString("CMD_REFRESCAR"));
         oBoton.click();
      };
   };
};

Así tiene que funcionar bien. Si no entiendes alguna línea la comentamos.

Saludos
Paco Satué


([N1] wikan) #11

Cuidado con esta línea:
oSubform = oSeparador.form("0PS_Ejercicios_app/" + theRoot.varToString("SUBFRM"));

Primero fallo de Paco :wink: se le ha ido el alias de su aplicación.
Si la variable SUBFRM ya viene como idRef:
oSubform = oSeparador.form(theRoot.varToString("SUBFRM"));


([N3] pacosatu) #12

Hola Manuel.

¡Hombre no es un fallo!, está puesto así a propósito para que quede claro que necesitamos el idRef() del subformulario.

Cada uno pondrá el Alias a su manera, a veces ya vendrá dado en la Variable Local SUBFRM y otras veces solo nos pasarán el id() del formulario, por lo que habrá que buscarlo en toda la herencia de proyectos. Por esta razón es importante nombrar determinados objetos con un id() único en toda la herencia y de esta forma localizarlos fácilmente cuando no nos pasan el Alias.

De todas formas, ya he dejado claro otras veces que esta forma de programar NO me gusta nada. Lo ideal sería poder hacer todo lo referente a Interfaz con Velneo nativo y no recurrir a ÑAPAS como la de disparar un click(). ¿No sería más lógico poder ejecutar cualquier Manejador de los subcontroles directamente? ¿No sería mucho más potente Velneo si nos centráramos en potenciar el sistema de eventos?¿Qué razones hay para que esto no sea así?

Preguntas técnicas para Life is Soft.

Saludos
Paco Satué


([N1] wikan) #13

Estoy de acuerdo contigo que desde el formulario principal poder ejecutar o incluso “disparar señales” de los formularios incrustados, debería, estaría muy bien.

Con respecto a que todo sea nativo, ojala. Pero usar vJavascript para mi es un “puntazo” poder dinamizar llamadas, variables etc. Si además le incluimos las “guarradas” de javascript.

Lo que está claro, es que desde comandos nativos no tenemos unas cosas y desde javascript no tenemos otras. Y supongo que poco a poco se irán equilibrando en la medida de los posible, pero siempre tendrás diferencias.

Otro ++++++ es lo que comentas, ya que Qt funciona por eventos y Velneo los ha incrustado. Estaría perfecto si pudieramos provocar señales desde procesos y no solo con los action. Creo que en su momento lo intente pero no funcionaba lanzar una acción desde el principal para capturarla desde el subformulario.


([N4] velavisual) #14

Muchas Gracias, Paco y Manuel

Ojalá este tipo de cosas fuesen nativas, pero me parece a mí que no caerá esa breva. De ahí la aparición de vJavaScript.