{{indexmenu_n>1}}
====== Más sobre Nodo PROP ======
\\
Aquí hemos más añadido más información del Nodo Prop para ampliar un poco más lo que previamente ya habíamos explicado. Adjuntamos más ejemplos en este apartado, un poco más sencillos y otros que no son tan usados.
Para la etiqueta del campo (label) se busca por orden de prioridad:
- Atributo **title**.
- Si el anterior no estuviese definido, se busca la cadena que haya entre **título que queramos**.
- Finalmente, si ninguno de los anteriores estuviese definido, se utiliza el nombre del campo contenido en el atributo **name**.
Los atributos del XML se tienen que escribir en minúsculas y los nombres de objeto (atributo name) se escriben en MAYÚSCULAS. (ésto último es una convención de los programadores XOne, no tiene por qué ser así obligatoriamente.)
\\
\\
===== EJEMPLO PROPIEDADES XONE =====
Recursos Propios\\
\\
===== Atributos Obligatorios =====
==== name="Valor" ====
\\
Este atributo contiene el nombre del objeto **en MAYUSCULAS**, éste debe ser único dentro de la colección. Si hubiesen dos nombres de objeto repetidos, se cogería el primero que se haya definido.\\
\\
* Para los campos enlazados de otras colecciones se pone el prefijo "MAP_" al nombre del objeto, esto le indica a la maquinaria que dicho campo no se graba, es simplemente de lectura.
* Para los campos de tipo "NC"(un entero que cogemos como bits separados) se pone el prefijo "%" al nombre del objeto.
* Para los campos calculados (también llamados campos tipo fórmula) se pone el prefijo "$" al nombre del objeto.
* Para los campos tipo "Z" (tipo CONTENT, relación de 1 a n con otra colección) se pone el prefijo "@" al nombre del objeto.
==== group="Num. Pestaña" ====
\\
Este atributo contiene un número indicando a qué pestaña pertenece este campo, de forma que los campos que forman el formulario de introducción de datos estén agrupados y al mismo tiempo se optimice su visualización en dispositivos con una pantalla reducida como es el caso de los dispositivos móviles.\\
\\
^ Vista Pestañas en POCKET PC ^ Vista Pestañas en Blackberry ^ Vista Pestañas en IPhone ^
| {{wiki:pda1.jpg?nolink}} | {{wiki:bb_pestanas.jpg?nolink}} | {{wiki:iphone.jpg?nolink}} |
\\
==== visible="Valor" ====
\\
Este atributo indica donde vamos a poder ver dicho campo en los distintos modos en que podemos ver una colección. \\
\\
Este campo puede verse como un entero con 4 bits, cada uno de los cuales los podemos sumar en binario y nos dará el valor que necesitamos.\\
\\
^ Posición BIT en binario ^ Visibilidad ^
| 0 ( 0 0 0 **__0__** ) | Visible en modo Edición |
| 1 ( 0 0 **__0__** 0 ) | Visible en modo Listado (Grid) |
| 2 ( 0 **__0__** 0 0 ) | Visible en modo Content (Grid asociado a otra colección principal) |
| 3 ( **__0__** 0 0 0 ) | Visible en modo Combo para filtrar |
\\
**Ejemplos**:
\\
^ Valor ^ Equivalente Binario ^ Visibilidad ^
| Visible="7" | 0111 | Visible en modo de Edición, listado y content |
| Visible="3" | 0011 | Visible en modo de Edición y listado |
| Visible="1" | 0001 | Visible sólo en modo de Edición |
| Visible="0" | 0000 | No Visible en ningún modo |
==== fieldsize="Valor" ====
Este atributo se emplea para indicar el tamaño visible del campo en pantalla.
==== size="Valor" ====
Este atributo se emplea para indicar el tamaño real en Base de Datos.
==== type="Valor" ====
\\
Este atributo se emplea para indicar el tipo de control visual que utilizaremos para dar valor a ese objeto.\\
\\
IMPORTANTE:
\\
Los tipos reseñados en la columna BD son los valores **RECOMENDADOS** que funcionan 100% en todos los DBMS, no olvidemos que la tecnología XOne puede funcionar en multitud de dispositivos diferentes.
El uso de cualquier otro tipo de datos diferente a los mostrados en la tabla inferior (//char//, //nvarchar//, //tinyint//, etc) pueden hacer que su aplicación no funcione en algún dispositivo específico (PDA, BLACKBERRY…) o hacer que su aplicación no funcione con algún DBMS (ORACLE, MSSQL, MYSQL...), por el simple hecho de que dicho tipo no exista en ese DBMS o incluso, aunque esté soportado, malas experiencias con algunos de estos tipos en diferentes dispositivos nos hace desaconsejar su utilización.\\
\\
^ Control Visual ^ Tipo ^ Mappings ^ BD ^
| {{ :wiki:control_texto.png | }} | Texto | Type="T" | Varchar |
| {{ :wiki:control_numerico.png | }} | Numérico | Type="N" | Int |
| {{ :wiki:control_real.png | }} | Real | Type="N2" (*) | Double |
| {{ :wiki:control_fecha.png | }} | Fecha | Type="D" | Datetime |
| {{ :wiki:control_bit.png | }} | Bit | Type="NC" | Int |
| {{ :wiki:control_label.png | }} | Etiqueta | Type="TL" | |
| {{ :wiki:control_password.png | }} | Password | Type="X" | Varchar |
| | Image | Type="IMG"(*2) | Varchar(100) |
| | Attach | Type="AT" | Varchar(100) |
| | Foto | Type="PH" | Varchar(100) |
(*) En el tipo de datos Real, en el mappings hay que poner type=”N2, N3, N4…”, especificando después de la N el número de decimales que queremos para dicho campo.\\
(*2) En android, si se define barcode="tipo", se generará un código de barras que codifique los datos guardados en este prop. Tipos soportados: codabar, code11, code128, code25, code39, code93, datamatrix, ean128, ean13, ean8, isbn, issn, itf14, identcode, interleaved2of5, leitcode, msi, onecode, pdf417, planet, postnet, rm4scc, upca, upce.\\
/*
===== Adjunto (type="AT") =====
^ Atributo ^Descripción ^
| **showgallery="true"** | Al pulsar el botón de adjunto, mostrará en primer lugar la galería de fotos del dispositivo. |
| **path="/rutaabsoluta/"** | Al pulsar el botón de adjunto, mostrará en primer lugar la ruta especificada. |
\\
===Nuevo atributo para los tipos "AT"===
\\
Se ha implementado un nuevo atributo para los props type=”AT”, allowed-extensions="pdf;txt", que indica separado por “;” las extensiones permitidas cuando se saca a ventana de selección de ficheros.\\
=====Type="N"=====
Es un inputbox para introducir valores numéricos. El teclado ya saldrá únicamente para que se introduzcan números. Si el tipo fuese diferente y se desea que se muestre el teclado numérico solamente se deberá especificar el atributo input-type="numeric".\\
===Slider y Rounded-slider===
\\
A partir del attributo **viewmode**, en los props Type N, define estos controles:\\
* viewmode=”slider”
* viewmode=”rounded-slider”
\\
El atributo max, define el máximo valor que puede tener el control.\\
\\
|**ATRIBUTOS DEL Prop viewmode=”slider”**|
|**max**: Valor máximo representable. Por defecto: 10.|
|**min**: Valor mínimo representable. Por defecto: 0.|
|**left-bar-color**: Color de la barra de progreso, pero sólo la parte de la izquierda. Por defecto: Tema del S.O.|
|**right-bar-color**: Color de la barra de progreso, pero sólo la parte de la derecha. Por defecto: Tema del S.O.|
|**img-thumb**: Imagen del icono que desplazamos con el dedo.|
\\
|**ATRIBUTOS DEL Prop viewmode=”rounded-slider”**|
|**max**: Valor máximo representable. Por defecto: 10.|
|**min**: Valor mínimo representable. Por defecto: 0.|
|**progress-bar-color**: Color genérico de la barra de progreso. Por defecto: Tema del S.O.|
**Ejemplos**:
\\
\\
*/
===== Atributos para cambiar imágenes por defecto =====
\\
Se han incorporado ciertos atributos para cambiar los iconos por defecto del frame de Android. \\
\\
Iconos en :\\
|< 100% 180px - >|
^ Atributo ^Descripción ^
| **img="cadena"** | Permite definir la imagen que se utiliza en el botón principal del control. |
| **img-sel="cadena"** | Define la imagen cuando se da click en el botón definido por "**img**".\\ Todos los atributos que comiencen con "**img**", permiten tener un valor para el sufijo "**sel**".\\ Ejemplos: "**img**" **->** "**img-sel**" y "**img-delete**" **->** "**img-delete-sel**" |
| **img-delete="cadena"** | Define la imagen del botón borrar o limpiar para los controles de edición. |
| **img-search="cadena"** | Define la imagen del botón linkeado "lupa" para los controles de edición. |
| **img-spinner="cadena"** | Define la imagen del botón linkeado "combo" con showinline="true" para los controles de edición. |
| **img-phone="cadena"** | Define la imagen del botón teléfono en los nodos con atributo "**phone=true**". |
| **img-width="Entero"** | Permite definir el ancho del botón principal.\\ Para cualquier otro botón es añadir **-width** al final de la definición de imagen.\\ Ejemplos: **img-undo-width="60"** y **img-delete-width="60"**. |
| **img-height="Entero"** | Permite definir el alto del botón principal.\\ Para cualquier otro botón es añadir **-height** al final de la definición de imagen.\\ Ejemplos: **img-undo-height="60"** y **img-delete-height="60"**. |
| **img-undo="cadena"** | Define la imagen del botón undo para los controles de edición. |
| **undo-button="true|false"** | Indica si se muestra los botones de limpiar o undo en los controles de edición. |
| **img-date** | Permite definir fecha. |
| **img-time** | Permite definir imagen en controles tipo hora. |
| **img-att** | Indica si muestra un clip para adjuntar archivos.|
| **img-delete-width** | Permite ajustar la anchura del botón borrar o limpiar para los controles de edición.|
| **img-delete-height**| Permite ajustar la altura del botón borrar o limpiar para los controles de edición.|
| **img-phone-width** |Permite ajustar la anchura del botón teléfono. |
| **img-phone-height** | Permite ajustar la altura del botón teléfono. |
| **img-date-width** |Permite ajustar la anchura del botón fecha. |
| **img-date-height** |Permite ajustar la altura del botón fecha.|
| **img-time-width** |Permite ajustar la anchura del botón para controles tipo hora.|
| **img-time-height** |Permite ajustar la altura del botón para controles tipo hora. |
| **img-att-width** |Permite ajustar la anchura del botón para adjuntar archivos. |
| **img-att-height** |Permite ajustar la altura del botón para adjuntar archivos. |
\\
**CSS de ejemplo**:\\
\\
prop
{
img-spinner:arrow_down.png;
img-spinner-sel:arrow_down_click.png;
img-search:lupa.png;
img-search-sel:lupa_click.png;
img-delete:delete.png;
img-delete-sel:delete_click.png;
img-undo:undo.png;
img-undo-sel:undo_click.png;
img-phone:phone.png;
img-phone-sel:phone_click.png;
}
prop:AT
{
img:attachment.png;
img-sel:attachment_click.png;
}
prop:PH
{
img:camera.png;
img-sel:camera_click.png;
}
prop:IMG
{
img:firma.png;
img-sel:firma_click.png;
}
prop:VD
{
img:video.png;
img-sel:video_click.png;
}
\\
/*
====Soporte para imágenes con extensión .GIF. ====
\\
Se ha implementado la posibilidad de poner en props type=”IMG” imágenes con extensión .Gif
\\
*/
====Atributo Floating====
\\
Se ha implementado el atributo floating para cualquier tipo de nodo prop, funciona igual que el que se definía para los nodos frame, con Left y top.\\
\\
====Atributo Fixedbottom====
\\
Para tener en pantalla un diseño fijo y que los contents tengan un número fijo de registros visibles, se ha implementado el atributo fixedbottom=”true”.\\
\\
Este atributo se define en el prop de definición de contents y ha de combinarse con el atributo height=”-2”, el cual indica que el alto vendrá definido por el alto de los hijos contenidos en el control.\\
\\
\\
En cuanto a la colección contents, debe tener un alto de celda fijo (cell-height), así como el atributo loadall=”true” para que se carguen los registros del content desde el inicio.\\
\\
/coll>
\\
====Radio Button====
\\
Se ha implementado el radio button a partir de los props type NC, mediantes los siguientes atributos:\\
^ATRIBUTOS^
|**check-type** : define si se quiere que el NC tenga aspecto de radio button con el valor "radio".|
|**radio-group** : define un id, que el framework agruparar todos los NC que tengan el mismo valor de radio-group y se encargar de marcar y desmarcar según corresponda.|
\\
**Ejemplo**:
\\
/*
===== Límites Subida de Archivos =====
\\
Se han incorporado ciertos atributos para "limitar" la subida de ficheros en los type "**AT**" (Adjuntar fichero), "**IMG**" (Firma), "**VD**" (Vídeo) y "**PH**" (Foto).
Atributos:
|< 100% 240px - >|
^ Atributo ^Descripción ^
| **file-maxsize="XXX"** | Tamaño en bytes, tamaño máximo del fichero a subir. |
| **file-msgfail="Mensaje Error"** | Personalizamos el error si se intenta subir un fichero muy grande. |
| **file-maxwidth="800"** | Ancho máximo de la foto que se tome. |
| **file-maxheight="600"** | Alto máximo de la foto que se tome. |
Se debe implementar file-maxwidth y file-maxheight para los campos de tipo foto y firma para que los distintos dispositivos repliquen todos las fotos y firmas siempre con la misma resolución. Esto hará que el tamaño de las fotos sea más predecible y de pequeño tamaño, y evitará problemas de memoria en dispositivos de gama baja.
===== Tipos de Controles =====
\\
==== TYPE "X" ====
\\
El type="X" es similar en apariencia al type="T", con la diferencia de que los caracteres introducidos en este campo se mostrarán en pantalla como asteriscos, puesto que es un campo de tipo password, por defecto con una codificación en BASE64, aunque con los siguientes atributos puede modificarse su comportamiento. \\
\\
**Atributos:**
|< 100% 240px - >|
^ Atributo ^Descripción ^
| **type="X"** | Este tiene que ir siempre, que es para indicar que es un campo de clave. |
| **hash-type="MD5"** | Esto es para indicar que es clave de tipo MD5. |
| **encode="HEX"** | este es para ver como viene la clave. La clave tiene que venir con las letras o todas en mayúsculas o todas en minúsculas, no pueden llegar con letras en mayúsculas y minúsculas en el mismo momento. Entonces si en esta propiedad le pones “HEX” en mayúsculas, es porque las letras vienen en mayúsculas en la clave y si le pones “hex” en minúsculas, es que vienen en minúsculas. |
==== TYPE "DR" ====
\\
El type="DR" (DRaw) es para poder dibujar en pantalla con el dedo, ideal para un campo de tipo FIRMA.\\
\\
**Atributos:**
|< 100% 300px - >|
^ Atributo ^Descripción ^
| **stroke-color="#333333"** | Para indicar el color de la línea que vamos a dibujar. |
| **stroke-width="4"** | Para indicar el tamaño en puntos de la línea que vamos a dibujar. |
| **apply-format-to-file="true"** | Para indicar que la imagen final incluya los estilos de formato que le hemos aplicado. Si éste parámetro se pone a false, el archivo final no tendrá colores y se aplicará el trazo en negro y fondo blanco. |
| **bgcolor="#FFFFFF"** | Color de fondo del control. |
| **img="fondo.jpg"** | Imagen que queremos poner de fondo. |
\\
**Ejemplo de código**:\\
ui.saveDrawing("FIRMACLIENTE") 'Con este método guardamos el fichero con la firma.
==== Campo FOTO (type "T") ====
\\
Para un campo de tipo FOTO, combinaremos el uso de un campo de type="T" que contendrá el nombre del fichero a transmitir con un campo de type="IMG" para tener una previsualización del fichero, para ello hacemos uso de un botón que llame a la cámara y deje el resultado de la foto en los campos de texto e img.\\
\\
Ejemplo de código:\\
\\
====Type=”T” con tooltip flotantes====
\\
Son Props con tooltip flotante, cuando el usuario pulsa sobre el campo el tooltip flota sobre el texto que el usuario escriba.\\
\\
^Atributos^
|**floating-tooltip**: Activa el tooltip flotante. |
|**expanded-hint-color**: determina el color del texto del tooltip cuando esta expandido.|
\\
Ejemplo:\\
==== Type= WEB ====
\\
\\
**Campo Tipo Web**
\\
\\
Un campo type="WEB" es como un iframe de html. Tras especificarle un ancho y alto, lo cargamos de valor especificando una dirección web o asociandole código HTML directamente.\\
\\
\\
Definimos un nodo de tipo web de la siguiente manera:\\
\\
\\
\\
Si se quiere que el tipo web se vea de forma correcta, cuando no tiene datos hay que inicializarlo con el siguiente valor:\\
\\
self.MAP_MI_TIPO_WEB = “”
\\
\\
^Atributos^ ^
| **scales-to-fit** |Aplica un viewport que se ajusta al ancho del webview, perosolo en el caso de que el HTML no tenga uno ya definido. Solose aplica este atributo cuando se carga el webview con un HTMLa fuego y no sirve para URLs.|
\\
\\
**Ejemplos:**
\\
Pone un vídeo de YouTube, únicamente teniendo el valor del vídeo en YouTube.\\
\\
function DevolverIframeVideoYoutube(sUrlYoutube,objeto){
if(sUrlYoutube == ""){
ui.showToast("Error, URL de youtube inválida");
return "";
}
var longitud = sUrlYoutube.length;
var urlIndice = sUrlYoutube.indexOf("watch?v=",1);
if(urlIndice != -1){
// Es una URL completa. Parseamos y sacamos el código.
if(urlIndice >= longitud){
// ui.ShowToast "Error, URL de youtube inválida”
return "";
}
sUrlYoutube = sUrlYoutube.substring(urlIndice + 8, longitud);
//Vemos si hay más parámetros después del código del vídeo,
//para ignorarlos.
var urlIndiceSiguenteParametro = sUrlYoutube.indexOf("&",1);
if(urlIndiceSiguenteParametro > -1){
//No hay parámetros, cogemos desde aquí hasta el final nos vale.
//}else{
//Hay parámetros. La posición del primer parámetro la hemos calculado
//a partir del InStr, así que se la sumamos para coger la posición
//en la cadena completa.
sUrlYoutube = sUrlYoutube.substring(1, urlIndiceSiguenteParametro - 1);
}
//objeto("MAP_IMG_FIJACAPITULO")="https://www.youtube.com/embed/" + sUrlYoutube + "?rel=0&autoplay=1"
//objeto.MAP_IMG_FIJACAPITULO = sUrlYoutube;
//Concatenamos el iframe.
return "";
}else{
//objeto.MAP_IMG_FIJACAPITULO = sUrlYoutube;
return "";
}
}
*/
==== fixed-text ====
\\
Para controlar que la cantidad de caracteres introducidos NO sea mayor a un límite concreto, podemos usar conjuntamente los atributos //**fixed-text**// y //**size**//. \\
\\
Cuando se utilizan conjuntamente estos dos atributos, **fixed-text**="true" (por defecto es false), el atributo **size** indica el límite de caracteres que se pueden introducir en un campo. \\
\\
Por defecto, los campos tienen un límite máximo de 50 caracteres y los campos multilínea tienen 500 caracteres.\\
\\
Sintáxis:\\
\\
/* Ejemplo para que sólo puedan introducirse 120 caracteres en un campo. */
prop>
==== onchange="refresh#" ====
Este atributo indica que valores de la misma colección vamos a refrescar cuando la propiedad actual cambie de valor. \\
El número que aparece seguido del atributo onchange="refresh#" es el equivalente en decimal a un mapa de bits que indica qué partes del objeto hay que refrescar y cuáles no. \\
Lo que aquí se explica es únicamente para PDA(POCKET PC), puesto que pintar la pantalla con un dispositivo tan limitado en procesador y memoria era algo muy costoso y lento, en las plataformas más actuales (Android,Iphone,Windows Phone...) ya no es necesario, simplemente un **onchange="refresh"**, refrescará todo.
\\
El primer bit (bit=0) que se representaría como onchange="refresh1" o simplemente onchange="refresh", refrescaría todas las propiedades del objeto cargado pero no refrescaría los contents contenidos en el objeto.\\
\\
El segundo bit (bit=1) indicaría que se van a refrescar contents indicando en los bits consecutivos a este (2,3,4,5,6,7) que contents van a ser refrescados según el orden de aparición en la colección. \\
\\
Hay que combinar el bit 1 con los siguientes para indicar qué contents queremos refrescar:\\
\\
^ Posición BIT en binario ^ Visibilidad ^
| 0 ( 0 0 0 0 0 0 0 **__0__** ) | Vamos a refrescar todas las propiedades de la pestaña actual. |
| 1 ( 0 0 0 0 0 0 **__0__** 0 ) | Vamos a refrescar los contents |
| Si el bit anterior está a 1, pasamos a definir qué contents se van a refrescar. ||
| 2 ( 0 0 0 0 0 **__0__** 0 0 ) | 1 content por orden de aparición en la colección se refrescará |
| 3 ( 0 0 0 0 **__0__** 0 0 0 ) | 2 content por orden de aparición en la colección se refrescará |
| 4 ( 0 0 0 **__0__** 0 0 0 0 ) | 3 content por orden de aparición en la colección se refrescará |
| 5 ( 0 0 **__0__** 0 0 0 0 0 ) | 4 content por orden de aparición en la colección se refrescará |
| 6 ( 0 **__0__** 0 0 0 0 0 0 ) | 5 content por orden de aparición en la colección se refrescará |
| 7 ( **__0__** 0 0 0 0 0 0 0 ) | 6 content por orden de aparición en la colección se refrescará |
\\
\\
**Ejemplos**
\\
\\
^ Valor ^ Equivalente Binario ^ Visibilidad ^
| refresh1 | 00000001 | Se refrescarán todas las propiedades |
| refresh6 | 00000110 | Primer content de la colección |
| refresh11 | 00000111 | Primer content de la colección y todas las propiedades |
| refresh255 | 11111111 | Se refresca TODO el contenido DE LA PESTAÑA ACTUAL |
| refresh256 | 100000000 | Se evaluan los //disablevisible// de las pestañas, pero NO refresca el contenido |
| refresh511 | 100000000 | Se refrescará TODO |
\\
\\
Esta modalidad de refresco está diseñada para evitar grandes cargas de datos al refrescar un campo, por ejemplo, en aplicaciones de PC con objetos que contienen un número de contents superior a 5.\\
Normalmente, en el resto de dispositivos (pocketpc, blackberry) se utilizan únicamente los //refresh1// y //refresh255// ya que la carga de los contents se realiza independiente por pestaña al mostrar la misma al usuario y no es factible visualmente posicionar varios contents en una pestaña. \\
\\
En la WEB tampoco tiene sentido el refresco independiente de contents ya que hay que recargar la página cada vez que se refresca el objeto.\\
\\
Para pocketpc también se utiliza el bit 8 de la máscara onchange="**refresh256**" que se utiliza para comprobar las condiciones de los //disablevisible// que tengan las diferentes pestañas del objeto. \\
\\
Si una pestaña no está visible porque no se cumple una determinada condición del //disablevisible// y queremos que este visible en el momento que dicha condición sea modificada, tendríamos que utilizar este tipo de refresco.\\
\\
/*
==== mapcol="coleccion" | mapfld="campo" | default-mapcol="coleccion"====
\\
|**mapcol:** Indica que esta propiedad está enlazada con otra colección, o sea, que esto es un campo clave en la relación de muchos a uno.|
\\
Ejemplo de código:\\
En este ejemplo se indica que la propiedad cuyo nombre es IDTIPO es númerica y está enlazada con una colección llamada "[[wiki:2.-desarrollo-app:2.3.-entender_un_mapping:a.-estructura_xml:5.-nodo-prop:tiposusuario]]".\\
\\
El campo que se usa para enlazar esta propiedad con la colección externa se indica mediante el atributo 'mapfld'.\\
\\
El valor de este atributo debe ser el nombre de una colección válida dentro de la aplicación. Si la colección no está definida la interfase de usuario puede provocar un error al intentar enlazar esta propiedad con cualquier otra.\\
\\
Para este valor, se puede usar la macro ##OWNERCOLL## indicando que se está refiriendo a la colección en la cual está definido el objeto propietario de este objeto. \\
\\
Si la propiedad está declarada en una colección de detalles de documentos, la colección propietaria sería la colección de documentos de la cual está es contents.\\
\\
La capa de datos sustituye el nombre de esta macro cuando se pide el valor de esta propiedad, por lo que la colección tiene que estar siendo usada como contents. \\
\\
En caso de que la colección se obtenga directamente de la aplicación y no como una colección de contenido, el resultado de esta macro se obtendrá del atributo //default-mapcol// en caso de que esté definido dicho atributo, de lo contrario será una cadena vacía.\\
\\
|**default-mapcol:** Este atributo se utiliza para completar el anterior cuando la colección que contiene este propiedad se utiliza como colección base y no como colección de contenido.|
\\
En este caso el atributo //mapcol// devolverá el valor que tenga este atributo. \\
\\
En el ejemplo siguiente se muestra este comportamiento:\\
\\
\\
En este ejemplo, la colección “**Recibos**” se ha declarado para usarse como colección de contenido en la colección “**Documentos**”. Cuando esto se hace así, el atributo //mapcol// devuelve el nombre “Documentos” por ser esta su colección propietaria.\\
\\
En caso de que la colección “Recibos” se obtenga directamente de la aplicación y no como contenido de “Documentos”, el atributo //mapcol// devolverá el valor “Facturas” que es el valor por defecto.\\
\\
|**mapfld:** Indica qué campo de la colección externa es el que se usa para enlazarla con esta propiedad. En el ejemplo anterior, la propiedad IDTIPO está enlazada con la colección “TiposUsuario” a través del campo ID. |
\\
Las propiedades que contienen esta pareja suelen ser propiedades de enlace solamente, por lo que suelen ser invisibles en la edición (visible=”0”). \\
Ver más en: [[wiki:2.-desarrollo-app:2.3.-codigo:b.-controles-xone:2.-lupa-combo:start]]
==== linkedto="campo" | linkedfield="campo" ====
\\
Estos atributos indican que la propiedad se ha obtenido mediante un enlace con una colección externa. Se define para aquellas propiedades que comienzan con el prefijo MAP_ para indicar que proceden de un enlace entre tablas. \\
\\
El valor de **linkedto** debe ser el campo que se ha usado para enlazarlo con la colección externa, tal como indica el ejemplo siguiente:\\
\\
Este atributo se utiliza en combinación con el atributo **linkedfield** para indicar el enlace con otra colección. En este caso se indica que el campo **MAP_TIPOUSER** está enlazado mediante el campo **IDTIPO** con la colección “TiposUsuario”. El campo que le corresponde a la propiedad **MAP_TIPOUSER** es el de la propiedad **ETIQUETA** de la colección destino. El programa no utiliza esta relación para leer los datos, ya que esto lo hace la sentencia SQL, sino para hacer actualizaciones en cascada, como se describe más adelante.\\
\\
Otro uso que tiene el atributo //linkedto// es definir el nombre de la propiedad a la cual está enlazada una propiedad de tipo “bitmapped”, como se describe más adelante. \\
\\
La sección **[[wiki:2.-desarrollo-app:2.3.-codigo:b.-controles-xone:2.-lupa-combo:start|Relaciones entre Colecciones]]** contiene una explicación detallada de cómo construir enlaces usando los atributos anteriormente explicados.\\
\\
*/
==== newline="true/false" | lmargin="true/false" ====
\\
Con el atributo newline indicamos si queremos que un campo (propiedad) este al lado de otro, para ello este atributo debe tener valor a false, siempre este atributo se le debe asignar al campo que deseamos se muestre a continuación del otro.\\
Con lmargin indicaremos el espacio entre los dos campos.\\
\\
Ejemplo:\\
\\
Veremos como el campo de 2do Apellido esta a continuación del 1er Apellido.
1er APELLIDO2do APELLIDO
\\
Si quitamos estos atributos, el campo de 2do Apellido nos aparecerá debajo y no al lado.\\
\\
==== updates="campo" ====
\\
Este atributo es opcional y le indica a la aplicación que cualquier cambio que ocurra en esta propiedad provocará un cambio similar en la propiedad cuyo nombre se indica. \\
Esto se emplea para efectuar cambios en cascada, como por ejemplo, actualizar el valor de un campo llamado **DESCRIPCION** en un detalle de documento obteniéndolo del campo **DESCRIPCION** de la colección de productos enlazada. A continuación mostramos este caso particular:\\
\\
Ejemplo:\\
\\
\\
==== tooltip="Descripcion campo" ====
\\
Este atributo contiene un texto que será asignado al tooltip del control que se muestre en pantalla cuando se esté editando este campo.\\
Los tooltips pueden ser muy útiles para explicar de forma breve el objetivo de este campo o su función. \\
El mecanismo de muestra de tooltips que se emplea es el propio de Windows. \\
El siguiente ejemplo muestra un caso de uso de tooltip:\\
\\
\\
/*
==== showinline="true/false" ====
Muestra la colección enlazada a través del atributo mapcol como un desplegable.
*/
==== lines="valor" ====
Indica el número de líneas que ocupará el prop.
==== bgcolor="valor" ====
Valor del color de fondo en formato RGB. Puede ser expresado en decimal, hexadecimal (#), o binario (B).
==== forecolor="valor" ====
Valor del color de texto en formato RGB. Puede ser expresado en decimal, hexadecimal (#), o binario (B).
==== xlat="coleccion" | targetfield="campo" | create="true\false" | cmpfield="campo" | cmpvalue="valor" ====
\\
===xlat===
Indica que esta propiedad está “traducida” de un objeto procedente de una de las colecciones contenidas en el objeto. \\
Por ejemplo, se puede tener un encabezado de documento que contenga varios detalles y la cantidad de unidades del primer detalle se puede mostrar como una propiedad del documento en sí. \\
La capa de datos se encarga de buscar este valor en el correspondiente detalle cuando se lee esta propiedad, y en caso de que cambie de valor, se encargará de llevarlo a su correspondiente propiedad en el objeto contenido. \\
El efecto que tiene el uso de **xlat** y sus atributos asociados es el de llevar un campo que está en forma “vertical” (o en una fila) a una posición “horizontal” en forma de columna. Por este motivo, nosotros llamamos a este mecanismo “**horizontalización**” de campos.\\
\\
===targetfield===
Usado en conjunción con //xlat//. Define el campo del objeto contenido que era “traducido” dentro de este campo.\\
===create===
Usado en conjunción con **xlat**. \\
Cuando este atributo vale **true** se le está indicando a la capa de datos que en caso de asignarse valor a la propiedad traducida, si el correspondiente objeto en la colección contenida no existe, deberá crearse. \\
Así, en el ejemplo que poníamos anteriormente, si se le asignara valor a la cantidad “horizontalizada” y el detalle no existiera, la capa de datos lo creará y le asignará el valor correspondiente sin necesidad de programar nada.\\
===cmpfield===
Usado en conjunción con //xlat//. Este campo es el que usará la capa de datos para buscar el objeto del cual leerá y hacia el cual escribirá el valor de esta propiedad cuando sea necesario. El mecanismo consiste en buscar en la colección indicada por el atributo //xlat// aquel objeto cuyo campo de nombre //cmpfield// tenga el valor especificado por el atributo //cmpvalue//. En caso de que se desee usar el primer objeto disponible en la colección contenida, tanto este atributo como el siguiente deben valer //self//.\\
===cmpvalue===
Usado en conjunción con **xlat**. Contiene el valor que será buscado dentro de la colección de contenidos indicada por **xlat**. \\
En caso de que se desee usar el primer objeto disponible este atributo y el anterior deben valer **self**.\\
\\
**Ejemplo**:
\\
EFECTIVO
\\
\\
En este ejemplo se ha definido una propiedad llamada **MAP_EFECTIVO**. El objeto posee una colección de contenido llamada “CajaFisica” la cual tendrá varios objetos, uno para cada tipo de forma de pago usada.\\
\\
Si la aplicación pide el valor de este campo, la capa de datos buscará en dicha colección aquel objeto cuyo tipo sea //0// y devolverá el valor su campo **EFECTIVO**. \\
\\
Igualmente en caso de que se asigne valor a la propiedad **MAP_EFECTIVO**, la capa de datos buscará el objeto cuyo campo TIPO sea //0//, si no lo encuentra, lo creará, y le asignará el valor que acaba de recibir la propiedad al campo **EFECTIVO**.\\
\\
Esto evita la necesidad de recorrer por programa la colección de formas de pago, al mismo tiempo que permite mostrar cada uno de los importes como una columna (por ejemplo, para un listado) sin tener que denormalizar la tabla.\\
==== disableedit="condicion" ====
Se le pone una condición. Si esta condición se cumple, no deja editar, si por lo contrario, es falsa, se deja editar.
==== disablevisible="condicion" ====
Si se cumple la condición, todos los prop que pertenezcan a ese group se deshabilitarán.
==== formula="ext.[NOMBREFORMULA]" ====
Con este atributo le especificamos el nombre de la fórmula que queremos ejecutar para averiguar algún valor ejecutando una SQL.
\\
Ver más en la sección de Controles por tipo: [[wiki:2.-desarrollo-app:2.3.-codigo:b.-controles-xone:3.-controles-por-tipo:start]]