B4J Question [BANAno]: How can I add dynamic css / InjectCSS to my app?

Discussion in 'B4J Questions' started by Mashiane, Jan 8, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Hi there.

    I'm thinking of enabling users apply dynamic theming depending on the color and intensity then specify for their app. What this intends to do is basically take the 'backcolor' and apply it to all the controls so that one has the same color specs throughout.

    The default colors for Materialize CSS 1.00 is teal and some variant of red. Going through their css, I have managed to pick up that setting a few backcolors this is able to be done. So I basically need something like InjectCSS on the _Ready function call.

    Here is some kind of hypothetical example...

    Code:
    'apply this theme based on app theme for all components
    'set the mater theme
    Sub ApplyTheme()
        
    If Theme.Length = 0 Then Return
        
    If Themes.ThemeExist(Theme) = False And Theme.Length > 0 Then
            LogError(
    $"App: ${Theme} theme '${Theme}' DOES NOT exist!"$)
        
    End If
        
    Dim fColor As String = Themes.GetForeColorHex(Theme)
        
    Dim bColor As String = Themes.GetBackGroundColorHex(Theme)
        
    If bColor.length > 0 Then
            
    'forecolor
            page.AddCssRule($".pagination li.active"$$"background-color: ${bColor};"$)
            
    page.AddCssRule($".pagination li.active a"$$"color: ${bColor};"$)
            
    page.AddCssRule($"blockquote"$,$"border-left: 5px solid ${bColor}"$)
            
    page.AddCssRule($".btn:focus, .btn-large:focus, .btn-small:focus,.btn-floating:focus"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".btn, .btn-large, .btn-small"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".btn:hover, .btn-large:hover, .btn-small:hover"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".btn-floating, .btn-floating:hover, .fixed-action-btn .fab-backdrop"$,$"background-color: ${bColor}"$)
            
            
    page.AddCssRule($".dropdown-content li>a, .dropdown-content li>span"$,$"color: ${bColor}"$)
            
    page.AddCssRule($"select:focus"$,$"outline: 1px solid ${bColor}"$)
            
    page.AddCssRule($"button:focus"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".input-field .prefix.active"$,$"color: ${bColor}"$)
            
    page.AddCssRule($"[type="radio"]:checked+span:after"$,$"border: 2px solid ${bColor}"$)
            
    page.AddCssRule($"[type="radio"].with-gap:checked+span:before"$,$"border: 2px solid ${bColor}"$)
            
    page.AddCssRule($"[type="radio"].with-gap:checked+span:after"$,$"border: 2px solid ${bColor}"$)
            
    page.AddCssRule($"[type="radio"]:checked+span:after"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($"[type="radio"].with-gap:checked+span:after"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($"[type="checkbox"]:checked+span:not(.lever):before"$,$"border-right: 2px solid ${bColor};border-bottom: 2px solid ${bColor}"$)
            
    page.AddCssRule($"[type="checkbox"]:indeterminate+span:not(.lever):before"$,$"border-right: 2px solid ${bColor};"$)
            
    page.AddCssRule($"[type="checkbox"].filled-in:checked+span:not(.lever):after"$,$"border: 2px solid ${bColor};background-color: ${bColor};"$)
            
    page.AddCssRule($"[type="checkbox"].filled-in.tabbed:checked:focus+span:not(.lever):after"$,$"background-color: ${bColor};border-color: ${bColor};"$)
            
    page.AddCssRule($".switch label input[type=checkbox]:checked+.lever:after"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".switch label input[type=checkbox]:checked+.lever"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".select-wrapper input.select-dropdown:focus"$,$"border-bottom: 1px solid ${bColor}"$)
            
    page.AddCssRule($"input[type=range]+.thumb"$,$"background-color: ${bColor};"$)
            
    page.AddCssRule($"input[type=range]::-webkit-slider-thumb"$,$"background: ${bColor};background-color: ${bColor};"$)
            
    page.AddCssRule($"input[type=range]::-moz-range-thumb"$$"background: ${bColor};"$)
            
    page.AddCssRule($"input[type=range]::-ms-thumb"$,$"background: ${bColor};"$)
            
    page.AddCssRule($".sidenav li>a.btn-floating:hover"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule(".sidenav li>a.btn:hover, .sidenav li>a.btn-large:hover,.sidenav li>a.btn-small:hover,.sidenav li>a.btn-large:hover",$"background-color: ${bColor}"$)
            
    page.AddCssRule($".secondary-content"$,$"color: ${bColor}"$)
            
    page.AddCssRule(".collection .collection-item.active",$"background-color: ${bColor};"$)
            
    page.AddCssRule(".collection a.collection-item",$"color: ${bColor}"$)
            
    page.AddCssRule(".progress .determinate",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".progress .indeterminate",$"background-color: ${bColor}"$)
            
    page.AddCssRule("span.badge.new",$"background-color: ${bColor}"$)
            
            
    page.AddCssRule(".chip",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".input-field .prefix.active",$"color: ${bColor}"$)
            
    page.AddCssRule(".datepicker-date-display",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".datepicker-table td.is-today",$"color: ${bColor}"$)
            
    page.AddCssRule(".datepicker-table td.is-selected",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".datepicker-day-button:focus",$"background-color: ${bColor}"$)
            
    page.AddCssRule($".datepicker-cancel, .datepicker-clear, .datepicker-today,    .datepicker-done"$,$"color: ${bColor}"$)
            
    page.AddCssRule(".timepicker-digital-display",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".timepicker-tick.active, .timepicker-tick:hover",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".timepicker-canvas line",$"stroke: ${bColor}"$)
            
    page.AddCssRule(".timepicker-canvas-bearing",$"fill: ${bColor}"$)
            
    page.AddCssRule(".timepicker-canvas-bg",$"fill: ${bColor}"$)
            
    page.AddCssRule(".timepicker-close",$"color: ${bColor}"$)
            
    page.AddCssRule(".card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating)",$"color: ${bColor}"$)
            
    page.AddCssRule(".card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating):hover",$"color: ${bColor}"$)
            
            
    page.AddCssRule(".chip:focus",$"background-color: ${bColor}"$)
            
    page.AddCssRule(".chips.focus",$"border-bottom: 1px solid ${bColor}; -webkit-box-shadow: 0 1px 0 0 ${bColor}; box-shadow: 0 1px 0 0 ${bColor}"$)
            
    page.AddCssRule($".noUi-horizontal .noUi-handle, .noUi-vertical .noUi-handle"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".noUi-connect"$,$"background: ${bColor}"$)
            
    page.AddCssRule($".noUi-target.noUi-horizontal .noUi-tooltip"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".noUi-target.noUi-vertical .noUi-tooltip"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".slider .indicators .indicator-item.active"$,$"background-color: ${bColor}"$)
            
    page.AddCssRule($".table-of-contents a.active"$,$"border-left: 2px solid ${bColor}"$)
            
    page.AddCssRule($".table-of-contents a:hover"$,$"border-left: 1px solid ${bColor}"$)
            
    page.AddCssRule($".tabs .tab a"$,$"color: ${bColor}"$)
            
    page.AddCssRule($".tabs .tab a:focus, .tabs .tab a:focus.active"$,$"background-color: transparent"$)
            
    page.AddCssRule($".tabs .tab a:hover, .tabs .tab a.active"$,$"color: ${bColor};"$)
            
    page.AddCssRule($".tabs .tab.disabled a, .tabs .tab.disabled a:hover"$,$"color: ${bColor};"$)
            
    page.AddCssRule($".tabs .indicator"$,$"background-color: ${bColor};"$)
            
    page.AddCssRule($".material-tooltip"$,$"background-color: ${bColor};"$)
            
    page.AddCssRule($"input:not([type]):focus:not([readonly]),
    input[type=text]:not(.browser-default):focus:not([readonly]),
    input[type=password]:not(.browser-default):focus:not([readonly]),
    input[type=email]:not(.browser-default):focus:not([readonly]),
    input[type=url]:not(.browser-default):focus:not([readonly]),
    input[type=time]:not(.browser-default):focus:not([readonly]),
    input[type=date]:not(.browser-default):focus:not([readonly]),
    input[type=datetime]:not(.browser-default):focus:not([readonly]),
    input[type=datetime-local]:not(.browser-default):focus:not([readonly]),
    input[type=tel]:not(.browser-default):focus:not([readonly]),
    input[type=number]:not(.browser-default):focus:not([readonly]),
    input[type=search]:not(.browser-default):focus:not([readonly]),
    textarea.materialize-textarea:focus:not([readonly])"$
    ,$"border-bottom: 1px solid ${bColor}; -webkit-box-shadow: 0 1px 0 0 ${bColor}; box-shadow: 0 1px 0 0 ${bColor}"$)
        
    End If
        
    page.AddCssRule($"input:not([type]):focus:not([readonly])+label,
    input[type=text]:not(.browser-default):focus:not([readonly])+label,
    input[type=password]:not(.browser-default):focus:not([readonly])+label,
    input[type=email]:not(.browser-default):focus:not([readonly])+label,
    input[type=url]:not(.browser-default):focus:not([readonly])+label,
    input[type=time]:not(.browser-default):focus:not([readonly])+label,
    input[type=date]:not(.browser-default):focus:not([readonly])+label,
    input[type=datetime]:not(.browser-default):focus:not([readonly])+label,
    input[type=datetime-local]:not(.browser-default):focus:not([readonly])+label,
    input[type=tel]:not(.browser-default):focus:not([readonly])+label,
    input[type=number]:not(.browser-default):focus:not([readonly])+label,
    input[type=search]:not(.browser-default):focus:not([readonly])+label,
    textarea.materialize-textarea:focus:not([readonly])+label"$
    ,$"color: ${bColor}"$)

        
    page.AddCssRule($".input-field>label"$,$"color: ${bColor};"$)
    End Sub
    Thanks.
     
    joulongleu likes this.
  2. alwaysbusy

    alwaysbusy Expert Licensed User

    I know from experience from ABM, you will end-up with a couple of thousands of those AddCSSRule lines. Materialize CSS is VERY badly prepared for theming.
     
  3. Mashiane

    Mashiane Expert Licensed User

    Yeah hey. I wish I wouldn't have to do this. Fortunately if I apply the code above only once it changes everything so if I want everything to have a lightblue color, all textboxes, radio, buttons will have lightblue and not the teal and red they have. This will definitely not have extensive theming like ABM at component level at all, thus this global approach. Thanks for the heads up!
     
  4. alwaysbusy

    alwaysbusy Expert Licensed User

    Good luck with that! I know a certain member on this forum who was the first to ask for ABM how he could change a border, forecolor, have multiple input colors, etc :rolleyes:

    Just saying, maybe this is a good time to reflect on maybe a better system than I had to do in ABM. At first, I also thought everyone would've been happy with just a couple of colors, hence I wrote the .Colorize() method on the themes where one could do exactly what you want to do now, remember? But hell no, the users insisted in being able to do more. ;) Even up to today, so many years later, I still am working my ass off because of requests in the ABM feedback app for certain styling properties. And the thing with CSS is, the inheritance is a nightmare so it becomes increasingly difficult to keep track...
     
    Mashiane likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice