{{indexmenu_n>1}} ====== Ejemplos de código Javascript ====== Para poder utilizar las funciones **cstr**, **now**, **len**, etc de VBScript, se ha implementado un fichero "vbscriptsupport.js" que tendremos que incluir en la colección empresas, que expone estas funciones para tenerlas disponibles cuando utilizamos scripts javascript usando la notación “vbSupport.left(XXXXX)”, “vbSupport.now()”, “vbSupport.cstr(XXXXX)”, etc. =====Código que recorre una colección completa===== Código para recorrer una colección registro a registro (Cuando son muchos datos para cargarlos todos en memoria). function recorrerColeccion() { var sMensaje = "Estos son los usuarios:"; // Variable con la coleccion que se va a utilizar var mColeccion = appData.getCollection("Usuarios"); // Guardamos el filtro que tiene la colección actualmente var filtro=mColeccion.getFilter(); // Le ponemos un filtro a la colección mColeccion.setFilter("t1.ACTIVO=1 AND t1.IDUSUARIO=" + user.ID + " AND date(t1.FECHA)=date('" + devolverFecha() + "')"); // Variable con la coleccion que se va a utilizar mColeccion.startBrowse(); try { var mObjeto; while((mObjeto = mColeccion.getCurrentItem()) != undefined) { sMensaje = sMensaje + "\n" + "Nombre: " + mObjeto.NOMBRE + " Login: " + mObjeto.LOGIN; mColeccion.moveNext(); } } catch(ex) { ui.showToast("Hubo un error al hacer startBrowse() en: " + mColeccion.getName()); } finally { // Cerramos el recordset mColeccion.endBrowse(); // Dejamos la colección con el filtro que tenía al principio mColeccion.setFilter(filtro); } return sMensaje; } =====Recorrer una colección/content con pocos datos===== Una colección con pocos datos (Por ejemplo, las filas de detalles de un contents), pueden recorrerse cargando los registros en un array de memoria en lugar de ir recorriendo registro a registro. function recorrerContents() { // Todas las variables que definamos dentro de una funcion son locales a ésta. var coll; var collCount; var SUM=0; var i; var obj; // (Para hacer referencia al objeto actual se utiliza self, para no interferir con el this de javascript). self.MAP_TLCABECERAROJO="TOTAL ENTREGAS"; self.MAP_TLCABECERAROJO1="SUMATORIO ENTREGADAS"; collCount=0; SUM=0; // Cogemos la coll contents Detalles del objeto actual coll=self.getContents("ContentSinCobrar"); // Cargamos los registros en memoria y averiguamos el número de registros coll.loadAll(); collCount=coll.count(); // Utilizamos un For para recorrer los registros del contents. for (i=0;i \\ ===== Obtener un objeto (fila) de una colección, teniendo el valor de un campo de dicho objeto ===== \\ function MarcarIncidencia(idIncid) { // Buscamos una incidencia en concreto conociendo el valor de algún campo único (Siempre se busca como cadena). var collInc = appData.getCollection("IncidenciasAct"); var objInc = collInc.getObject(vb.cstr(idIncid)); objInc.CERRADA=1; objInc.FECHACIERREXONE=vb.now(); objInc.save(); objInc=null; collInc.clear(); } \\ ===== Obtener un objeto (fila) de una colección, utilizando una SQL con más de un campo (FINDOBJECT) ===== \\ AppData.PushValue objLoquesea lanza un objeto en edición. function ejemploFindObject() { var nId = 2; var mObjeto = appData.getCollection("Usuarios").findObject("ID = " + nId); if(mObjeto == undefined) { ui.msgBox("No se encontró el usuario con ID " + nId, "Mensaje", 0); } else { ui.msgBox("El login del usuario con ID " + nId + " es: " + mObjeto.LOGIN, "Mensaje", 0); // Lo lanzamos en edición appData.pushValue(mObjeto); } } ===== Obtener nombre de la Colección Actual (activa en ese momento) ===== \\ function getCurrentCollName() { let ventana = ui.getView(); if (!ventana) { return ""; } let dataObject = ventana.getDataObject(); if (!dataObject) { return ""; } let ownerCollection = dataObject.getOwnerCollection(); return ownerCollection.getName(); } ===== Crear Registro con Script ===== \\ Crear un nuevo registro con script. El script se podrá ejecutar en un **create, insert, delete, botón**...\\ \\ function creaRegistro() { var cCierre = appData.getCollection("Cierre"); var objCierre = cCierre.createObject(); cCierre.addItem(objCierre); objCierre.NUMINCIDENCIA=self.NUMINCIDENCIA; objCierre.NUMPROGRESO=self.NUMPROGRESO; objCierre.CODTECNICO=self.CODTECNICO; objCierre.save(); // Si queremos lanzarlo en edición appData.pushValue(objCierre); } ===== Nodo para irnos a una colección pasando un parámetro (irColl/abrirColl) ===== \\ Primero tendríamos un botón para llamar a este nodo: El código del nodo quedaría: 'Hemos llamado al nodo abrirColl pero podríamos haberlo llamado de cualquier otra forma. function ircoll(collname){ var coll = appData.getCollection(collname); var obj = coll.createObject(); coll.addItem(obj); appData.pushValue(obj); } ===== Mostrar mensajes por pantalla ===== Tenemos varias formas de mostrar un mensaje en pantalla. |< 95% 30% - >| ^ Comando ^ Descripción ^ | ui.msgBox("Ejemplo", "Mensaje", 0);\\ msg1=ui.msgBox("Ejemplo", "Mensaje", 2);\\ msg2=ui.msgBox("Ejemplo", "Mensaje", 4); | Mensaje del framework que necesita respuesta por parte del usuario. El último parámetro puede ser: * **0**, que no devuelve ningún valor, únicamente aparece un botón OK. * **2**, que nos muestra 2 botones: ACEPTAR y CANCELAR que devuelven un 1 ó un 2 respectivamente, según se pulse uno u otro. * **4**, que nos muestra 2 botones: SI y NO que devuelven un 6 ó un 7 respectivamente, según se pulse uno u otro. | | ui.showNotification(1, “Título”, “Mensaje”); | Notificación en la barra superior de notificaciones, se le especifica un ID (1) para si queremos modificar la notificación más adelante, podemos utilizar el mismo comando con otro mensaje y se modificará el que ya existía. | | ui.dismissNotification(1); | Elimina la Notificación de la barra superior de notificaciones realizado con el "ShowNotification", hemos de especificar el ID (1) de la notificación para especificar el mensaje que queremos quitar. | | ui.showToast("Se ha recibido un nuevo mensaje"); | Mensaje TOAST del sistema operativo, ver la captura de pantalla más abajo. El mensaje desaparece automáticamente tras un par de segundos en pantalla. | \\ **Ejemplo de código:** ===== Salir de la ventana actual. Nodo onback. ===== \\ \\ ===== Ejecutar alguna acción SIN replicar las operaciones ===== \\ Si estamos trabajando offline, por defecto, todo lo que se hace en el framework se va almacenando en la tabla master_replica_queue del dispositivo para posteriormente replicarla al servidor.\\ Si en algún momento no deseamos que ésto suceda, podemos realizar alguna operación directamente sobre la base de datos del dispositivo sin que se llegue a replicar al servidor. \\ Este comportamiento es muy utilizado en los mantenimientos sobre la base de datos local del dispositivo para eliminar información que ya no necesitamos (Partes o Pedidos antiguos, etc...).\\ La metodología es muy simple, se trata de crear una colección que "apunte" directamente a la base de datos del dispositivo. Por regla general la solemos llamar siempre igual en todos los proyectos: "ForMaintenance". Lo realmente especial es el atributo connection="mtto" que posee esta colección, que apunta al nodo **** que tenga dicho **name**. No puede haber 2 nodos **** que tengan el mismo name en el mappings. Se recomienda que todos los nodos **** se definan en el nodo APP y así tenerlos todos "centralizados" en un único lugar y estar disponibles para cualquier colección a la cual le definamos el atributo **connection="mtto"** (o cualquier otro nombre que le hayamos puesto al nodo connection). ===== MACRO de usuario para cambiar el filtro de una colección ===== Podemos crear una MACRO de usuario en una colección para sustituir en tiempo real la SQL de una colección, pudiendo llegar a sustituir incluso la SQL de la colección completa. Una vez definida la macro en la colección, posteriormente podemos utilizarla para cambiar el valor de dicha macro y por lo tanto cambiar el SQL.\\ En éste caso concreto, cambiamos el filtro de una colección cuando cambie el valor de un campo "MAP_FTTIPOGASTO". ===== Variables globales o de colección ===== \\ Podemos crear variables que tengan ámbito global y así puedan estar disponibles desde cualquier lugar de la aplicación.\\ \\ Una opción sería incluir un fichero **.js** en la colección de empresas, donde se definirían con "var" las diferentes variables javascript que vayamos a necesitar que sean globales.\\ \\ El otro método sería el que se ha utilizado hasta ahora en la plataforma: // Para establecer el valor de una variable global: appData.getCurrentEnterprise().setVariables("GPSTime", objTransac.FECHA); // Para obtener el valor de una variable global: vLastPieza=appData.getCurrentEnterprise().getVariables("LastPieza"); // Para establecer el valor de una variable de la colección "Usuarios": var mColeccion = appData.getCollection("Usuarios"); mColeccion.setVariables("mensaje", "hola que tal"); // Para obtener el valor de una variable de la colección "Usuarios": var mColeccion = appData.getCollection("Usuarios"); var sMensaje = mColeccion.getVariables("mensaje"); ===== Ir a otra pestaña o group ===== \\ ui.showGroup(self.MAP_PAGINA,"##LEFT_IN##",500,"##LEFT_OUT##",500); ===== Codigo para Crear/Editar/Borrar un registro de un contents ===== //Para poder dar de __ALTA__ un registro en un contents tendríamos que pasarle el ID de la cabecera... function addContents(coll,campoenlace) { var CollCV = appData.getCollection(coll); var ObjCV = CollCV.createObject(); CollCV.addItem(ObjCV); ObjCV(campoenlace) = self.ID; appData.pushValue(ObjCV); } //A ésta función tenemos que pasarle la referencia al contents y el ID que queremos EDITAR. function editContents(coll,idselected) { var CollCV = appData.getCollection(coll); var ObjCV = CollCV.findObject("ID="+idselected); if (ObjCV) { appData.pushValue(ObjCV); } } //Realmente no borramos el registro físicamente, lo que hacemos es cambiar el campo de enlace con la cabecera //ó podemos ponerle un BAJA=1, para darlo de baja lógica. Posteriormente tendríamos un mantenimiento para //eliminar éstos registros del dispositivo (Para que no se replique el borrado físico del registro). function deleteContents(coll,idselected,campoenlace) var result = ui.msgBox("¿Esta seguro de que desea eliminar el registro seleccionado?","¡ALERTA!",4); if (result == 6) { var CollCV = appData.getCollection(coll); var ObjCV = CollCV.findObject("ID="+idselected); if (ObjCV) { ObjCV.campoenlace = -9999; ObjCV.save(); } } } =====Tipos de errores===== \\ \\ =====Botón con Script===== \\ CÓDIGO PARA REALIZAR UN BOTÓN. \\ \\ Está formado por **2 nodos**:\\ \\ |**Nodo 1** |**Prop de tipo "B" (botón)**| Es el nodo que define donde sale el mismo, título y a que nodo llama para ejecutar su código. Tiene el atributo method, que es el que realiza la llamada al nodo que tiene su código, el nombre "ExecuteNode", es el nombre del nodo "method", y tiene que llamarse de la misma forma (mayúsculas-minúsculas).| |**Nodo 2** |**Nodo en el que se pone el código que se va a ejecutar**| El nombre es definido por el usuario, y como único requisito, es el nombre del nodo, tiene que llamarse igual (mayúsculas-minúsculas) que el nodo al que llama el nodo button en su atributo method.| \\ \\ ===== Generar UUID ===== \\ Generar un UUID con Javascript. \\ function generateUUID() { var d = new Date().getTime(); var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (d + Math.random()*16)%16 | 0; d = Math.floor(d/16); return (c=='x' ? r : (r&0x3|0x8)).toString(16); }); return uuid; } \\ ===== Obtener la fecha actual ===== // Ejemplo de uso: var f=getFecha("dmy","/"); function getFecha(formato,separador) { var sToday = ""; var today = new Date(); var dd = today.getDate(); var mm = today.getMonth()+1; // De 0-11 así que sumamos 1. var yyyy = today.getFullYear(); if(dd<10) { dd='0'+dd; } if(mm<10) { mm='0'+mm; } if (!separador) { separador="/"; } if (formato) { switch (formato){ case "dmy": sToday = dd+separador+mm+separador+yyyy; break; case "mdy": sToday = mm+separador+dd+separador+yyyy; break; case "ymd": sToday = yyyy+separador+mm+separador+dd; break; default: sToday = dd+"/"+mm+"/"+yyyy; break; } } else { sToday = dd+"/"+mm+"/"+yyyy; } return sToday; } =====Información Queue Dispositivo===== \\ COLECCION QUE MUESTRA LA CANTIDAD DE DATOS QUE QUEDAN POR ENVIAR.\\ \\ Esta colección se puede complicar todo lo que se quiera, incluso poniendo **Join** con otras tablas, para decir de que tabla faltan los datos por enviar desde el dispositivo móvil a la central.\\ \\ La tabla MASTER_REPLICA_QUEUE, solo se puede utilizar para ver datos, nunca para escribir directamente en la misma, ya que es una tabla de sistema, con la cual se enviarán los datos desde el dispositivo móvil al servidor central.\\ \\ DATOS PARA ENVIAR \\