Truco: Color de fondo en WebDialogs

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.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *