Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set CSS style colors in GWT

I have a GWT + AppEngine application that lets users create online polls. I want to let the poll creator choose from a variety of themes for his poll. We will save the theme a poll creator chose on the server and whenever a poll respondent access the poll he will get the questions with the chosen theme.

A theme for us means a set of 4-5 colors which we will use to style the poll page. Our client side application is a GWT application with styles set inline in UiBinder templates elements, for example:

<ui:style>
.header {
background: color1;
padding: 6px 6px;
}
.anothercssclass {
background: color2;
padding: 6px 6px;
}
</ui:style>

Please suggest how we can set the color1 and color2 from the theme saved on server. Please note this is NOT a GWT module theme question.

like image 275
AmaltasCoder Avatar asked Dec 30 '10 13:12

AmaltasCoder


1 Answers

As far as I know it is not possible to change the uibinder template during runtime (since it is compiled into javascript at compiletime and not accessible anymore at runtime).

You will probably have to manually change the colors in your gwt code (= in java files, not in .xml files).

Straight forward:

  1. create database-structure for storing your color information
  2. create server code to get colors from database
  3. implement gwt-service (and async interface and servlet implementation class) to deliver color information to the client
  4. implement gwt client code, which asks for the color information and then sets the colors for your gwt-components. You can do it like this (use camel case as descriped at http://www.francoismaillet.com/blog/?p=68 ):

    widget.getElement().getStyle().setProperty("background", colorValueFromDatabase);

Of course this solution is pretty unhandy when a lot of widgets have to be changed.

Alternative 1:

Implement a plain old Java Servlet (without gwt), which can provide a css file (a standard servlet, that loads color data from database and returns that colors as css definitions to the browser). Use a link to that Servlet in your gwt-html starting page.

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CssServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // you somehow have to get your user's information out of the session
        User user = (User) request.getSession().getAttribute("loggedInUser");
        PrintWriter writer = response.getWriter();

        // use saved color values and generate css
        writer.append(".header {");
        writer.append(" background: " + getHeaderColorForUser(user) + ";");
        writer.append(" padding: 6px 6px;");
        writer.append(" }");
        writer.append(" .anothercssclass {");
        writer.append(" background: " + getAnotherCssClassColorForUser(user) + ";");
        writer.append(" padding: 6px 6px;");
        writer.append(" }");

        // finish request
        writer.close();
        response.setStatus(HttpServletResponse.SC_OK);
    }

    private String getAnotherCssClassColorForUser(User user) {
        // TODO Auto-generated method stub
        return null;
    }

    private String getHeaderColorForUser(User user) {
        // TODO Auto-generated method stub
        return null;
    }

}

Problem with this alternative is, that you cannot instantly refresh the color information. The user has to reload the page to see changes in his color styles.

Alternative 2:

Use javascript (native code) to dynamically change your css configurations.

// in java code:
changeCssStyle("header", "background", colorFromDatabase);

and

private native void changeCssStyle(String cssClass, String cssName, String cssValue)
/*-{
    var children = document.getElementsByTagName('*') || document.all;
    var elements = new Array();

    // iterate over ALL elements
    for (i in children) {
        var child = children[i];
        var classNames = child.className.split(' ');
        for (c in classNames) {

            // does this element use our css class?
            if (classNames[c] == '.' + cssClass) {

                // now modify this element: set the attribute with name "cssName" to the value "cssValue"
                child.style.setAttribute(cssName, cssValue);
            }
        }
    }
 }-*/
;

Conclusion

Three workarounds for your problem, non of them is really a solution - but hopefully it helps you implementing your code. Good luck!

PS: my code is untested...

like image 84
slartidan Avatar answered Nov 03 '22 16:11

slartidan