开发者

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.


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...


Contrary to what slartidan answered it is possible to defer UIBinder styles to runtime substitution. The only caveat to this is that you must have the color preference loaded before you try to inject the stylesheet, which I believe is done on the create and bind ui method and you must make these preferences available via a static method.

<ui:style>
    @eval color1 com.module.UserPreferences.getColor1();
    .header {
      background: color1;
      padding: 6px 6px;
    }
    @eval color2 com.module.UserPreferences.getColor2();
    .anothercssclass {
      background: color2;
      padding: 6px 6px;
    }
</ui:style>


  1. Switching between styles is easy. See programmatically select inline styles. Just declare your color schemes under different CSS classes and then assign them to your elements. This can be cumbersome if you have a lot of elements.

  2. Manipulating an existing CSS style is AFAIK not directly supported in GWT. You will need to resort to JSNI. See this thread: change css rules dynamically

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