xonecode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/dist/agent/authEnDisco.js +56 -0
- package/dist/agent/authEnDisco.js.map +1 -0
- package/dist/agent/configEnDisco.js +109 -0
- package/dist/agent/configEnDisco.js.map +1 -0
- package/dist/agent/crearProyecto.js +34 -0
- package/dist/agent/crearProyecto.js.map +1 -0
- package/dist/agent/entorno.js +124 -0
- package/dist/agent/entorno.js.map +1 -0
- package/dist/agent/guionizado.js +53 -0
- package/dist/agent/guionizado.js.map +1 -0
- package/dist/agent/instantanea.js +129 -0
- package/dist/agent/instantanea.js.map +1 -0
- package/dist/agent/interrupts.js +83 -0
- package/dist/agent/interrupts.js.map +1 -0
- package/dist/agent/mensajes.js +24 -0
- package/dist/agent/mensajes.js.map +1 -0
- package/dist/agent/modelos.js +42 -0
- package/dist/agent/modelos.js.map +1 -0
- package/dist/agent/normalizar.js +20 -0
- package/dist/agent/normalizar.js.map +1 -0
- package/dist/agent/perfiles.js +103 -0
- package/dist/agent/perfiles.js.map +1 -0
- package/dist/agent/proyecto.js +107 -0
- package/dist/agent/proyecto.js.map +1 -0
- package/dist/agent/puente.js +142 -0
- package/dist/agent/puente.js.map +1 -0
- package/dist/agent/resumenDeTool.js +48 -0
- package/dist/agent/resumenDeTool.js.map +1 -0
- package/dist/agent/skills.js +65 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/textoDeTool.js +113 -0
- package/dist/agent/textoDeTool.js.map +1 -0
- package/dist/agent/turnoReal.js +173 -0
- package/dist/agent/turnoReal.js.map +1 -0
- package/dist/agent/verificador.js +65 -0
- package/dist/agent/verificador.js.map +1 -0
- package/dist/agent/xoneAgent.js +106 -0
- package/dist/agent/xoneAgent.js.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/aprobar.js +82 -0
- package/dist/cli/aprobar.js.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consola.js +346 -0
- package/dist/cli/consola.js.map +1 -0
- package/dist/cli/describe.js +53 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/doctor.js +45 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/markdown.js +90 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/run.js +164 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spinner.js +89 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/stdio.js +193 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/tema.js +40 -0
- package/dist/cli/tema.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/core/bitacora.js +30 -0
- package/dist/core/bitacora.js.map +1 -0
- package/dist/core/config.js +236 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextos.js +56 -0
- package/dist/core/contextos.js.map +1 -0
- package/dist/core/deps.js +51 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/diff.js +79 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/esqueleto.js +366 -0
- package/dist/core/esqueleto.js.map +1 -0
- package/dist/core/events.js +2 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/modelos.js +85 -0
- package/dist/core/modelos.js.map +1 -0
- package/dist/core/notify.js +106 -0
- package/dist/core/notify.js.map +1 -0
- package/dist/core/ports.js +114 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/turno.js +127 -0
- package/dist/core/turno.js.map +1 -0
- package/dist/vendor/hitl.js +103 -0
- package/dist/vendor/hitl.js.map +1 -0
- package/dist/vendor/skillLoaders/catalog.js +74 -0
- package/dist/vendor/skillLoaders/catalog.js.map +1 -0
- package/dist/vendor/tokenTracking.js +58 -0
- package/dist/vendor/tokenTracking.js.map +1 -0
- package/package.json +41 -0
- package/skills/xone-debugging/SKILL.md +52 -0
- package/skills/xone-debugging/references/faq.md +561 -0
- package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
- package/skills/xone-development/SKILL.md +105 -0
- package/skills/xone-development/references/anti-patrones.md +94 -0
- package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
- package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
- package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
- package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
- package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
- package/skills/xone-development/references/datos/appdata.md +611 -0
- package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
- package/skills/xone-development/references/datos/http.md +366 -0
- package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
- package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
- package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
- package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
- package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
- package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
- package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
- package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
- package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
- package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
- package/skills/xone-development/references/indice-completo.md +77 -0
- package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
- package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
- package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
- package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
- package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
- package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
- package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
- package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
- package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
- package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
- package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
- package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
- package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
- package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
- package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
- package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
- package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
- package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
- package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
- package/skills/xone-development/references/tipos-de-prop.md +28 -0
- package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
- package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
- package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
- package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
- package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
- package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
- package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
- package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
- package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
- package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
- package/skills/xone-development/references/xml-ui/mapas.md +685 -0
- package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
- package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
- package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
- package/skills/xone-plan-builder/SKILL.md +183 -0
- package/skills/xone-plan-builder/agents/openai.yaml +5 -0
- package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
- package/skills/xone-project-generator/SKILL.md +111 -0
- package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
- package/skills/xone-project-generator/references/colecciones-base.md +16 -0
- package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
- package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
- package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
- package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
- package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
- package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
- package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
- package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
- package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
- package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
- package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
- package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
- package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
- package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
- package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
- package/skills/xone-review/SKILL.md +189 -0
- package/skills/xone-spec-builder/SKILL.md +235 -0
- package/skills/xone-spec-builder/agents/openai.yaml +5 -0
- package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
- package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
- package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
|
@@ -0,0 +1,704 @@
|
|
|
1
|
+
# XOne — Eventos: sistema, ciclo de vida e interacción
|
|
2
|
+
|
|
3
|
+
> Fuente: `xone/v2/xone-help-docs/topics/05-events-patterns-faq.md` §1–§3. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
|
|
4
|
+
|
|
5
|
+
Contenido: §1 cómo funciona el sistema de eventos · §2 eventos de ciclo de vida (create, before-edit, after-edit, load) · §3 eventos de interacción (onclick, onchange, selecteditem, onlongpressitem, onback)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Sistema de Eventos en XOne
|
|
10
|
+
|
|
11
|
+
### 1.1 Como funciona el sistema de eventos
|
|
12
|
+
|
|
13
|
+
XOne utiliza un sistema de eventos declarativo en XML. Los eventos se definen como nodos dentro de una coleccion (`<coll>`) y contienen acciones que se ejecutan cuando el evento se dispara.
|
|
14
|
+
|
|
15
|
+
El flujo básico es:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Evento disparado --> Nodo XML del evento --> Accion(es) --> Script JavaScript
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Las acciones principales dentro de un evento son:
|
|
22
|
+
|
|
23
|
+
- **`runscript`** - Ejecuta código JavaScript
|
|
24
|
+
- **`setval`** - Establece un valor en un campo
|
|
25
|
+
|
|
26
|
+
Ejemplo básico de un evento con acción:
|
|
27
|
+
|
|
28
|
+
```xml
|
|
29
|
+
<create refresh="true" show-wait-dialog="false">
|
|
30
|
+
<action name="setval" field="FECHA" value="##NOW_TIME##"/>
|
|
31
|
+
<action name="runscript">
|
|
32
|
+
<script language="javascript">
|
|
33
|
+
inicializarFormulario();
|
|
34
|
+
</script>
|
|
35
|
+
</action>
|
|
36
|
+
</create>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **Referencia cruzada:** Para la estructura XML de los nodos de eventos, consultar el tópico 02 sobre estructura XML.
|
|
40
|
+
|
|
41
|
+
### 1.2 Ambitos de eventos
|
|
42
|
+
|
|
43
|
+
Los eventos en XOne operan en cuatro ambitos distintos:
|
|
44
|
+
|
|
45
|
+
| Ambito | Descripción | Donde se declara | Ejemplos |
|
|
46
|
+
|--------|-------------|------------------|----------|
|
|
47
|
+
| **application** | Nivel de aplicación completa | Coleccion `Empresas` en `mappings.xne` | `onlogon`, `maintenance`, `onpushreceived`, `sys-message` |
|
|
48
|
+
| **collection** | Nivel de coleccion | Dentro del nodo `<coll>` | `selecteditem`, `onlongpressitem`, `login-ok`, `login-fail` |
|
|
49
|
+
| **object** | Nivel de objeto individual | Dentro del nodo `<coll>` | `create`, `load`, `before-edit`, `after-edit`, `onback`, `onrefresh` |
|
|
50
|
+
| **property** | Nivel de propiedad/campo | Como atributo en `<prop>` | `onclick`, `onchange`, `ontextchanged`, `onfocuschanged` |
|
|
51
|
+
|
|
52
|
+
### 1.3 Atributos comunes de eventos
|
|
53
|
+
|
|
54
|
+
Todos los nodos de evento soportan los siguientes atributos de configuración:
|
|
55
|
+
|
|
56
|
+
| Atributo | Tipo | Descripción | Valor por defecto |
|
|
57
|
+
|----------|------|-------------|-------------------|
|
|
58
|
+
| `refresh` | boolean | Refrescar la UI después de ejecutar el evento | `true` |
|
|
59
|
+
| `show-wait-dialog` | boolean | Mostrar un dialogo de espera mientras se ejecuta | `true` |
|
|
60
|
+
| `wait-dialog-text` | string | Texto personalizado del dialogo de espera | (vacio) |
|
|
61
|
+
|
|
62
|
+
Ejemplo con todos los atributos:
|
|
63
|
+
|
|
64
|
+
```xml
|
|
65
|
+
<GuardarDatos refresh="true" show-wait-dialog="true" wait-dialog-text="Guardando...">
|
|
66
|
+
<action name="runscript">
|
|
67
|
+
<script language="javascript">
|
|
68
|
+
guardarFormulario();
|
|
69
|
+
</script>
|
|
70
|
+
</action>
|
|
71
|
+
</GuardarDatos>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Buena práctica:** Establece `refresh="false"` y `show-wait-dialog="false"` en eventos que no modifican la UI para evitar parpadeos innecesarios.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 2. Eventos de Ciclo de Vida
|
|
79
|
+
|
|
80
|
+
### 2.1 create - Al crear objeto nuevo
|
|
81
|
+
|
|
82
|
+
**Ambito:** object | **Tipo:** interno
|
|
83
|
+
|
|
84
|
+
Se dispara una única vez cuando se crea un nuevo objeto en la coleccion. Es ideal para inicializar valores por defecto.
|
|
85
|
+
|
|
86
|
+
```xml
|
|
87
|
+
<create refresh="true" show-wait-dialog="false">
|
|
88
|
+
<action name="setval" field="FECHA" value="##NOW_TIME##"/>
|
|
89
|
+
<action name="runscript">
|
|
90
|
+
<script language="javascript">
|
|
91
|
+
inicializarFormulario();
|
|
92
|
+
</script>
|
|
93
|
+
</action>
|
|
94
|
+
</create>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Ejemplo real** (del proyecto EspecialCalendario):
|
|
98
|
+
|
|
99
|
+
```xml
|
|
100
|
+
<create>
|
|
101
|
+
<action name="runscript">
|
|
102
|
+
<script language="javascript">
|
|
103
|
+
self.MAP_CTN_TITLE_FECHA = "FECHA";
|
|
104
|
+
self.MAP_CTN_TITLE_TIPO = "TIPO";
|
|
105
|
+
self.MAP_CTN_TITLE_DESCRIPCION = "DESCRIPCION";
|
|
106
|
+
</script>
|
|
107
|
+
</action>
|
|
108
|
+
</create>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Ejemplo real** (del proyecto ContentCoordenadasGPS, con `setval` y `mapval`):
|
|
112
|
+
|
|
113
|
+
```xml
|
|
114
|
+
<create>
|
|
115
|
+
<action name="setval" field="FECHA" value="##NOW_TIME##"/>
|
|
116
|
+
<action name="mapval" field="USUARIO" coll="Usuarios"
|
|
117
|
+
mapfld="ID" mapvalue="##USERID##" targetfld="LOGIN"/>
|
|
118
|
+
</create>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 2.2 load - Al cargar cada DataObject
|
|
122
|
+
|
|
123
|
+
**Ambito:** object | **Tipo:** interno
|
|
124
|
+
|
|
125
|
+
Se dispara **por cada DataObject** al cargarse desde la base de datos (en `loadAll()`, `startBrowse()` o cuando se hidrata un item de `<contents>`). Se ejecuta después de `create` si el objeto es nuevo.
|
|
126
|
+
|
|
127
|
+
> **NUNCA usar `<load>` para inicializar una pantalla** — usar `<before-edit>`. En una pantalla `special="true"` sin coleccion de datos, `<load>` no se dispara nunca; en pantallas con coleccion, se dispara una vez por cada item cargado y penaliza rendimiento.
|
|
128
|
+
|
|
129
|
+
### 2.3 before-edit - Antes de entrar en edición
|
|
130
|
+
|
|
131
|
+
**Ambito:** object | **Tipo:** interno
|
|
132
|
+
|
|
133
|
+
Se dispara antes de que la vista entre en modo edición. Es el evento más utilizado para preparar la pantalla, inicializar variables MAP y configurar contents.
|
|
134
|
+
|
|
135
|
+
```xml
|
|
136
|
+
<before-edit refresh="false" show-wait-dialog="false">
|
|
137
|
+
<action name="runscript">
|
|
138
|
+
<script language="javascript">
|
|
139
|
+
self.MAP_USER = self.getOwnerCollection().getVariable("##LOGIN_LASTUSER##");
|
|
140
|
+
</script>
|
|
141
|
+
</action>
|
|
142
|
+
</before-edit>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Ejemplo real** (del proyecto EspecialContents):
|
|
146
|
+
|
|
147
|
+
```xml
|
|
148
|
+
<before-edit refresh="true">
|
|
149
|
+
<action name="runscript">
|
|
150
|
+
<script language="javascript">
|
|
151
|
+
self.MAP_GROUP = 1;
|
|
152
|
+
self.MAP_TOTAL_PAGES = 5;
|
|
153
|
+
self.MAP_ORDEN = "ASC";
|
|
154
|
+
self.MAP_BTORDEN = "sortAZ.png";
|
|
155
|
+
self.MAP_BTORDENCLICK = "sortAZ_click.png";
|
|
156
|
+
self.getContents("content4").sort = "NOMBRE ASC";
|
|
157
|
+
self.getContents("content4").loadAll();
|
|
158
|
+
self.getContents("content4").lock();
|
|
159
|
+
|
|
160
|
+
self.getContents("content1").clear();
|
|
161
|
+
self.getContents("content1").lock();
|
|
162
|
+
|
|
163
|
+
ui.startGps();
|
|
164
|
+
self.MAP_NOMBRESEL = "";
|
|
165
|
+
</script>
|
|
166
|
+
</action>
|
|
167
|
+
</before-edit>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Ejemplo real** (del proyecto EspecialEventos, con `bind` para eventos por script):
|
|
171
|
+
|
|
172
|
+
```xml
|
|
173
|
+
<before-edit>
|
|
174
|
+
<action name="runscript">
|
|
175
|
+
<script language="javascript">
|
|
176
|
+
var v = ui.getView(self);
|
|
177
|
+
v.bind("MAP_ONTEXTCHANGED", "ontextchanged", eventoOnTextChanged);
|
|
178
|
+
v.bind("MAP_ONFOCUSCHANGED01", "onfocuschanged", eventoOnFocusChanged);
|
|
179
|
+
|
|
180
|
+
v.bind("SCJAVA", "onclick",
|
|
181
|
+
{title:'valor desde fuera', msg:'LLamada inline'},
|
|
182
|
+
function(e) {
|
|
183
|
+
ui.msgBox(e.target + ":" + e.data.msg, e.data.title, 0);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
v.bind("SCJAVA1", "onclick", "EspecialcollTest1", jstestClick);
|
|
187
|
+
</script>
|
|
188
|
+
</action>
|
|
189
|
+
</before-edit>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 2.4 after-edit - Después de entrar en edición
|
|
193
|
+
|
|
194
|
+
**Ambito:** object | **Tipo:** interno
|
|
195
|
+
|
|
196
|
+
Se dispara después de que la vista ha entrado en modo edición y se ha pintado la interfaz. Útil para operaciones que requieren que la UI ya este renderizada.
|
|
197
|
+
|
|
198
|
+
```xml
|
|
199
|
+
<after-edit show-wait-dialog="false" refresh="false">
|
|
200
|
+
<action name="runscript">
|
|
201
|
+
<script language="javascript">
|
|
202
|
+
if (appData.getGlobalMacro("##DEVICE_OS##") == "android")
|
|
203
|
+
requestIgnoreBatteryOptimizations();
|
|
204
|
+
</script>
|
|
205
|
+
</action>
|
|
206
|
+
</after-edit>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Ejemplo real** (del proyecto EspecialChat):
|
|
210
|
+
|
|
211
|
+
```xml
|
|
212
|
+
<after-edit show-wait-dialog="false" refresh="false">
|
|
213
|
+
<action name="runscript">
|
|
214
|
+
<script language="javascript">
|
|
215
|
+
lockContents(["Chat", "nUsuarios", "Chatear"]);
|
|
216
|
+
</script>
|
|
217
|
+
</action>
|
|
218
|
+
</after-edit>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 2.5 Orden de ejecución de lifecycle
|
|
222
|
+
|
|
223
|
+
El orden de ejecución de los eventos de ciclo de vida es:
|
|
224
|
+
|
|
225
|
+
**Para un objeto nuevo:**
|
|
226
|
+
1. `create` - Se inicializa el objeto
|
|
227
|
+
2. `before-edit` - Se prepara la vista
|
|
228
|
+
3. (Se pinta la interfaz)
|
|
229
|
+
4. `after-edit` - La vista esta renderizada
|
|
230
|
+
|
|
231
|
+
**Para un objeto existente:**
|
|
232
|
+
1. `load` - Se carga desde BD
|
|
233
|
+
2. `before-edit` - Se prepara la vista
|
|
234
|
+
3. (Se pinta la interfaz)
|
|
235
|
+
4. `after-edit` - La vista esta renderizada
|
|
236
|
+
|
|
237
|
+
**Al salir:**
|
|
238
|
+
1. `onback` - El usuario pulsa atrás
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 3. Eventos de Interaccion
|
|
243
|
+
|
|
244
|
+
### 3.1 onclick (atributo) - Click/tap en elemento
|
|
245
|
+
|
|
246
|
+
**Ambito:** property | **Tipo:** atributo
|
|
247
|
+
|
|
248
|
+
Se dispara cuando el usuario hace click o tap en un elemento. Se declara como atributo en el nodo `<prop>`.
|
|
249
|
+
|
|
250
|
+
```xml
|
|
251
|
+
<prop type="B" name="BTN_LOGIN" title="Login"
|
|
252
|
+
onclick="doLogin();"/>
|
|
253
|
+
|
|
254
|
+
<prop name="BTN_ACCION" type="B"
|
|
255
|
+
onclick="self.MAP_QR=1; ui.refresh('frmCamera'); ui.sleep(0.1);"/>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Ejemplo real** (del proyecto EspecialEventos, llamada inline con parámetros):
|
|
259
|
+
|
|
260
|
+
```xml
|
|
261
|
+
<prop name="ATTJAVA" title="No abre coleccion"
|
|
262
|
+
onclick="javascript:(function(e, data) {
|
|
263
|
+
ui.msgBox(e.target + ':' + data.msg, data.title, 0);
|
|
264
|
+
})(e, {title:'valor desde fuera', msg:'LLamada inline'});"
|
|
265
|
+
type="B" visible="1" width="300p" height="150p"
|
|
266
|
+
labelwidth="1" bgcolor="#666666" forecolor="#F2F2F2"/>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Ejemplo real** (del proyecto EspecialEventos, llamada a función con datos):
|
|
270
|
+
|
|
271
|
+
```xml
|
|
272
|
+
<prop name="ATTJAVA1" title="Abrir coleccion 1"
|
|
273
|
+
onclick="javascript:jstestClickNode(e, 'EspecialcollTest1');"
|
|
274
|
+
type="B" visible="1" width="300p" height="150p"/>
|
|
275
|
+
|
|
276
|
+
<prop name="ATTJAVA2" title="Abrir coleccion 2"
|
|
277
|
+
onclick="javascript:jstestClickNode(e, {
|
|
278
|
+
title:'valor desde fuera',
|
|
279
|
+
msg:'Abre un nuevo objeto',
|
|
280
|
+
collName: 'EspecialcollTest2'
|
|
281
|
+
});"
|
|
282
|
+
type="B" visible="1" width="300p" height="150p"/>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 3.2 onchange (nodo y atributo) - Cambio de valor
|
|
286
|
+
|
|
287
|
+
**Ambito:** property/object | **Tipo:** interno/atributo
|
|
288
|
+
|
|
289
|
+
Se dispara cuando cambia el valor de una propiedad. Puede usarse de dos formas:
|
|
290
|
+
|
|
291
|
+
**Como nodo `<onchange>` con campos `<field>` especificos:**
|
|
292
|
+
|
|
293
|
+
```xml
|
|
294
|
+
<onchange show-wait-dialog="false" refresh="false">
|
|
295
|
+
<field name="MAP_TIPO">
|
|
296
|
+
<action name="runscript">
|
|
297
|
+
<script language="javascript">
|
|
298
|
+
actualizarPorTipo();
|
|
299
|
+
</script>
|
|
300
|
+
</action>
|
|
301
|
+
</field>
|
|
302
|
+
</onchange>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Ejemplo real** (del proyecto EspecialMacros, con multiples campos):
|
|
306
|
+
|
|
307
|
+
```xml
|
|
308
|
+
<onchange>
|
|
309
|
+
<field name="MAP_TIPO">
|
|
310
|
+
<action name="runscript">
|
|
311
|
+
<script language="javascript">
|
|
312
|
+
var coll = self.getContents("content1");
|
|
313
|
+
if (self.TIPO == "TODOS") {
|
|
314
|
+
coll.setMacro("##TIPO##", "1=1");
|
|
315
|
+
} else {
|
|
316
|
+
coll.setMacro("##TIPO##", "FILTRO='" + self.TIPO.toString() + "'");
|
|
317
|
+
}
|
|
318
|
+
ui.refresh();
|
|
319
|
+
</script>
|
|
320
|
+
</action>
|
|
321
|
+
</field>
|
|
322
|
+
<field name="MAP_TIPO1">
|
|
323
|
+
<action name="runscript">
|
|
324
|
+
<script language="javascript">
|
|
325
|
+
var coll = self.getContents("content2");
|
|
326
|
+
if (self.TIPO1 == "TODOS") {
|
|
327
|
+
coll.setMacro("##TIPO##",
|
|
328
|
+
"SELECT ID,TITULO,FILTRO FROM GEN_CONTROLES");
|
|
329
|
+
} else {
|
|
330
|
+
coll.setMacro("##TIPO##",
|
|
331
|
+
"SELECT ID,TITULO,FILTRO FROM GEN_CONTROLES WHERE FILTRO='"
|
|
332
|
+
+ self.TIPO1.toString() + "'");
|
|
333
|
+
}
|
|
334
|
+
ui.refresh();
|
|
335
|
+
</script>
|
|
336
|
+
</action>
|
|
337
|
+
</field>
|
|
338
|
+
</onchange>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Ejemplo real** (del proyecto EspecialChat, escuchando cambios en foto y adjunto):
|
|
342
|
+
|
|
343
|
+
```xml
|
|
344
|
+
<onchange>
|
|
345
|
+
<field name="MAP_FOTO">
|
|
346
|
+
<action name="runscript">
|
|
347
|
+
<script language="javascript">
|
|
348
|
+
AccionesChatEspecial('enviar');
|
|
349
|
+
</script>
|
|
350
|
+
</action>
|
|
351
|
+
</field>
|
|
352
|
+
<field name="MAP_ADJUNTO">
|
|
353
|
+
<action name="runscript">
|
|
354
|
+
<script language="javascript">
|
|
355
|
+
AccionesChatEspecial('adjuntoguardar', e);
|
|
356
|
+
</script>
|
|
357
|
+
</action>
|
|
358
|
+
</field>
|
|
359
|
+
</onchange>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Como atributo en `<prop>` (forma simplificada):**
|
|
363
|
+
|
|
364
|
+
```xml
|
|
365
|
+
<prop name="CANTIDAD" type="N" onchange="Refresh"/>
|
|
366
|
+
<prop name="MAP_TEXT" type="T" onchange="ExecuteNode(oldvalue)"/>
|
|
367
|
+
<prop name="Calendario" type="Z" onchange="refresh" postonchange="refresh"/>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
El valor `"Refresh"` o `"refresh"` hace un refresco automático de la pantalla. También puede usarse `"refresh(campo1,campo2)"` para refrescar campos especificos.
|
|
371
|
+
|
|
372
|
+
#### onvaluechanged (atributo) — Cambio de valor en la capa de datos
|
|
373
|
+
|
|
374
|
+
`onvaluechanged` se dispara cuando el valor de un campo cambia. Tiene dos características que lo distinguen:
|
|
375
|
+
|
|
376
|
+
1. **Su valor es JavaScript inline normal** (igual que `onclick`): escribes directamente el código a ejecutar.
|
|
377
|
+
2. **Se dispara desde la capa de datos**, así que salta siempre que el valor del campo cambie de verdad, **aunque no haya ninguna ventana abierta** (cambios provocados por scripts de fondo, réplica, tareas programadas, etc.).
|
|
378
|
+
|
|
379
|
+
Recibe un objeto de evento `e` con estas propiedades:
|
|
380
|
+
|
|
381
|
+
| Propiedad | Descripción |
|
|
382
|
+
|-----------|-------------|
|
|
383
|
+
| `e.value` | Nuevo valor del campo (después del cambio) |
|
|
384
|
+
| `e.oldValue` | Valor que tenía el campo antes del cambio |
|
|
385
|
+
| `e.target` | Nombre del campo que ha cambiado |
|
|
386
|
+
| `e.objItem` | Objeto de datos sobre el que se ha producido el cambio |
|
|
387
|
+
| `e.data` | Dato libre asociado al binding (normalmente vacío) |
|
|
388
|
+
|
|
389
|
+
```xml
|
|
390
|
+
<!-- Recalcular un total al cambiar la cantidad, haya o no pantalla abierta -->
|
|
391
|
+
<prop name="CANTIDAD" type="N" visible="1"
|
|
392
|
+
onvaluechanged="self.TOTAL = e.value * self.PRECIO;" />
|
|
393
|
+
|
|
394
|
+
<!-- Registrar el cambio en una auditoría -->
|
|
395
|
+
<prop name="ESTADO" type="T" visible="1"
|
|
396
|
+
onvaluechanged="registrarCambio(e.target, e.oldValue, e.value);" />
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
También se puede registrar dinámicamente desde JavaScript:
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
self.bind("CANTIDAD", "onvaluechanged", function (e) {
|
|
403
|
+
self.TOTAL = e.value * self.PRECIO;
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Solo JavaScript.** Se dispara únicamente cuando el valor cambia de verdad (reasignar el mismo valor no lo dispara) y nunca durante la carga del objeto desde la base de datos.
|
|
408
|
+
|
|
409
|
+
Es ideal para lógica que debe ejecutarse siempre que el dato cambie (recalcular campos, `Save()`, auditoría, sincronización), haya o no una pantalla abierta.
|
|
410
|
+
|
|
411
|
+
### 3.3 selecteditem - Selección en lista
|
|
412
|
+
|
|
413
|
+
**Ambito:** collection | **Tipo:** interno
|
|
414
|
+
|
|
415
|
+
Se dispara cuando el usuario selecciona un item de una lista o content.
|
|
416
|
+
|
|
417
|
+
```xml
|
|
418
|
+
<selecteditem refresh="false" show-wait-dialog="false">
|
|
419
|
+
<action name="runscript">
|
|
420
|
+
<script language="javascript">
|
|
421
|
+
onSelectedItem(self);
|
|
422
|
+
</script>
|
|
423
|
+
</action>
|
|
424
|
+
</selecteditem>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
> **Referencia cruzada:** Para ver como se implementa la selección en listas con contents, ver el tópico 02 sobre estructura XML y el patron maestro-detalle en la sección 10.2.
|
|
428
|
+
|
|
429
|
+
### 3.4 onlongpressitem - Pulsacion larga
|
|
430
|
+
|
|
431
|
+
**Ambito:** collection | **Tipo:** interno
|
|
432
|
+
|
|
433
|
+
Se dispara cuando el usuario hace una pulsacion larga sobre un item de una lista.
|
|
434
|
+
|
|
435
|
+
```xml
|
|
436
|
+
<onlongpressitem refresh="false" show-wait-dialog="false">
|
|
437
|
+
<action name="runscript">
|
|
438
|
+
<script language="javascript">
|
|
439
|
+
mostrarMenuContextual(self);
|
|
440
|
+
</script>
|
|
441
|
+
</action>
|
|
442
|
+
</onlongpressitem>
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### 3.5 onback - Botón retroceso
|
|
446
|
+
|
|
447
|
+
**Ambito:** object | **Tipo:** interno
|
|
448
|
+
|
|
449
|
+
Se dispara cuando el usuario presiona el botón de retroceso del dispositivo. Permite controlar la navegación hacia atrás.
|
|
450
|
+
|
|
451
|
+
```xml
|
|
452
|
+
<onback refresh="false" show-wait-dialog="false">
|
|
453
|
+
<action name="runscript">
|
|
454
|
+
<script language="javascript">
|
|
455
|
+
if (hayDatosSinGuardar()) {
|
|
456
|
+
confirmarSalida();
|
|
457
|
+
} else {
|
|
458
|
+
ui.closeApp();
|
|
459
|
+
}
|
|
460
|
+
</script>
|
|
461
|
+
</action>
|
|
462
|
+
</onback>
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Ejemplo real** (patron estándar en todos los proyectos del wiki):
|
|
466
|
+
|
|
467
|
+
```xml
|
|
468
|
+
<onback show-wait-dialog="false">
|
|
469
|
+
<action name="runscript">
|
|
470
|
+
<script language="javascript">
|
|
471
|
+
ui.getView(self).exit();
|
|
472
|
+
</script>
|
|
473
|
+
</action>
|
|
474
|
+
</onback>
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Ejemplo real** (del proyecto UseCars - EntradaApp, con confirmacion):
|
|
478
|
+
|
|
479
|
+
```xml
|
|
480
|
+
<onback>
|
|
481
|
+
<script>
|
|
482
|
+
if (confirmar("¿Desea salir de la aplicación?", "Salir")) {
|
|
483
|
+
appData.exit();
|
|
484
|
+
}
|
|
485
|
+
</script>
|
|
486
|
+
</onback>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Ejemplo real** (del proyecto EspecialChat, lógica condicional):
|
|
490
|
+
|
|
491
|
+
```xml
|
|
492
|
+
<onback show-wait-dialog="false" refresh="false">
|
|
493
|
+
<action name="runscript">
|
|
494
|
+
<script language="javascript">
|
|
495
|
+
salir();
|
|
496
|
+
</script>
|
|
497
|
+
</action>
|
|
498
|
+
</onback>
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### 3.6 onrefresh - Al refrescar vista
|
|
502
|
+
|
|
503
|
+
**Ambito:** object | **Tipo:** interno
|
|
504
|
+
|
|
505
|
+
Se dispara cuando se refresca la vista del objeto.
|
|
506
|
+
|
|
507
|
+
```xml
|
|
508
|
+
<onrefresh>
|
|
509
|
+
<action name="runscript">
|
|
510
|
+
<script language="javascript">
|
|
511
|
+
actualizarContadores();
|
|
512
|
+
</script>
|
|
513
|
+
</action>
|
|
514
|
+
</onrefresh>
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### 3.7 postonchange (atributo) - Post-cambio
|
|
518
|
+
|
|
519
|
+
**Ambito:** property | **Tipo:** atributo
|
|
520
|
+
|
|
521
|
+
Se ejecuta después de que cambia el valor de una propiedad. A diferencia de `onchange`, se ejecuta en un segundo paso, permitiendo realizar acciones de post-procesamiento como refrescar la UI o ejecutar otro nodo.
|
|
522
|
+
|
|
523
|
+
```xml
|
|
524
|
+
<prop name="FOTO" type="IMG"
|
|
525
|
+
method="executenode(HacerFoto)"
|
|
526
|
+
postonchange="actualizarGaleria();"/>
|
|
527
|
+
|
|
528
|
+
<prop name="BNew" type="B" img="nuevo.png"
|
|
529
|
+
method="ExecuteNode(nuevo)"
|
|
530
|
+
postonchange="refresh"/>
|
|
531
|
+
|
|
532
|
+
<prop name="EGECUTARYREFRES" type="B"
|
|
533
|
+
method="executeNode(pulsaronchange('EspecialColeccionDePegaOnchange'))"
|
|
534
|
+
postonchange="ExecuteNode(postpulsaronchange)"/>
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 3.8 ontextchanged - Cambio de texto en tiempo real
|
|
538
|
+
|
|
539
|
+
**Ambito:** property | **Tipo:** atributo
|
|
540
|
+
|
|
541
|
+
Se dispara cada vez que el usuario escribe o borra un carácter en un campo de texto. Recibe un objeto evento con información sobre el cambio.
|
|
542
|
+
|
|
543
|
+
```xml
|
|
544
|
+
<prop name="MAP_ONTEXTCHANGED" title="onTextChanged" type="T"
|
|
545
|
+
ontextchanged="javascript:eventoOnTextChanged(e);"/>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Ejemplo real** (del proyecto EspecialEventos - la función receptora en JS):
|
|
549
|
+
|
|
550
|
+
```javascript
|
|
551
|
+
function eventoOnTextChanged(evento) {
|
|
552
|
+
self["MAP_DESCRIPCIONEVENTO"] = "onTextChanged! target: " + evento.target
|
|
553
|
+
+ "\nObjItem: " + evento.objItem
|
|
554
|
+
+ "\nTecla pulsada: " + evento.keyPressed
|
|
555
|
+
+ "\noldText: " + evento.oldText
|
|
556
|
+
+ "\nnewText: " + evento.newText;
|
|
557
|
+
ui.getView(self).refresh("MAP_DESCRIPCIONEVENTO");
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Ejemplo real** (del proyecto EspecialContents, filtrado en tiempo real):
|
|
562
|
+
|
|
563
|
+
```xml
|
|
564
|
+
<prop name="MAP_BUSCAR_TEXT"
|
|
565
|
+
ontextchanged="javascript:FiltraMarcados(e);"
|
|
566
|
+
labelwidth="0" text-border="true" type="T"
|
|
567
|
+
width="98%" height="60p" tooltip="Texto a buscar"/>
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
```javascript
|
|
571
|
+
function FiltraMarcados(e) {
|
|
572
|
+
self.MAP_BUSCAR_TEXT = e.newText;
|
|
573
|
+
self.executeNode("applyfilter");
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**Propiedades del objeto evento (`e`):**
|
|
578
|
+
|
|
579
|
+
| Propiedad | Tipo | Descripción |
|
|
580
|
+
|-----------|------|-------------|
|
|
581
|
+
| `e.target` | string | Nombre del campo que disparo el evento |
|
|
582
|
+
| `e.objItem` | object | Referencia al objeto que contiene el campo |
|
|
583
|
+
| `e.keyPressed` | string | Tecla pulsada |
|
|
584
|
+
| `e.oldText` | string | Texto anterior al cambio |
|
|
585
|
+
| `e.newText` | string | Texto nuevo después del cambio |
|
|
586
|
+
|
|
587
|
+
### 3.9 onfocuschanged - Cambio de foco
|
|
588
|
+
|
|
589
|
+
**Ambito:** property | **Tipo:** atributo
|
|
590
|
+
|
|
591
|
+
Se dispara cuando un campo gana o pierde el foco.
|
|
592
|
+
|
|
593
|
+
```xml
|
|
594
|
+
<prop name="MAP_ONFOCUSCHANGED01"
|
|
595
|
+
onfocuschanged="javascript:eventoOnFocusChanged(e);"
|
|
596
|
+
title="Evento onFocus" type="T"/>
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
**Ejemplo real** (del proyecto EspecialEventos):
|
|
600
|
+
|
|
601
|
+
```javascript
|
|
602
|
+
function eventoOnFocusChanged(evento) {
|
|
603
|
+
self.MAP_DESCRIPCIONEVENTO = "onFocusChanged! target: " + evento.target
|
|
604
|
+
+ "\nObjItem: " + evento.objItem
|
|
605
|
+
+ "\nTiene foco: " + evento.isFocused;
|
|
606
|
+
ui.getView(self).refresh("MAP_DESCRIPCIONEVENTO");
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Ejemplo real** (del proyecto EspecialChat, en campo de texto del chat):
|
|
611
|
+
|
|
612
|
+
```xml
|
|
613
|
+
<prop name="MAP_TITLE"
|
|
614
|
+
onfocuschanged="javascript:AccionesChatEspecial('foco', e);"
|
|
615
|
+
ontextchanged="javascript:AccionesChatEspecial('textoChange', e);"
|
|
616
|
+
type="T" visible="1" width="424p" height="80p"/>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
**Propiedades del objeto evento (`e`):**
|
|
620
|
+
|
|
621
|
+
| Propiedad | Tipo | Descripción |
|
|
622
|
+
|-----------|------|-------------|
|
|
623
|
+
| `e.target` | string | Nombre del campo |
|
|
624
|
+
| `e.objItem` | object | Referencia al objeto |
|
|
625
|
+
| `e.isFocused` | boolean | `true` si gano el foco, `false` si lo perdio |
|
|
626
|
+
|
|
627
|
+
### 3.10 onscroll - Al hacer scroll
|
|
628
|
+
|
|
629
|
+
**Ambito:** frame | **Tipo:** atributo
|
|
630
|
+
|
|
631
|
+
Se dispara cuando el usuario hace scroll dentro de un frame con `scroll="true"`.
|
|
632
|
+
|
|
633
|
+
```xml
|
|
634
|
+
<frame name="atttop" align="top" height="100%" width="100%"
|
|
635
|
+
scroll="true"
|
|
636
|
+
onscroll="javascript:scrollArrow(e, '2');">
|
|
637
|
+
<!-- contenido -->
|
|
638
|
+
</frame>
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
**Ejemplo real** (del proyecto EspecialEventos, mostrar/ocultar flecha de scroll):
|
|
642
|
+
|
|
643
|
+
```javascript
|
|
644
|
+
function scrollArrow(e, miparam) {
|
|
645
|
+
if (miparam == 1) {
|
|
646
|
+
if (e.dy <= 10 && self.MAP_VALORVER == 1) {
|
|
647
|
+
self.MAP_VALORVER = 0;
|
|
648
|
+
ui.getView(self).refresh("frmblotante");
|
|
649
|
+
} else if (e.dy > 10 && self.MAP_VALORVER == 0) {
|
|
650
|
+
self.MAP_VALORVER = 1;
|
|
651
|
+
ui.getView(self).refresh("frmblotante");
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
**También se puede usar `bind` en `before-edit` para asignar el evento por script:**
|
|
658
|
+
|
|
659
|
+
```javascript
|
|
660
|
+
v.bind("sctop", "onscroll", function(e) {
|
|
661
|
+
if (e.dy <= 10 && self.MAP_SCSHOWOVERSCROLL == 1) {
|
|
662
|
+
self.MAP_SCSHOWOVERSCROLL = 0;
|
|
663
|
+
ui.getView(self).refresh("scfroverscroll");
|
|
664
|
+
} else if (e.dy > 10 && self.MAP_SCSHOWOVERSCROLL == 0) {
|
|
665
|
+
self.MAP_SCSHOWOVERSCROLL = 1;
|
|
666
|
+
ui.getView(self).refresh("scfroverscroll");
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
**Propiedades del objeto evento (`e`):**
|
|
672
|
+
|
|
673
|
+
| Propiedad | Tipo | Descripción |
|
|
674
|
+
|-----------|------|-------------|
|
|
675
|
+
| `e.dy` | number | Desplazamiento vertical acumulado |
|
|
676
|
+
|
|
677
|
+
### 3.11 onfocus (grupo) - Al enfocar un grupo
|
|
678
|
+
|
|
679
|
+
**Ambito:** group | **Tipo:** atributo
|
|
680
|
+
|
|
681
|
+
Se dispara cuando un grupo (pestana) recibe el foco, típicamente al cambiar de tab con `group-swipe="true"`.
|
|
682
|
+
|
|
683
|
+
```xml
|
|
684
|
+
<group name="Group1" id="1" onfocus="ExecuteNode(onfocusgrupo(1))">
|
|
685
|
+
<!-- contenido -->
|
|
686
|
+
</group>
|
|
687
|
+
<group name="Group2" id="2" onfocus="ExecuteNode(onfocusgrupo(2))">
|
|
688
|
+
<!-- contenido -->
|
|
689
|
+
</group>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
**Ejemplo real** (nodo custom asociado, presente en todos los proyectos del wiki):
|
|
693
|
+
|
|
694
|
+
```xml
|
|
695
|
+
<onfocusgrupo show-wait-dialog="false">
|
|
696
|
+
<action name="runscript">
|
|
697
|
+
<param name="index"/>
|
|
698
|
+
<script language="javascript">
|
|
699
|
+
self.MAP_GROUP = index;
|
|
700
|
+
</script>
|
|
701
|
+
</action>
|
|
702
|
+
</onfocusgrupo>
|
|
703
|
+
```
|
|
704
|
+
|