Etiqueta

Mostrando entradas con la etiqueta jsClient. Mostrar todas las entradas
Mostrando entradas con la etiqueta jsClient. Mostrar todas las entradas

02 julio 2018

Uso del método "$pushdata"

Para dar soporte a las notificaciones "push", disponemos de un nuevo método para instancias "remote form" denominado $pushdata(), con la siguiente sintaxis:

$pushdata(wRow[~&cErrorText])

Usado en conjunción con $clientcommand("openpush";row()). El método provoca una llamada al método $pushed de la instancia "remote form" del cliente, pasando "wRow" como parámetro, su formato debe ser compatible JSON, por lo que solo puede contener tipos:

"character", "boolean", "integer", "number", "date", "list" o "row".

Omnis mantendrá encolados los datos enviados desde cada "remote task", independiente de las llamadas "openpush" que tenga asociadas. Tan pronto como llega una petición "push" de un cliente, Omnis envía los datos a la cola, para que el cliente la procese cuando esté disponible.

Cuando el cliente procesa la respuesta se emite una nueva petición "push", indicándole al servidor que recibió los datos. Esto permite al servidor eliminar de la cola, los elementos de datos ya procesados liberando memoria. La conexión permanece abierta y tan pronto como desde del servidor se ordena la ejecución de "$pushdata", Omnis envía los datos al cliente, puede dar la impresión de que existiese una conexión permanente entre servidor y cliente, pero no es así, sino que simplemente se establece un control de datos enviados y recibidos por los clientes, evitando pérdidas.

La práctica habitual sera que los clientes guarden la información entregada por "$pushdata" en una variable o en subconjunto de variables de ambito instancia, para actualizar su "remote form".

29 enero 2018

Obtener el UUID de la sesión Omnis Studio Web

Entre las muchas cosas que incorporó la versión 8.1 de Omnis Studio para la Web, nos contaba los chico de Omnis, que ahora al establecerse la comunicación desde el cliente con el servidor de aplicaciones web, se genera un UUID de identificación para la sesión, el cual es guardado como una cookie y enviada como parámetro cada vez que se produce un intercambio de datos. La cookie caduca después de un año, tras el cual, se generará un nuevo UUID. Naturalmente las cookies deberán estar habilitadas, tanto en el servidor web, como en los clientes para que esto funcione.



Nada mas leer esto me preguntaba cómo podríamos desde programación Omnis, obtener el UUID asignado y así poder usarlo, para (por ejemplo) guardar y ajustar preferencias relativas a la sesión en uso, la respuesta viene de la mano de javascript, ya sabemos que podemos incluir código javascript, en los métodos de ejecución exclusiva en el cliente, habitualmente usamos el método "$init" en nuestros "remote-form" con éste propósito, a continuación mostramos el código necesario para la obtención del UUID asignado a la sesión:

JavaScript: var getCookie = function (name) {
JavaScript: {    var cookies = document.cookie.split(';');}
JavaScript: {    for (var i = 0 ; i < cookies.length ; ++i) {}
JavaScript: {        var pair = cookies[i].trim().split('=');}
JavaScript: {        if (pair[0] == name) return pair[1];}
JavaScript: {    }}
JavaScript: {    return NULL;}
JavaScript: }
JavaScript: lIDCookie = getCookie("OMNISCLIENTID");
Do method setIDCookie (lIDCookie)
"lIdCookie" es una variable local y "setIDCookie" es el método (de ejecución en el servidor) que recibirá "lIDCookie" como parámetro.



22 enero 2018

Aplicar CSS a las líneas de un pop-menu en Omnis Studio Web

Aún existen esos "tipos raros" que dedican su tiempo libre a investigar como hacer ciertas cosas en programación con Omnis Studio, el reto que me plantee consistía en como conseguir espaciar las líneas que componen un pop-menú en Omnis Studio para la Web, la siguiente imagen describe lo que se pretende conseguir:


Haciendo un poco de investigación, se puede observar que omnis monta una tabla (etiqueta html ≤table≥) a la que asigna un nombre de clase (atributo class) compuesta del siguiente modo: [nombre-del-remoteform]_[id-del-objeto-pop-menu]_clientTable de modo que lo que hice fue incluir un identificador de clase y algunos atributos CSS en el documento "user.css" que Omnis suministra al efecto.

