{{indexmenu_n>1}} ====== Javascript code examples====== \\ To be able to use the functions **cstr**, **now**, **len**, etc from VBScript, a "vbscriptsupport.js" file has been implemented which we will have to include at the companies collection, that displays these functions to have it availables when we use scripts javascript by using the notation “vbSupport.left(XXXXX)”, “vbSupport.now()”, “vbSupport.cstr(XXXXX)”, etc. \\ =====Code that browses a full collection===== \\ Code to browse a collection record by record (When are too many data to load them in memory). \\ 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; } \\ =====Browsing a collection/content with few data===== \\ A collection with few data (for instance, the details rows of a contents), may be browsed by loading the record in a memory array instead browsing record by record.\\ \\ 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 \\ ===== Getting an object (row) from a collection, having the value of a field of such object ===== \\ 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(); } \\ ===== Getting an object (row) from a collection, by using an SQL with more than a field (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); } } \\ ===== Creating Record with Script ===== \\ Creating a new record with script. The script wil be able to be executed in a **create, insert, delete, button**...\\ \\ 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(); } \\ ===== Showing messages by screen ===== \\ We have several ways to show a message on screen.\\ \\ |< 95% 30% - >| ^ Command ^ Description ^ | ui.msgBox("Ejemplo", "Mensaje", 0);\\ msg1=ui.msgBox("Ejemplo", "Mensaje", 2);\\ msg2=ui.msgBox("Ejemplo", "Mensaje", 4); | Message of the framework that needs answer by the user. The last parameter can be: * **0**, returning no value, it only appears an OK button. * **2**, showing us 2 buttons: ACCEPT and CANCEL that return 1 or 2 respectively, as one or the other is pressed. * **4**, that shows us 2 buttons: YES and NO that return 6 or 7 respectively, as one or the other is pressed. | | ui.showNotification(1, “Título”, “Mensaje”); | Notification in the top bar of notifications, an ID is specified (1) in order if we want to modify the notification further, we can use the same command with another message and the one which did exist already will be modified. | | ui.dismissNotification(1); | It deletes the Notification from the top bar of notifications made with the "ShowNotification", we have to specify the ID of the notification to specify the message we want to remove. | | ui.showToast("Se ha recibido un nuevo mensaje"); | Mensaje TOAST message of the operative system, see the screenshot below. The message disappears automatically after a couple of seconds on screen. | \\ **Example of code:** \\ ===== Leave the current window. onback node. ===== \\ \\ ===== Executing some action WITHOUT replicating the operations ===== \\ If we are working offline, by default, everything is done at the framework is stored at the tabla master_replica_queue of the device in order to replicate it to the server later.\\ If at any time we don´t want this happens, we can make any operation directly over the database of the device without it being replicated to the server. \\ This behaviour is very used in the maintenances over the local database of the device to delete information that we do not need yet (Reports or old Orders, etc...).\\ The methodology is very simple, it is about to create a collection that points directly to the device database. By general rule, we usually call it always the same in all projects: "ForMaintenance". What is really special is the connection="mtto" attribute that this collection has, which points to the ****node that such **name** has. \\ It cannot be 2 **** nodes with the same name at the mappings. It is advisable that all the **** nodes are defined at the APP node and so have them all "centralized" at an only place and being availables to any collection to which we define the **connection="mtto"** attribute (or any other name we have set to the connection node). \\ \\ ===== User MACRO to change the filter of a collection ===== \\ We can crate a MACRO of user in a collection to replace in real time the SQL of a collection, being able to replace even the SQL of the full collection. \\ \\ \\ Once defined the macro in the collection, we can use it later to change the value of that macro and therefore changing the SQL.\\ \\ In this concrete case, we change the filter of a collection when the value of a "MAP_FTTIPOGASTO" field changes. \\ \\ \\ ===== Variable global of from the collection ===== \\ We can createa variable that thave global scope and so they can be available from any place of the application.\\ \\ An option would be including a **.js** file in the companies collection, where they would be defined with "var" the different javascript variables that we are going to need to be globals.\\ \\ The other method would be the one that has been used so far in the platform:\\ \\ // 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"); \\ ===== Going to another tab or group ===== \\ ui.showGroup(self.MAP_PAGINA,"##LEFT_IN##",500,"##LEFT_OUT##",500); \\ ===== Code to Create/Edit/Delete a record of a 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 esta 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 //o 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("¿Está 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(); } } } \\ =====Types of errors===== \\ \\ =====Button with Script===== \\ CODE TO MAKE A BUTTON. \\ \\ It is made up of **2 nodes**:\\ \\ |**Node 1** |**Prop of type "B" (button)**| It is the node that defines where it comes up, the title and which node it calls to execute its code. It has the method attribute, that is the one which makes the call to the node that has its code, the name "ExecuteNode", is the name of the "method" name, and it has to be called in the same way (uppercase-lowercase).| |**Node 2** |**Node in which the code to execute is put**| The name is defined by the user, and as only requirement, it is the node name, it has to be called the same (uppercase-lowercase) that the node to which the button node calls in its method attribute. | \\ \\ ===== Generating UUID ===== \\ Generating an UUID with 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; } \\ ===== Getting the current date ===== \\ // 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; } \\ =====Queue Device Information===== \\ COLLECTION THAT DISPLAYS THE AMOUNT OF MISSING DATA TO SEND.\\ \\ This collection can be as complicated as we want to, even by putting **Join** with another tables, to say from which table remains the data to be sent from the mobile device to the central.\\ \\ The MASTER_REPLICA_QUEUE table, only can be used to see data, never for writing directly on it, since it is a system table, with which the data will be sent from the mobile device to the central server.\\ \\ DATOS PARA ENVIAR \\