Re: [Webware-discuss] How to get rid of labels for buttons in FormKit

CLIFFORD ILKAY wrote:
>> That's very strange. We've never seen that sort of thing, and we use
>> non-validated fields all of the time.
>
> I'll send the code to you privately.
Roger.
> I specified:
>
> newForm.addField(Fields.TextField('mname',[Validators.MaxLength(25)],label="Middle
> Name"))
>
> It made no difference in the width of the field that was rendered. I
> specified MaxLength(6) for Salutation and both fields were the same
> width, and no different than when I had not specified any MaxLength.
MaxLength is a validator; it has no affect on the painting of the form
field (tag). There is also an attribute of <input> tags in html that is
called "maxlength". It's just a bit of confusion.
For example:
>>> from FormKit import Fields
>>> t = Fields.TextField('foo')
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" />'
>>> t = Fields.TextField('foo',attributes={'maxlength':6})
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" maxlength="6" />'
>
>> The "right way" to do it is to use CSS though.
>
>
> I do not know of a way to specify the width of a given text entry
> field in a form with CSS. When you think about it, it makes sense as
> CSS operates on classes of things, not individual instances of things.
CSS operates on classes, yes, also on id's, also on individual elements.
It's very flexible. The best way is certainly to add classes (in fact,
we have hacked our own FK to always include stock classes on input
items, since we almost always style them).
Here are some (other) ways:
>>> t = Fields.TextField('foo')
>>> t.addStyle({'width':'200px;'})
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value=""
style="width:200px;" />'
or, without using addStyle, you can have a stylesheet like this:
<style>
#field_foo { width: 200px; border: 2px solid blue; }
</style>
or even:
>>> t = Fields.TextField('foo')
>>> t.addClass( 'myClass' )
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" class="myClass" />'
and then
<style>
.myClass { width: 200px; background-color:yellow;}
</style>
It's useful to open up fields in an interactive session (like PyCrust)
and poke in it; there are all kinds of useful methods, like setting the
access key and tab order in forms.
This is also the way to add javascript or whatever.

Thread view

Hi,
Does anyone know how to get rid of the label that is automatically added to
buttons in FormKit? It is weird to see a button called "Submit" with a
label next to it called "Submit".
Regards,
Clifford Ilkay
Dinamis Corporation
3266 Yonge Street, Suite 1419
Toronto, Ontario
Canada M4N 3P6
Tel: 416-410-3326

Hi Clifford.
FormKit is 3rd party software, not included with Webkit, but I'm one of
the two authors, so I'll answer.
The form.dump() method is very very simple, and not really meant for
permanent use. It's just to make sure that your form works. Of course,
it /can/ be used, but it's ugly, as you noticed. We use it to make sure
everything is okay, then replace the form output bits in our servlets
with more hand-crafted code.
Every field in a form has a set of accessor methods that you can pick at
to lay out your form in a template or manually or however you wish:
myfield.tag()
myfield.label()
myfield.error()
myfield.value()
and some others...
Basically, you just want to set up your code in self.writeln() or
whatever, and just grab onto the tag() text, and drop it into your page
output wherever you wish.
CLIFFORD ILKAY wrote:
>
> Does anyone know how to get rid of the label that is automatically
> added to buttons in FormKit? It is weird to see a button called
> "Submit" with a label next to it called "Submit".
>

At 05:49 PM 21/06/2004 -0400, Matt Feifarek wrote:
>CLIFFORD ILKAY wrote:
>
>>It would be nice to have a way of not having to write the fiddly HTML
>>bits, whether using tables or DIV tags, and do something like:
>>
>>self.writeln(self.form.userID.label())
>>self.writeln(self.form.userID.tag())
>>
>>self.form.userID.label() and .tag() would expand out to either the
>>appropriate table row/cell tag or DIV tag. I guess this is what something
>>like Cheetah template is allegedly able to do, though I have not figured
>>out how to do that yet.
>
>We do have a divDump() method in there. That with CSS and you can pretty
>much have what you're asking for. To make FormKit itself output the
>"chrome" of html surrounding label, tag, error, etc... well, we've
>provided two ways. Anything else is up to you ;-)
I did not see the divDump() method anywhere in the Class Reference PDF.
Perhaps I missed it.
>One thing that we like to do is the dictionary substitution, also. Then
>you can just assign-up your bits like this:
>
>subDict = {
> 'pass' : self.form.userID.tag(),
> 'name' : self.form.userName.tag(),
>}
>
>Or whatever.
>
>Then, use the '''%(pass)s''' % subDict form. Is pretty decent poor-man's
>templating.
I think I have to play with this to understand. Here is what I have done.
... in the __init__ method
newForm.addField(Fields.TextField('fname',[notEmpty],label="First
Name"))
newForm.addField(Fields.TextField('mname',label="Middle
Name"))
newForm.addField(Fields.TextField('lname',[notEmpty],label="Last
Name"))
... in the writeContent() method
if self.form.fname.error():
self.writeln('''\t<tr><td
class="errorLabel">Please enter a first name</td>''')
self.writeln('''\t<td
class="errorField">%s</td></tr>''' % self.form.fname.tag())
else:
self.writeln('''\t<tr><td>%s</td>''' %
self.form.fname.label())
self.writeln('''\t<td>%s</td></tr>''' %
self.form.fname.tag())
self.writeln('''\t<tr><td>%s</td>''' %
self.form.mname.label())
self.writeln('''\t<td>%s</td></tr>''' %
self.form.mname.tag())
if self.form.lname.error():
self.writeln('''\t<tr><td
class="errorLabel">Please enter a last name</td>''')
self.writeln('''\t<td
class="errorField">%s</td></tr>''' % self.form.lname.tag())
else:
self.writeln('''\t<tr><td>%s</td>''' %
self.form.lname.label())
self.writeln('''\t<td>%s</td></tr>''' %
self.form.lname.tag())
This seems to work though I have a couple of questions about it.
1. When I click on the Submit button, if I do not enter a Middle Name, the
form will not POST successfully. That is strange considering that Middle
Name is not mandatory. If I enter anything in Middle Name, the form will
POST. The only difference I can see between Middle Name and the other
fields is that it is not mandatory and as such, I do not test for an error
condition. How can I get the form to POST with a blank Middle Name field?
2. I am using SQLObject to map the PostgreSQL tables to Python objects. I
have that part prototyped and working. Once I get past the hurdle above, I
have to transfer the contents of the form fields above to the Person object
attributes. According to the Class Reference, I think I should be using
self.form.value(fieldName) to do this. e.g.
if self.form.isSuccessful():
newPerson = Person(
firstName = self.form.value(fname),
middleName = self.form.value(mname),
lastName = self.form.value(lname),
)
... where Person is a SQLObject class corresponding to a PostgreSQL table.
Am I on the right track?
Regards,
Clifford Ilkay
Dinamis Corporation
3266 Yonge Street, Suite 1419
Toronto, Ontario
Canada M4N 3P6
Tel: 416-410-3326

CLIFFORD ILKAY wrote:
> ... in the writeContent() method
>
> if self.form.fname.error():
> self.writeln('''\t<tr><td
> class="errorLabel">Please enter a first name</td>''')
> self.writeln('''\t<td
> class="errorField">%s</td></tr>''' % self.form.fname.tag())
> else:
> self.writeln('''\t<tr><td>%s</td>''' %
> self.form.fname.label())
> self.writeln('''\t<td>%s</td></tr>'''
> % self.form.fname.tag())
>
> self.writeln('''\t<tr><td>%s</td>''' %
> self.form.mname.label())
> self.writeln('''\t<td>%s</td></tr>''' %
> self.form.mname.tag())
>
> if self.form.lname.error():
> self.writeln('''\t<tr><td
> class="errorLabel">Please enter a last name</td>''')
> self.writeln('''\t<td
> class="errorField">%s</td></tr>''' % self.form.lname.tag())
> else:
> self.writeln('''\t<tr><td>%s</td>''' %
> self.form.lname.label())
> self.writeln('''\t<td>%s</td></tr>'''
> % self.form.lname.tag())
>
Some comments:
In FK there is already stuff for error formatting. For example, if
there's an error, the input tag will contain class="error" so you can
mark that as "red" or something (look in the examples). Also, it's
easier on your typing if you make a short-name reference to the form
object in your local name space, like "f = self.form". Then you can just
do f.lname.tag().
But there's nothing "wrong" with what you're doing; there's just already
some plumbing for some of it.
> This seems to work though I have a couple of questions about it.
>
> 1. When I click on the Submit button, if I do not enter a Middle Name,
> the form will not POST successfully. That is strange considering that
> Middle Name is not mandatory. If I enter anything in Middle Name, the
> form will POST. The only difference I can see between Middle Name and
> the other fields is that it is not mandatory and as such, I do not
> test for an error condition. How can I get the form to POST with a
> blank Middle Name field?
Hmm. That shouldn't happen. It's possible that it's getting confused by
the lack of a Validator set declaration in the constructor of your
field. IE,
newForm.addField(Fields.TextField('mname',label="Middle Name"))
may have to be:
newForm.addField(Fields.TextField('mname', [ ], label="Middle Name"))
If that's the case, that's a bad bug on our parts. Send me your actual
code and I'll take a look.
> 2. I am using SQLObject to map the PostgreSQL tables to Python
> objects. I have that part prototyped and working. Once I get past the
> hurdle above, I have to transfer the contents of the form fields above
> to the Person object attributes. According to the Class Reference, I
> think I should be using self.form.value(fieldName) to do this. e.g.
>
> if self.form.isSuccessful():
> newPerson = Person(
> firstName = self.form.value(fname),
> middleName = self.form.value(mname),
> lastName = self.form.value(lname),
> )
>
> ... where Person is a SQLObject class corresponding to a PostgreSQL
> table. Am I on the right track?
That will certainly work. Alternatively, you can poke at each field:
newPerson = Person(
firstName = self.form.fname.value(),
middleName = self.form.mname.value(),
[etc]
)
Or, better yet, just get the whole values bundle as a dictionary:
values = self.form.values()
newPerson = Person( firstName=values['fname'],
middleName=values['mname'] ) etc...

Hi Matt,
At 02:14 PM 22/06/2004 -0400, Matt Feifarek wrote:
>CLIFFORD ILKAY wrote:
>
>>... in the writeContent() method
>>
>> if self.form.fname.error():
>> self.writeln('''\t<tr><td
>> class="errorLabel">Please enter a first name</td>''')
>> self.writeln('''\t<td
>> class="errorField">%s</td></tr>''' % self.form.fname.tag())
>> else:
>> self.writeln('''\t<tr><td>%s</td>''' %
>> self.form.fname.label())
>> self.writeln('''\t<td>%s</td></tr>''' %
>> self.form.fname.tag())
>>
>> self.writeln('''\t<tr><td>%s</td>''' %
>> self.form.mname.label())
>> self.writeln('''\t<td>%s</td></tr>''' %
>> self.form.mname.tag())
>>
>> if self.form.lname.error():
>> self.writeln('''\t<tr><td
>> class="errorLabel">Please enter a last name</td>''')
>> self.writeln('''\t<td
>> class="errorField">%s</td></tr>''' % self.form.lname.tag())
>> else:
>> self.writeln('''\t<tr><td>%s</td>''' %
>> self.form.lname.label())
>> self.writeln('''\t<td>%s</td></tr>''' %
>> self.form.lname.tag())
>Some comments:
>
>In FK there is already stuff for error formatting. For example, if there's
>an error, the input tag will contain class="error" so you can mark that as
>"red" or something (look in the examples).
I saw that but I wanted to customize the layout of the incomplete form,
i.e. I wanted the error string beside the fields, not above them, and I
wanted more specific error messages. Having said that, it can get out of
hand very quickly if you have a couple of error conditions you are testing
for. You have to have a bunch of tests just to output the correct error
string. I cannot think of a better way of doing it though in order to
provide useful feedback to the user.
>Also, it's easier on your typing if you make a short-name reference to the
>form object in your local name space, like "f = self.form". Then you can
>just do f.lname.tag().
Select, middle button click is quite fast too:) As you saw below, I used an
alias for self.form in newForm. I prefer names that convey meaning even to
those who may not be familiar with Python, or even programming for that matter.
>But there's nothing "wrong" with what you're doing; there's just already
>some plumbing for some of it.
>
>>This seems to work though I have a couple of questions about it.
>>
>>1. When I click on the Submit button, if I do not enter a Middle Name,
>>the form will not POST successfully. That is strange considering that
>>Middle Name is not mandatory. If I enter anything in Middle Name, the
>>form will POST. The only difference I can see between Middle Name and the
>>other fields is that it is not mandatory and as such, I do not test for
>>an error condition. How can I get the form to POST with a blank Middle
>>Name field?
>
>Hmm. That shouldn't happen. It's possible that it's getting confused by
>the lack of a Validator set declaration in the constructor of your field. IE,
>
> newForm.addField(Fields.TextField('mname',label="Middle Name"))
>
>may have to be:
>
> newForm.addField(Fields.TextField('mname', [ ], label="Middle Name"))
>
>If that's the case, that's a bad bug on our parts. Send me your actual
>code and I'll take a look.
Setting an empty parameter for the error test made no difference. As soon
as I put in some error test though, e.g. Validators.MaxLength(25) for
middle name, the form posted properly. Speaking of MaxLength(), how does
one specify the width of a text field in FormKit? I saw no obvious way to
do it.
>>2. I am using SQLObject to map the PostgreSQL tables to Python objects. I
>>have that part prototyped and working. Once I get past the hurdle above,
>>I have to transfer the contents of the form fields above to the Person
>>object attributes. According to the Class Reference, I think I should be
>>using self.form.value(fieldName) to do this. e.g.
>>
>>if self.form.isSuccessful():
>> newPerson = Person(
>> firstName = self.form.value(fname),
>> middleName = self.form.value(mname),
>> lastName = self.form.value(lname),
>> )
>>
>>... where Person is a SQLObject class corresponding to a PostgreSQL
>>table. Am I on the right track?
>
>That will certainly work. Alternatively, you can poke at each field:
>
> newPerson = Person(
> firstName = self.form.fname.value(),
> middleName = self.form.mname.value(),
> [etc]
> )
>
>Or, better yet, just get the whole values bundle as a dictionary:
>
>values = self.form.values()
>
>newPerson = Person( firstName=values['fname'], middleName=values['mname']
>) etc...
The first or second option is probably more readily understood by someone
who may be new to Python.
Regards,
Clifford Ilkay
Dinamis Corporation
3266 Yonge Street, Suite 1419
Toronto, Ontario
Canada M4N 3P6
Tel: 416-410-3326

CLIFFORD ILKAY wrote:
> Setting an empty parameter for the error test made no difference. As
> soon as I put in some error test though, e.g. Validators.MaxLength(25)
> for middle name, the form posted properly. Speaking of MaxLength(),
> how does one specify the width of a text field in FormKit? I saw no
> obvious way to do it.
>
That's very strange. We've never seen that sort of thing, and we use
non-validated fields all of the time.
As far as maxlength, you can send maxLength into the constructor for
TextInputField. If you want to use just TextField, you can set the
attributes yourself (it's not techincally a valid attribute in xhtml, I
think).
The "right way" to do it is to use CSS though.
Regards...

At 03:18 PM 23/06/2004 -0400, Matt Feifarek wrote:
>CLIFFORD ILKAY wrote:
>
>>Setting an empty parameter for the error test made no difference. As soon
>>as I put in some error test though, e.g. Validators.MaxLength(25) for
>>middle name, the form posted properly. Speaking of MaxLength(), how does
>>one specify the width of a text field in FormKit? I saw no obvious way to
>>do it.
>That's very strange. We've never seen that sort of thing, and we use
>non-validated fields all of the time.
I'll send the code to you privately.
>As far as maxlength, you can send maxLength into the constructor for
>TextInputField. If you want to use just TextField, you can set the
>attributes yourself (it's not techincally a valid attribute in xhtml, I think).
I specified:
newForm.addField(Fields.TextField('mname',[Validators.MaxLength(25)],label="Middle
Name"))
It made no difference in the width of the field that was rendered. I
specified MaxLength(6) for Salutation and both fields were the same width,
and no different than when I had not specified any MaxLength.
>The "right way" to do it is to use CSS though.
I do not know of a way to specify the width of a given text entry field in
a form with CSS. When you think about it, it makes sense as CSS operates on
classes of things, not individual instances of things.
Regards,
Clifford Ilkay
Dinamis Corporation
3266 Yonge Street, Suite 1419
Toronto, Ontario
Canada M4N 3P6
Tel: 416-410-3326

CLIFFORD ILKAY wrote:
>> That's very strange. We've never seen that sort of thing, and we use
>> non-validated fields all of the time.
>
> I'll send the code to you privately.
Roger.
> I specified:
>
> newForm.addField(Fields.TextField('mname',[Validators.MaxLength(25)],label="Middle
> Name"))
>
> It made no difference in the width of the field that was rendered. I
> specified MaxLength(6) for Salutation and both fields were the same
> width, and no different than when I had not specified any MaxLength.
MaxLength is a validator; it has no affect on the painting of the form
field (tag). There is also an attribute of <input> tags in html that is
called "maxlength". It's just a bit of confusion.
For example:
>>> from FormKit import Fields
>>> t = Fields.TextField('foo')
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" />'
>>> t = Fields.TextField('foo',attributes={'maxlength':6})
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" maxlength="6" />'
>
>> The "right way" to do it is to use CSS though.
>
>
> I do not know of a way to specify the width of a given text entry
> field in a form with CSS. When you think about it, it makes sense as
> CSS operates on classes of things, not individual instances of things.
CSS operates on classes, yes, also on id's, also on individual elements.
It's very flexible. The best way is certainly to add classes (in fact,
we have hacked our own FK to always include stock classes on input
items, since we almost always style them).
Here are some (other) ways:
>>> t = Fields.TextField('foo')
>>> t.addStyle({'width':'200px;'})
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value=""
style="width:200px;" />'
or, without using addStyle, you can have a stylesheet like this:
<style>
#field_foo { width: 200px; border: 2px solid blue; }
</style>
or even:
>>> t = Fields.TextField('foo')
>>> t.addClass( 'myClass' )
>>> t.tag()
'<input type="text" id="field_foo" name="foo" value="" class="myClass" />'
and then
<style>
.myClass { width: 200px; background-color:yellow;}
</style>
It's useful to open up fields in an interactive session (like PyCrust)
and poke in it; there are all kinds of useful methods, like setting the
access key and tab order in forms.
This is also the way to add javascript or whatever.