Ejemplo:


.RemoteForm_1001_clientTable {
border-collapse: separate;
border-spacing: 0px 10px;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}

En el ejemplo, he añadido algo de separación  entre el primero y último elemento del grupo. Les animo a que prueben variantes del código expuesto adaptándolo a sus necesidades.

Otra variante de este CSS podría ser lo siguiente...

.RemoteForm_1001_clientTable td {
     height: 31px; 
}

...esto modificará únicamente las líneas del menú cambian su altura y por tanto también el espacio entre ellas, éste último caso es el que más me gusta y que uso habitualmente para mis menús.

NOTA: Creo que los ingenieros de Omnis se han hecho eco de éste artículo, pues en la versión 8.1.6, ya se incluyen nombres de clases CSS para poder realizar éste tipo de cambios más facilmente, para el caso que nos ocupa, sería cambiar ".RemoteForm_1001_clientTable" por ".omnis-menu-table", de éste modo funcionará para con todos los menús de nuestra aplicación.


14 diciembre 2017

Android Studio vs Omnis Studio

En éste artículo quiero comparar lo que supone crear una aplicación sencilla para un dispositivo Android, con dos diferentes herramientas para el desarrollo de "App's": Android Studio (exclusiva de la plataforma y gratuita) y Omnis Studio (multi-plataforma y de pago). Queremos que la aplicación sea capaz de crear una base de datos SQLite en el dispositivo, con tres campos: ID, Nombre y Apellido y cuatro botones para iteracción con el usuario: "Buscar", "Insertar", "Actualizar" y "Borrar", su aspecto y código necesarios se muestran a continuación:

Aspecto con Android Studio

Aspecto con Omnis Studio

Para añadir los elementos de la "interface" en ambos casos sólo ha sido necesario arrastrar y soltar componentes desde sus respectivas paletas, pero a la hora de girar el dispositivo, "Android Studio" a requerido programación adicional, mientras que con "Omnis Studio" no ha sido necesario incluir programación alguna.

A continuación indicaremos el código que ha sido necesario escribir en cada caso, empezando por la creación de la BBDD SQLite en el dispositivo:

Creación de la BBDD en Android Studio

public class Estructura_BBDD {

private Estructura_BBDD() {}

        public static final String TABLE_NAME = "datosPersonales";
        public static final String NOMBRE_COLUMNA1 = "id";
        public static final String NOMBRE_COLUMNA2 = "nombre";
        public static final String NOMBRE_COLUMNA3 = "apellido";

    public static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + Estructura_BBDD.TABLE_NAME + " (" +
                    Estructura_BBDD.NOMBRE_COLUMNA1 + " INTEGER PRIMARY KEY," +
                    Estructura_BBDD.NOMBRE_COLUMNA2 + " TEXT," +
                    Estructura_BBDD.NOMBRE_COLUMNA3 + " TEXT)";

    public static final String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + Estructura_BBDD.TABLE_NAME;
}

Creación de la BBDD en Omnis Studio

Do $cinst.$sqlobject.$execute('CREATE TABLE Empleados (Id INTEGER UNIQUE, Nombre TEXT, Apellido TEXT)')
      Returns IDcreatetable

Un apunte antes de continuar en cuanto a la programación asociada a cada botón, en el caso de "Andriod Studio" ha sido necesario añadir código adicional para poner los botones en modo "OnClickListener", cosa totalmente innecesaria en "Omnis Studio", salvando ésta diferencia, (no trivial) indicamos el asociado a cada botón:

Botón "Buscar" en Android Studio

