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;
}