Recientemente me han preguntado acerca de cómo se puede definir el color de fondo para un WebDialog
en Web 2.0 con Xojo. Como en cualquier otra cosa, puedes optar por varios caminos; desde el más simple, consistente en añadir un rectángulo al WebDialog y definir su color, hasta el consistente en modificar la propiedad de estilo del objeto en el modelo DOM de la página. Esta es la técnica que usaremos aquí.
El primer paso consiste en añadir un nuevo Módulo
a nuestro proyecto Web. Lo llamaremos WebTools
pero puedes utilizar cualquier otro nombre que prefieras. A continuación, añadiremos el siguiente método con un ámbito Global
(de modo que estará disponible para cualquier elemento del proyecto):
- Method Name:
ModalBackgroundColor
Parameters:
Extends v As WebDialog, assigns c As String
Scope:
Global
Y escribiendo el siguiente fragmento de código en el Editor de Código asociado:
v.ExecuteJavascript("document.getElementById('" + v.ControlID + "_body').style.backgroundColor='"+c+"';")
Una vez realizado, sólo tendremos que llamarlo desde el Manejador de Evento Opening
en la instancia WebDialog para ajustar su color de fondo:
Me.ModalBackgroundColor = "#f00" // Ajusta el color de fondo a Rojo.
Pero esta aproximación nos llevan a algunos efectos colaterales interesantes. Por ejemplo, la cabecera del control WebListBox
o el icono de lupa en el control WebSearchField
aparecerán como transparentes… mostrando el color de fondo asignado al diálogo web.
Aún podemos solucionar este tipo de problemas accediendo a la propiedad de estilo adecuadas sobre la clase div
de estos objetos; pero la parte más complicada consiste en acceder al número de instancia de la cabecera del listbox que necesitamos modificar. Para ello la técnica utilizada aquí puede parecer un poco desmesurada… pero funciona.
Dicha técnica consiste en crear subclases de los controles web de los cuales necesitamos mantener referencias. En este caso, vamos a crear subclases para el WebListBox
y el WebSearchField
.
Añade una nueva clase al proyecto y nómbrala, por ejemplo, MyWebListBox
, definiendo a continuación su Super
a WebListBox
. A continuación, añade una propiedad compartida con los siguientes valores:
- Shared Property Name:
globalInstance()
Data Type:
MyWebListBox
Scope:
Private
Y una segunda propiedad normal con estos valores:
- Property Name:
instanceNumber
Data Type:
Integer
Scope:
Public
Añade a continuación el método Constructor
a la nueva clase. El IDE se encargará de incluir el código necesario para llamar al Constructor en la clase a partir de la cual se ha creado. A continuación sólo necesitamos añadir un par de líneas de código para ajustar el valor de la propiedad instanceNumber
al último índice del array globalInstance
. El código final sería como sigue:
Super.Constructor globalInstance.add me instanceNumber = globalInstance.LastIndex
Añade ahora el manejador de evento Closed
incluyendo el siguiente fragmento en el Editor de Código asociado:
globalInstance.Remove(Me.instanceNumber) For n As Integer = Me.instanceNumber To globalInstance.LastIndex globalInstance(n).instanceNumber = globalInstance(n).instanceNumber-1 Next
Y dado que nuestra subclase consume dicho manejador de evento, es necesario que definamos uno nuevo con el mismo nombre para que pueda ser implementado por cualquier instancia creada a partir de nuestra subclase.
Repite los mismos pasos para añadir una nueva clase MyWebSearchField
con su Super definida a WebSearchField
.
Una vez creadas ambas clases, añádelas a una instancia de WebDialog (por ejemplo WebDialog1
). Luego, sólo necesitamos incluir la siguiente línea de código en el manejador de evento Shown
para cada una de estas instancias:
En el caso de la instancia ListBox1
:
Me.ExecuteJavascript("document.getElementsByClassName(""dataTables_scrollHeadInner"")["+me.instanceNumber.tostring+"].style.backgroundColor='#f00';") // This will set the listbox header background color to Red
Y en el caso de la instancia SearchField1
:
Me.ExecuteJavascript("document.getElementsByClassName(""input-group-append"")["+me.instanceNumber.toString+"].style.backgroundColor='#fff';") // This will set the "loupe" icon background color to White
Dado que estos controles necesitan mantener un seguimiento de sí mismos, añade el manejador de eventos Dismissed
a WebDialog1
, y escribe el siguiente código en el Editor de Código asociado:
ListBox1.Close SearchField1.Close
Si ejecutas el proyecto de ejemplo verás como la primera instancia del ListBox (en la página WebPage1
) mantiene el color blanco de su cabecera, dado que el color de fondo de la página es blanco; mientras que el segundo ListBox mostrado en el WebDialog (WebDialog1
) muestra el color de fondo de la cabecera con el color rojo. En el caso del control SearchField también puedes ver cómo el icono de Lupa mantiene el color de fondo blanco.
Truco Adicional
Además, una vez que sabemos cómo acceder al ID adecuado para ajustar el fondo de un WebDialog, también es sencillo definir una imagen como fondo en el diálogo. Por ejemplo, con esta línea de código en el evento Shown
de la instancia WebDialog1
mostraremos el logo de Xojo como imagen de fondo del diálogo:
Me.ModalBackgroundImage = "https://www.xojo.com/assets/img/logo.png"
Siendo en este caso ModalBackgroundImage
otro método añadido al módulo WebTools
en el que se utiliza la siguiente signatura:
- Method Name:
ModalBackgroundImage
Parameters:
Extends v as WebDialog, Assigns url As String
Y con este código en el Editor de Código asociado:
Var s As String = "document.getElementById('" + _ v.ControlID + "_body').style.backgroundImage=""url('"+url+"')"";" v.ExecuteJavascript(s)
Por supuesto, puedes investigar más para definir otros atributos del fondo, como por ejemplo que no se repita la imagen asignada como fondo, ajustar su tamaño, etc.