botonBuscar.setOnClickListener(new View.OnClickListener() {
   @Override   public void onClick(View v) {
       SQLiteDatabase db = helper.getReadableDatabase();
       String[] projection = {
               Estructura_BBDD.NOMBRE_COLUMNA2,
               Estructura_BBDD.NOMBRE_COLUMNA3       };

       String selection = Estructura_BBDD.NOMBRE_COLUMNA1 + " = ?";
       String[] selectionArgs = { textoId.getText().toString() };

       try {
           Cursor c = db.query(
                   Estructura_BBDD.TABLE_NAME,         
                   projection,                         
                   selection,                          
                   selectionArgs,                      
                   null,                               
                   null,                               
                   null                                
           );

           c.moveToFirst();
           textoNombre.setText(c.getString(0));
           textoApellido.setText(c.getString(1));

       }catch (Exception e){
           Toast.makeText(getApplicationContext(),"No se han encontrado registros.", Toast.LENGTH_LONG).show();
       }
   }
});

Botón "Buscar" en Omnis Studio

On evClick
Do lRow.$define(i_ID;i_Nombre;i_Apellido)
Do lRow.$assigncols(i_ID;i_Nombre;i_Apellido)
Do $cinst.$sqlobject.$selectfetch("Select * from Empleados where Id = @[i_ID]";lRow;kFetchAll) 
              Returns IDselectfetch

Botón "Insertar" en Android Studio

botonInsertar.setOnClickListener(new View.OnClickListener() {
    @Override    public void onClick(View v) {
        SQLiteDatabase db = helper.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(Estructura_BBDD.NOMBRE_COLUMNA1, textoId.getText().toString());
        values.put(Estructura_BBDD.NOMBRE_COLUMNA2, textoNombre.getText().toString());
        values.put(Estructura_BBDD.NOMBRE_COLUMNA3, textoApellido.getText().toString());

        long newRowId = db.insert(Estructura_BBDD.TABLE_NAME, null, values);
        Toast.makeText(getApplicationContext(),"Insertado ID: " + newRowId, Toast.LENGTH_LONG).show();
    }
});

Botón "Insertar" en Omnis Studio

On evClick
Do lRow.$define(i_ID;i_Nombre;i_Apellido)
Do lRow.$assigncols(i_ID;i_Nombre;i_Apellido)
Do $cinst.$sqlobject.$insert("INSERT INTO Empleados (Id, Nombre, Apellido) VALUES (@[i_ID],@[i_Nombre],@[i_Apellido])";lRow)
             Returns IDinsert

Botón "Actualizar" en Android Studio

botonActualizar.setOnClickListener(new View.OnClickListener() {
    @Override    public void onClick(View v) {

        SQLiteDatabase db = helper.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(Estructura_BBDD.NOMBRE_COLUMNA2, textoNombre.getText().toString());
        values.put(Estructura_BBDD.NOMBRE_COLUMNA3, textoApellido.getText().toString());

        String selection = Estructura_BBDD.NOMBRE_COLUMNA1 + " LIKE ?";
        String[] selectionArgs = { textoId.getText().toString() };

        int count = db.update(
                Estructura_BBDD.TABLE_NAME,
                values,
                selection,
                selectionArgs);
        Toast.makeText(getApplicationContext(),"Registro actualizado.", Toast.LENGTH_LONG).show();
    }
});

Botón "Actualizar" en Omnis Studio

On evClick
Do lRow.$define(i_ID;i_Nombre;i_Apellido)
Do lRow.$assigncols(i_ID;i_Nombre;i_Apellido)
Do $cinst.$sqlobject.$update("UPDATE Empleados SET Nombre=@[i_Nombre], Apellido=@[i_Apellido] where Id = @[i_ID]";lRow;lRow)
              Returns IDupdate

Botón "Borrar" en Android Studio

botonBorrar.setOnClickListener(new View.OnClickListener() {
    @Override    public void onClick(View v) {

        SQLiteDatabase db = helper.getWritableDatabase();
        String selection = Estructura_BBDD.NOMBRE_COLUMNA1 + " LIKE ?";
        String[] selectionArgs = { textoId.getText().toString() };
        db.delete(Estructura_BBDD.TABLE_NAME, selection, selectionArgs);
        Toast.makeText(getApplicationContext(),"Registro borrado.", Toast.LENGTH_LONG).show();
        textoId.setText("");
        textoNombre.setText("");
        textoApellido.setText("");
    }
});

Botón "Borrar" en Omnis Studio

