My app is pretty much all custom ComplexPanel and Widget
implementations to create my own widgets.

I've found that it's much easier and more productive to just create a
custom widget or container for just every part of the UI than try and
make the built in widgets do what I want (in some cases though I
extend the built in widgets and add my own stuff).

Here is the container widget that draws the forms:

class Form(ComplexPanel, Model):
    def __init__(self):
        self.setElement(DOM.createDiv())
        ComplexPanel.__init__(self, StyleName="form")
        Model.__init__(self)

    def section(self, name=None):
        fieldset = DOM.createDiv()
        DOM.setAttribute(fieldset, "className", "fieldset")
        if name:
            legend = DOM.createDiv()
            DOM.setAttribute(legend, "className", "legend")
            DOM.setInnerText(legend, name)
            DOM.appendChild(fieldset, legend)
        DOM.appendChild(self.getElement(), fieldset)
        self.fieldset = fieldset
        self.br()

    def field(self, name, desc, widget):
        f = Field(desc, widget)
        self.row.add(f)
        self.addField(name, f)

    def button(self, url, cb):
        b = Image(url)
        b.setStyleName("button")
        b.addClickListener(cb)
        self.row.add(b)
        self.children.append(b)

        p = DOM.getParent(b.getElement())
        DOM.setAttribute(p, "className", "button-container")

    def br(self):
        self.row = HorizontalPanel()
        DOM.appendChild(self.fieldset, self.row.getElement())




And here is an example of how I use it (you can see the result of the
form below in the screenshot):



class AddressForm(Form):
    def __init__(s, title, prefix, timeLabel, customerForm):
        Form.__init__(s)
        section, field, button, br = s.section, s.field, s.button, s.br

        s.prefix = prefix
        s.customerForm = customerForm

        section(title)
        field(prefix+"name", "Name", TextBox())
        button('images/home.png', s.insertHomeAddress)
        button('images/directory_lookup.png', s.lookupAddress)
        br()
        field(prefix+"address1", "House Number, Street", TextBox())
        br()
        field(prefix+"address2", "Apartment, Suite, etc.", TextBox())
        br()
        field(prefix+"city", "City", TextBox(Text="Chicago"))
        field(prefix+"state", "", StateList())
        field(prefix+"zipcode", "Zip Code", TextBox())
        br()
        field(prefix+"time", timeLabel, TextBox())



90% of the look that you see in the screenshot is just plain old CSS
using the classes assigned with DOM.setAttribute(element, "className",
"CLASS_NAME_HERE").

See the attached CSS file for how it all comes together.

 - lex

On Mon, Jan 23, 2012 at 9:11 AM, Vsevolod Fedorov
<[email protected]> wrote:
> Lex,
>
> Ok, ok, I agree with you :)
> I will check for placeholder availability in my own code.
>
>  > I've attached a screenshot of an app that has solutions for both of
>  > the things mentioned above: instructions underneath search box
>
> This is beautiful! How did you do this? Do you have a pointer to howto etc.?
>
> Seva
.form {
}

.fieldset {
    border: none;
    background: #CBCBCB;
    margin-bottom: 10px;
    border-radius: 10px;
}

td > .form > .fieldset {
    margin-bottom: 0px;
}

.fieldset .legend {
    color: white;
    padding: 2px 6px 2px 6px;
}

.fieldset table {
    width: 100%;
    border-spacing: 0px;
}

.fieldset tr {
    width: 100%;
}

.fieldset table:first-of-type td:first-child,
.fieldset table:first-of-type td:first-child input,
.fieldset table:first-of-type td:first-child select,
.fieldset table:first-of-type td:first-child .button
{
    border-top-left-radius: 10px;
}

.fieldset table:first-of-type td:last-child,
.fieldset table:first-of-type td:last-child input,
.fieldset table:first-of-type td:last-child select,
.fieldset table:first-of-type td:last-child .button
{
    border-top-right-radius: 10px;
}

.fieldset table:last-of-type td:first-child,
.fieldset table:last-of-type td:first-child input,
.fieldset table:last-of-type td:first-child select,
.fieldset table:last-of-type td:first-child .button
{
    border-bottom-left-radius: 10px;
}

.fieldset table:last-of-type td:last-child,
.fieldset table:last-of-type td:last-child input,
.fieldset table:last-of-type td:last-child select,
.fieldset table:last-of-type td:last-child .button
{
    border-bottom-right-radius: 10px;
}

.fieldset td {
    padding: 0px;
    border-style: solid;
    border-color: black;
    border-width: 1px 1px 0px 0px;
    background: white;
}

.fieldset table td:first-of-type {
    border-left-width: 1px;
}

.fieldset table:last-of-type td {
    border-bottom-width: 1px;
}

.field {
    position: relative;
}

.field label {
    position: absolute;
    z-index: 1;
    font-size: 0.6em;
    color: #999;
    top: 1px;
    right: 20px;
}

.field input, .field textarea, .field select {
    z-index: 2;
    width: 100%;
    height: 36px;
    min-width: 50px;

    border: none;
    box-shadow: inset 0 0 6px #333;
    padding: 6px;
    background: transparent;
}
.field select {
    padding: 0px;
}

.button {
    background: #CBCBCB;
    opacity: 0.7;
}

.button:hover {
    background: #F0FFF0;
    opacity: 1.0;
    cursor: pointer;
}

.button-container {
    width: 36px;
}

Reply via email to