On evClick
Do lRow.$define(i_ID;i_Nombre;i_Apellido)
Do lRow.$assigncols(i_ID;i_Nombre;i_Apellido)
Do $cinst.$sqlobject.$delete("DELETE FROM Empleados WHERE Id = @[i_ID]";lRow)
              Returns IDdelete

Notemos que en el código Android se ha evitado deliberadamente la incorporación del código necesario para tratar las excepciones, salvo en el caso del botón "Buscar" donde se usa un "try-catch", para controlar el hecho que pueda no encontrarse el registro buscado. Omnis predefine un método para tratar las excepciones denominado "$sqldone", a continuación mostramos un ejemplo de uso:

;  Se ejecuta cada vez que concluye una operación SQL (asíncrona)
;  Abandona el método con el mensaje de error, si se produce.

Do $cinst.$sqlobject.$getlasterrortext() Returns lErr
If lErr<>"OK"
Calculate i_ID as 0
Calculate i_Nombre as ''
Calculate i_Apellido as ''
Do $cinst.$showmessage(lErr;"Error")
Quit method
End If

;  Se ejecuta uno u otro proceso según el resultado
Switch pID
Case IDselecttables
If pResult.$linecount=0
Do $cinst.$creaTabla()     ;; Si no existe se crea la tabla
End If
Case IDselectfetch
Calculate lRows as pResult.$linecount
If lRows=0
Calculate i_ID as 0
Calculate i_Nombre as ''
Calculate i_Apellido as ''
Do $cinst.$showmessage("No existe el ID";"Respuesta")
Quit method
End If
Calculate i_Nombre as pResult.C2
Calculate i_Apellido as pResult.C3
Case IDcreatetable
Do $cinst.$showmessage("Tabla creada";"Respuesta")
Case IDinsert
Do $cinst.$showmessage("Inserción realizada";"Respuesta")
Case IDdelete
Calculate i_ID as 0
Calculate i_Nombre as ''
Calculate i_Apellido as ''
Do $cinst.$showmessage("Entrada borrada";"Respuesta")
Case IDupdate
Do $cinst.$showmessage("Actualización realizada";"Respuesta")
Default
Calculate i_ID as 0
Calculate i_Nombre as ''
Calculate i_Apellido as ''
Do $cinst.$showmessage("Error inesperado")
End Switch

En ocasiones los programadores y compañías dedicadas al desarrollo y mantenimiento de software, nos preguntamos ¿Porqué pagar por una herramienta, cuando existe otra que es gratis?, pero definitivamente puedo decir que en muchas ocasiones lo "barato" sale caro. Omnis Studio permite el desarrollo de aplicaciones para dispositivos móviles (Android, iOS y Windows), aplicaciones de escritorio (MacOS, Windows, Linux) o aplicaciones para la Web, sin necesidad de usar más herramientas que el propio Omnis Studio. El ejemplo de eficacia que hemos expuesto, compara una herramienta que sólo permite el desarrollo para dispositivos Android, por lo que el código resultante no podrá ser ejecutado en (por ejemplo) un dispositivo iOS, en cambio el código Omnis, puede ser ejecutado sin cambio alguno, sobre dispositivos iOS o Windows 10.

Juzguen ustedes mismos sobre si lo "barato" sale caro, llevo trabajando con Omnis Studio por unos 20 años ya, período durante el que las tecnologías han sufrido muchos y diferentes cambios que han hecho, al mismo tiempo, aparecer y desaparecer lenguajes de programación, pero Omnis Studio a sabido adaptarse a los tiempos y a tiempo con gran lujo y esmero.

Programar con Omnis Studio hace que me guste éste trabajo.

13 noviembre 2017

Componentes JSON&JS (Parte 12 de 12)

El JavaScript     

Una vez creado el fichero JSON del control y agregado a la carpeta Omnis correspondiente, será el momento para añadir el archivo JavaScript que le da soporte (si hemos usado el "JSON Control Editor" esto se habrá hecho automáticamente). Para hacerlo manualmente deberemos añadir lo siguiente al fichero html, que cargue nuestro formulario remoto:
 ≤script type="text/javascript" src="scripts/ctl_net_omnis_mycontrol.js"≥≤/script≥
Si lo colocamos bajo la sección para scripts del archivo "jsctempl.htm" (en la carpeta html) haremos que siempre se incluya en la página HTML que Omnis genera automáticamente para probar nuestro formularios remotos, pero, para la aplicación final, también deberemos incluirlo en la página HTML que lance la aplicación web o móvil desplegada.

06 noviembre 2017

Componentes JSON&JS (Parte 11 de 12)

html    

Es obligatorio y permite especificar cómo se generará el HTML inicial que remitirá al cliente el control (es el contenedor del control). Posee los siguientes elementos:
  • template
Obligatorio. Básicamente consiste en un texto que conforma la plantilla con el "div" que contendrá el control. Por ejemplo: ≤div %o %s data-props='%p' data-mvprops=‘%m’≥≤/div≥:

JsControls sustituirá el "%o" por los atributos del JavaScript, mediante su "id", por lo que deberá especificarse este elemento, reemplazará el "%s" con el atributo de estilo para la "div", basándose en las propiedades que soporta el control, también reemplazará el "%p" según las propiedades de control que siempre que no sean multi-valor. "%p" es reemplazado por una cadena JSON, que describe un objeto, donde cada uno de sus miembros contiene el nombre de la propiedad y su valor. 
El valor puede haber sido asignado por Omnis según lo requerido, para ciertos tipos de propiedades, tales como "color" e "icon". El cliente JavaScript usará esta cadena para componer un objeto adicional, con la configuración de la propiedad.

JsControls también reemplazará "%m" con las propiedades de control multi-valr. "%m" deberá omitirse si el control no hace uso de éste tipo de propiedades. Como en el caso de "%p", "%m" es sustituido por una cadena JSON, excepto que se trata de una matriz de objetos, con una entrada para cada elemento o valor-múltiple.
  • extrastyles
Opcional. Texto no superior a 255 caracteres con los atributos de estilo extra para incluir junto con el atributo de estilo "%s" en la plantilla, por ejemplo: "Margen: 2px".
  • padding
Opcional. Deberá ser un entero utilizado para establecer el "padding" (en píxeles) junto con "%s".
  • relativeposition
Opcional y booleano. (por defecto "false") Si es "true", el atributo de estilo que reemplaza "%s" usará posicionamiento relativo en lugar de absoluto. 
  • nowrap
Opcional y booleano. (por defecto "false") Si es "true", el atributo style que reemplaza el "%s" incluirá "white-space nowrap".
Ejemplo:
"html": {
"template": "
", "extrastyles":"margin:1px;"
}
La "div" resultante para el control podría verse así:

≤div style='position:absolute; top:0px; left:0px; height:106px; width:88px; font- family:'Times New Roman',Georgia,Serif; font-size:12pt;font- weight:bold; font- style:italic;text-align:right;color:#00FFFF; overflow- x:auto; overflow-y:auto;margin:1px;' data-backgroundcolor='#555555; rgba(85,85,85,1.0000)' data-dragmode='1' data- effect='1' data-linestyle='1' data-bordercolor='16711935' data- props='{"headercolor":"#FF0000","headericon":"icons/datafile/omnispic/001663 n16.png? 46", "rangeofinternalconstants":14, "rangeofexternalconstants":5, "headerpattern": 1, "headerfontstyle":4, "headerlinestyle":7, "headermultiline":"Lots of text entered like this\rwith multiple\rlines\r", "headerset": 13, "headerremotemenu":"NewRemoteMenu", "headerfont":"Courier New,Monospace"}'  data- mvprops='[{"mvprop1":1,"mvprop2":false,"mvprop3":""}, {"mvprop1": 2,"mvprop2":true, "mvprop3":"NewRemoteMenu"}, {"mvprop1": 2,"mvprop2":true,"mvprop3":"aaaa"}]'≥≤/div≥
Es importante el uso de comillas simples para encerrar los atributos de la plantilla, ya que JSON incluye comillas dobles. JsControls escapará el uso de comillas simples en el JSON que se inserten en como \u0027.


customtabname

El elemento "customtabname" es opcional y permite especificar el nombre que tendrá en la ficha de propiedades el control, al mostrarse sobre el "Property Manager". 

    30 octubre 2017

    Componentes JSON&JS (Parte 10 de 12)

    methods   

    Es opcional y permite especificar los métodos "client-executed" que proporciona el control. Cada miembro del grupo identifica un método. El nombre de cada uno es el también el nombre del método, incluyendo su prefijo "$". Los elementos válidos para la definición de un método son:
    • id
    Es obligatorio, será el número (entero positivo) del método. Debe ser único dentro del contexto del control. Es utilizado internamente por Omnis.
    • desc
    Es obligatorio, y deberá consistir en un texto descriptivo del método. 
    • type
    Es obligatorio e indica el tipo de dato que retorna el método. ("integer", "boolean", "character" o "list")
    • parameters
    Es opcional. Consiste en una matriz que describe los parámetros del método. Cada miembro de la matriz es un parámetro con los siguientes atributos: 
    • name
    Es obligatorio y es el nombre del parámetro. Omnis insertará el carácter "p" al comienzo de este nombre.
    • desc
    Es obligatorio y deberá consistir en un texto descriptivo del parámetro. 
    • type
    Es obligatorio e indica el tipo de datos que admitirá el parámetro. ("integer", "character", "boolean" o "list").
    • altered
    Opcional. Deberá ser booleano. (por defecto "false") Si es "true", el parámetro se marcará como no-alterable.  
    • optional 
    Opcional. Deberá ser booleano. (por defecto "false"). Si es "true", el parámetro se marcará como opcional. 
     Ejemplo:
    "methods": {
       "$mymethod1": { 
          "id": 1,
          "desc": "This is my method", 
          "type": "integer", "parameters": [
       {
          "name": "p1",
          "type": "character", 
          "altered": true,
          "desc": "The parameter p1"
       },
       {
          "name": "p2",
          "type": "integer",
          "desc": "The parameter p2", 
          "optional":true
        }
       ]
      }
    }

    25 octubre 2017

    Componentes JSON&JS (Parte 9 de 12)

    events  

    Es opcional y permite especificar los eventos que generará el control (además de los indicados en el grupo "flags"). Cada miembro del objeto events identifica un evento. El nombre de cada uno es también el nombre del evento, incluyendo su prefijo "ev". Se pueden incluir ciertos eventos estándar, tales como: "evClick", "evDoubleClick", "evTabSelected", "evCellChanges", "evHeaderClick" y "evHeadedListDisplayOrderChanged". Los elementos válidos de cada objeto-evento son:
    • id
    No debe especificarse para eventos estándar, pero, para el resto es obligatorio y debe ser un número entero positivo. Este identificador deberá coincidir con el identificador de evento, usado en la construcción del control JavaScript  y ser único dentro del contexto del mismo. 
    • desc
    No debe especificarse para eventos estándar, pero, para el resto es obligatorio y deberá consistir en un texto descriptivo del evento. 
    • parameters
    Define los parámetros del evento. Consiste es una lista, donde cada línea de la misma, identifica a cada uno de los parámetros, conformando por los siguientes elementos: 
    • name
    Es obligatorio y da nombre al parámetro. No deberá incluirse el prefijo "p". (ya que será agregado por Omnis) Tenga en cuenta que si se usara de nuevo el mismo nombre para definir otro parámetro, se tomará sólo su primera definición, ignorándose el resto, incluyendo su tipo y descripción.
    • type
    Es obligatorio e indica el tipo de datos que admitirá el parámetro. ("integer", "character", "boolean" o "list").
    • desc
    Es obligatorio y deberá consistir en un texto descriptivo del parámetro. 
     Ejemplo:
    "events": {
       "evNetOmnisControlOpened": { 
          "id": 1,
          "desc": "The event sent when the control opens", 
          "parameters": [
             {
                "name": "name",
                "type": "character",
                "desc": "The name event parameter"
             },
            {
               "name": "name2",
               "type": "integer",
               "desc": "The second event parameter"
            }
          ]
         },
         "evClick": {
         "parameters": [
            {
               "name": "zname1",
               "type": "character",
               "desc": "The zname1 event parameter"
            },
            {
               "name": "zname2",
               "type": "integer",
               "desc": "The zname2 event parameter"
            },
            {
              "name": "horzcell",
              "type": "character",
              "desc": "the horz cell event parameter"
            }
          ]
       }

    16 octubre 2017

    Componentes JSON&JS (Parte 8 de 12)

    multivalueproperties 

    El grupo de propiedades multivalor es opcional y permite configurar propiedades que pueden contener múltiples valores. A continuación describimos cada uno de sus miembros:
    • itemlistproperty
    Es obligatorio. Cuando un control admite propiedades con varios valores, éstas son guardadas en una lista. Cada fila de la lista contendrá el conjunto de propiedades de la pestaña o columna en particular. Llamaremos a la pestaña o columna "elemento". Esto significa que éstas propiedades mostrarán una lista de tipos, que se ocultará automáticamente sobre el "Property manager". 
    • itemcountproperty
    Es obligatorio y debe ser el nombre de una propiedad "integer" definida en el grupo de propiedades, de modo que se podrá especificar el número de elementos en la lista. Se podrá especificar un valor máximo para esta propiedad, a fin de restringir el número de elementos, de lo contrario se limitará a no más de 256. 
    • currentitemproperty
    Es obligatorio y debe ser el nombre de una propiedad "integer" definida en el grupo de propiedades. Identifica al elemento actual seleccionado en el "Property Manager", los cambios aplican sólo a propiedades multi-valor. 
    • moveitemproperty
    Es obligatorio y debe ser el nombre de una propiedad "integer" definida en el grupo de propiedades. Es utilizado para mover el elemento actual a una nueva posición en la lista de elementos.
    • properties
    Es obligatorio. Permite conformar su lista de valores. Cada miembro ("Property Name") deberá corresponder con el nombre de una propiedad de entre el grupo de propiedades principal; El valor para cada miembro conforma la lista de valores para la propiedad. Es importante no cambiar el orden de las columnas una vez se haya comenzado a utilizar el control.
    Ejemplo: 
    "multivalueproperties": { 
         "currentitemproperty": "curitem",
         "itemlistproperty": "itemlist",
         "moveitemproperty": "move",
         "itemcountproperty": "itemcount", 
         "properties": {
              "mvprop1": 1,
              "mvprop2": 2
             }
          }
    }

    constants 

    Es obligatorio y permite definir las constantes del control. Cada miembro del objeto constantes es en sí mismo un objeto que contiene los miembros que describen cada constante. Su nombre será también el nombre de la constante. Los elementos válidos para definir cada objeto constante son:
    • value
    Es el valor de tipo "integer" de la constante y es obligatorio.
    • desc
    Descripción de la constante. Un texto obligatorio, utilizado por el IDE como información adicional para la herramienta "catalog". 
    • group
    Identifica al grupo en el "catalog" al que pertenece la constante y es opcional. De forma predeterminada, todas las constantes pertenecerán al grupo "RF:jsControls-≤control name≥". Todas las constantes que figuren a continuación de la que contenga un nombre del grupo, se entenderá como pertenecientes a ese grupo, hasta que se especifique un nuevo nombre de grupo (si procede).
    Ejemplo: 
    "constants": { 
         "kNetOmnisControlHeaderColor": {
             "value": 123,
             "desc": "The description of this constant"
         },
         "kNetOmnisControl1Range1": { 
            "value": 3,
            "desc": "Range constant 1”, 
            “group": “Ranges"
         },
         "kNetOmnisControl1Range2": { 
            "value": 5,
            "desc": "Range constant 2"
         }
    }

    09 octubre 2017

    Componentes JSON&JS (Parte 7 de 12)

    properties

    Éste grupo es obligatorio. Contiene el conjunto de propiedades específicas del control. Cada uno de sus miembros es una propiedad y es en sí mismo un objeto que a su vez contiene los elementos que la describen. El nombre de cada miembro constituye el nombre de la propiedad, sin el prefijo "$".
    Los miembros válidos para cada propiedad son los siguientes:

    • id
    Es el identificador de la propiedad. Un entero positivo. Es obligatorio y es un campo crítico ya que Omnis usa éste dato para identificar la propiedad. Lo cual significa que no deberá cambiar estos valores de ID una vez que se ha comenzado a hacer uso del control. Id, debe ser único para todas las propiedades del control. Cuando "jsControls" carga el control, validará su unicidad. Normalmente se comenzar a numerar las propiedades desde 1. 

    • desc
    Es la descripción de la propiedad. Un texto obligatorio, utilizado por el IDE, por ejemplo, como "tooltip" de la propiedad en el "Property Manager". 

    • tab
    Es opcional y es el texto que identifica la ficha a la que pertenece en el "Property Manager". "custom" será la ficha predeterminada, si se omite. De lo contrario, deberá usarse uno de los siguientes valores: "custom", "general", "data", "appearance", "action", "prefs", "text", "pane", "sections", "java" o "column".

    • type
    Es obligatorio. Identifica el tipo de la propiedad. Puede ser uno de los básicos (integer, character, boolean o list) o uno específico como (color, dataname, font, icon, pattern, fontstyle, linestyle, multiline, set, o remotemenu). 

    • runtimeonly
    Es opcional y booleano, si es "true" indica que la propiedad es "runtime only". Su valor predeterminado si es omitido es "false". 

    • findandreplace
    Es opcional y booleano, si es "true" indica que la propiedad puede ser localizada mediante "find and replace". Su valor predeterminado es "false". 

    • extconstant
    Es opcional y booleano, si es "true" indica que la propiedad está restringida a un rango de constantes predefinidas para este control. Esto afectará al menú emergente en el "Property Manager". Puede usarse tanto con propiedades de tipo "integer" como con las de tipo "set"; En este último caso, el primer miembro del rango deberá ser una constante con valor cero, para representar al "set" vacío. 

    • intconstant
    Es opcional y booleano, si es "true" indica que la propiedad está restringida a un rango de constantes predefinidas desde el núcleo de Omnis. Esto afectará al menú emergente en el "Property Manager". Puede usarse tanto con propiedades de tipo "integer" como con las de tipo "set"; En este último caso, el primer miembro del rango deberá ser una constante con valor cero, para representar al "set" vacío. "extconstant" y "intcontant" no deben ser "true" al mismo tiempo. 

    • constrangestart y constrangeend
    Ambos deben existir si "extconstant" o "intconstant" son "true". En el caso de "intconstant", son "idents" (identificadores) de constantes que conformarán el rango de constantes a usar (podrá saber cuales son los "idents" de las constantes de núcleo Omnis, consultando el grupo "$constants" mediante el "Notation inspector"). En el caso de "extconstant", serán los nombres de las constantes definidas para el control; El conjunto estará entre "constrangestart" y "constrangeend" y en el orden en que figuren en el fichero "control.json". Tenga en cuenta que cuando se utiliza con un "set", los valores de las constantes deberán corresponderse con el "bit mask" (máscara) usada para representar el "set". 

    • min  y 
    --> max
    Son opcionales y solo se aplican cuando el tipo es "integer". Especifican los valores mínimos y máximos de la propiedad. 

    • initial
    Es opcional y puede ser utilizado para indicar el valor inicial de la propiedad. Para los tipos "character", deberá ser un texto. Para tipos "integer", deberá ser un número entero. Para tipos "boolean" deberá ser un valor booleano.
    Ejemplo:
    "properties": { 
         "headercolor": {
              "id": 1, 
              "desc": "The header color of the control", 
              "type": "color",
              "tab": “appearance”,
              "initial": 255
         },
         "headericon": { 
              "id": 2,
              "desc": "The header icon of the control", 
              "popuptype": "icon",
              "tab": "appearance"
         },
         "rangeofexternalconstants": { 
           "id": 3,
           "desc": "Range of external constants", 
           "type": "integer",
           "extconstant": true,
           "constrangestart": "kNetOmnisControl1Range1",
           "constrangeend": "kNetOmnisControl1Range3",
         }
    }