Using ZPT with options/radio/checkboxes
Is there an easy way to use TAL/TALES to set the checked values of radios and checkboxes and the selected attribute of options? I am trying to find a clean example. For Instance: <select name="question_type" id="question_type"> <option value="Text" selected="selected">Text</option> <option value="TextArea">TextArea</option> <option value="ListSingle">ListSingle</option> <option value="ListMulti">ListMulti</option> <option value="ComboSingle">ComboSingle</option> <option value="Option">Option</option> <option value="Checkbox">Checkbox</option> </select> If the question_type was in the REQUEST object, how would I evaluate which one was selected? Same goes for radio buttons: <input type="radio" name="required" value="1" /> Yes <input name="required" type="radio" value="0" checked="checked" /> No and the 'required' was in the REQUEST object. I am trying to do this using TAL/TALES only. Thanks for any suggestions/code samples. Chris Chris Bruce Bionic Pixels LLC www.bionicpixels.com 323-660-8444 323-650-9926 fax 964 1/2 N. Vermont Ave. Los Angeles, CA 90029
On ke, 06.08.2003 at 14:17 -0700, Chris Bruce wrote:
For Instance:
<select name="question_type" id="question_type"> <option value="Text" selected="selected">Text</option> <option value="TextArea">TextArea</option> <option value="ListSingle">ListSingle</option> <option value="ListMulti">ListMulti</option> <option value="ComboSingle">ComboSingle</option> <option value="Option">Option</option> <option value="Checkbox">Checkbox</option> </select>
If the question_type was in the REQUEST object, how would I evaluate which one was selected?
<select> <span tal:repeat="option options" tal:omit-tag=""> <option tal:condition="python: option == request.get('question_type')" selected="selected" tal:content="option"/> <option tal:condition="not:python: option == request.get('question_type')" tal:content="option"/> </span> </select>
Same goes for radio buttons: <input type="radio" name="required" value="1" /> Yes <input name="required" type="radio" value="0" checked="checked" /> No
and the 'required' was in the REQUEST object.
<span tal:condition="python:request.get('required')" tal:omit-tag=""> <input type="radio" name="required" value="1" checked="checked"/> Yes <input type="radio" name="required" value="0"/> No </span> <span tal:condition="not:python:request.get('required')" tal:omit-tag=""> <input type="radio" name="required" value="1"/> Yes <input type="radio" name="required" value="0" checked="checked"/> No </span> -- paavo. "How convenient for you then that others have to work in a sweatshop so that you won't have to be poor..."
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Chris Bruce
Is there an easy way to use TAL/TALES to set the checked values of radios and checkboxes and the selected attribute of options?
<select name="question_type" id="question_type"> <option value="Text" selected="selected">Text</option> <option value="TextArea">TextArea</option> ... </select>
If the question_type was in the REQUEST object, how would I evaluate which one was selected?
<select name="question_type" id="question_type"> <option value="Text" tal:attributes="selected python:path('request/question_type | nothing') == 'Text'">Text</option> ... </select> If you have the option values in a list, you can "repeat" through them, filling in the blanks. Otherwise, you'll need to put the tal:attributes in each option tag. The "| nothing" is to fail gracefully if question_type happens to not be in REQUEST.
Same goes for radio buttons: <input type="radio" name="required" value="1" /> Yes <input name="required" type="radio" value="0" checked="checked" /> No
and the 'required' was in the REQUEST object.
<input type="radio" name="required" value="1" tal:attributes="checked python:path('request/required | nothing') == '1'" /> Yes <input type="radio" name="required" value="0" tal:attributes="checked python:path('request/required | nothing') == '0'"/> No This will work for checkboxes too. The "| nothing" is especially important for checkboxes, since a checkbox variable is only set if it's checked. If it's unchecked, it's left out of REQUEST altogether. Hope this helps. _______________________ Ron Bickers Logic Etc, Inc.
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Ron Bickers
<input type="radio" name="required" value="1" tal:attributes="checked python:path('request/required | nothing') == '1'" /> Yes <input type="radio" name="required" value="0" tal:attributes="checked python:path('request/required | nothing') == '0'"/> No
As a follow up to this for checkboxes... The following should work even though it doesn't test the value, since (as I mentioned) checkboxes will only be there if they're checked. <input type="checkbox" name="likespizza" value="1" tal:attributes="checked request/likespizza | nothing" /> If you have a :list of checkboxes, you could use the following: <input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:'Pepperoni' in path('request/toppings | python:[]') /> Pepperoni <input type="checkbox" name="toppings:list" value="Mushroom" tal:attributes="checked python:'Mushroom' in path('request/toppings | python:[]') /> Mushroom <input type="checkbox" name="toppings:list" value="Green Pepper" tal:attributes="checked python:'Green Pepper' in path('request/toppings | python:[]') /> Green Pepper These are the cleanest ways I've found to do this. If someone has a cleaner one, I'd like to know. _______________________ Ron Bickers Logic Etc, Inc.
On Thu, Aug 07, 2003 at 01:59:34AM -0400, Ron Bickers wrote:
<input type="checkbox" name="likespizza" value="1" tal:attributes="checked request/likespizza | nothing" />
If you have a :list of checkboxes, you could use the following:
<input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:'Pepperoni' in path('request/toppings | python:[]') /> Pepperoni (snip)
well, this is fascinating and very surprising to me. I didn't see how your examples could work, until I tried them. As I've always (mis)understood TAL, I thought that the following bit of ZPT... <input type="checkbox" attributes="checked python:0" /> <input type="checkbox" attributes="checked python:1" /> ... should evaluate to the following HTML... <input type="checkbox" checked="0" /> <input type="checkbox" checked="1" /> ... and in both cases, Mozilla displays the checkbox as checked. But in fact, this is not what happens!! The rendered HTML is: <input type="checkbox" /> <input type="checkbox" checked="checked" /> Apparently, there is some special-casing in ZPT such that "checked" and "selected" attributes are handled differently from all others. The return value of the expression is tested for truth and then discarded. I must say that while this is convenient, it has 3 problems: 1) It's surprising - other attributes don't behave this way. 2) It's undocumented AFAICT. 3) It's specific to XHTML and likely to be problematic when using ZPT to generate other flavors of XML. I notice that this special behavior is applied regardless of what tag you put these attributes in. I wonder if it would be better to have an explicit way that can be used for any attribute, to conditionally insert or omit it. There is of course the common idiom of writing the entire tag twice with two opposing "tal:condition"s, but that often leads to redundant html as well as redundant tag contents. So it might be nice to be able to say "If this expression is true, set the value of this attribute to the result; otherwise, omit the attribute." Like so: <input type="checkbox" tal:conditional_attributes="checked request/some_var | nothing" /> Or, an alternative, there could be a way to say "remove the attribute if this expression is true": <input type="checkbox" checked="checked" tal:omit_attributes="checked not:request/some_var | nothing" /> ... or maybe spell it like this, to say "keep the attribute if this expression is true": <input type="checkbox" checked="checked" tal:attribute_filters="checked request/some_var | nothing" /> I think I like that last variant the best, it seems easier to understand than the first and usually more natural than the second. It also combines nicely with existing tal:attributes useage: <p tal:attributes="class here/get_special_style" tal:attribute_filters="class request/something | nothing" > (As an optimization, tal:attribute_filters could be evaluated first, and tal:attributes would not evaluate attributes that are to be filtered out.) P.S. okay Shane, fire away ;-) -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's POST-MEGATRON-IAN! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Paul Winkler
<input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:'Pepperoni' in path('request/toppings | python:[]') /> Pepperoni (snip)
well, this is fascinating and very surprising to me. I didn't see how your examples could work, until I tried them.
Apparently, there is some special-casing in ZPT such that "checked" and "selected" attributes are handled differently from all others.
Indeed. I didn't realize this. Regardless of the attribute, if the expression evaluates to 'nothing', then it's discarded. One could accomplish the same as above by doing the following and there would be no need for special handling of checked/selected. <input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:test('Pepperoni' in path('request/toppings | python:[]'), 'checked', nothing)" /> Not quite as elegant, but it's not horrible and it behaves as expected, yes? _______________________ Ron Bickers Logic Etc, Inc.
On Thu, Aug 07, 2003 at 12:54:25PM -0400, Ron Bickers wrote:
Regardless of the attribute, if the expression evaluates to 'nothing', then it's discarded.
yes, i'd missed that... and it's documented.
One could accomplish the same as above by doing the following and there would be no need for special handling of checked/selected.
<input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:test('Pepperoni' in path('request/toppings | python:[]'), 'checked', nothing)" />
Not quite as elegant, but it's not horrible and it behaves as expected, yes?
nested python: expressions.... hmm... sorry to say that pushes it over the "horrible" mark for me :-\ I might write it like this: <input type="checkbox" name="toppings:list" value="Pepperoni" checked="checked" tal:attributes="checked python:test('Pepperoni' in request.get('toppings', []), default, nothing)" /> or like this: <input type="checkbox" name="toppings:list" value="Pepperoni" checked="checked" tal:attributes="checked python:('Pepperoni' in request.get('toppings',[])) and default or nothing" /> -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's KILLER YELLOW SOLDIER! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Paul Winkler
I might write it like this:
<input type="checkbox" name="toppings:list" value="Pepperoni" checked="checked" tal:attributes="checked python:test('Pepperoni' in request.get('toppings', []), default, nothing)" />
or like this:
<input type="checkbox" name="toppings:list" value="Pepperoni" checked="checked" tal:attributes="checked python:('Pepperoni' in request.get('toppings',[])) and default or nothing" />
Yeah. These are nicer. I got my version long ago during discussions before ZPT was included in Zope. So, my select/option and radio examples without needing the special behavior would look like this: <select name="question_type" id="question_type"> <option value="Text" tal:attributes="selected python:request.get('question_type', None) == 'Text' and 'selected' or nothing">Text</option> ... </select> ...and... <input type="radio" name="required" value="1" tal:attributes="checked python:request.get('required', None) == '1' and 'checked' or nothing" /> Yes <input type="radio" name="required" value="0" tal:attributes="checked python:request.get('required', None) == '0' and 'checked' or nothing"/> No I don't know if any graphical editors will have a problem with multiple inputs having the checked/selected attribute or not, so I chose the string 'selected' instead of default. Did I miss anything? Is there an advantage or disadvantage of using "and...or" instead of test()? _______________________ Ron Bickers Logic Etc, Inc.
On Thu, Aug 07, 2003 at 03:09:57PM -0400, Ron Bickers wrote:
I don't know if any graphical editors will have a problem with multiple inputs having the checked/selected attribute or not, so I chose the string 'selected' instead of default.
hmm, that's a good point, i don't know either. I'd be worried of something "fixing" it for me.
Did I miss anything? Is there an advantage or disadvantage of using "and...or" instead of test()?
only that it short-circuits. In the expression "foo and bar or baz": * bar is only evaluated if foo is true. * baz is only evaluated if either foo or bar is false. test() evaluates everything before it is even called. However, in the grand scheme of things, this is probably not significant to your website performance :-) -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's THE PUERILE DEMON! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Paul Winkler
<input type="checkbox" name="toppings:list" value="Pepperoni" tal:attributes="checked python:test('Pepperoni' in path('request/toppings | python:[]'), 'checked', nothing)" />
Not quite as elegant, but it's not horrible and it behaves as expected, yes?
nested python: expressions.... hmm... sorry to say that pushes it over the "horrible" mark for me :-\
I remember now why I used the path() function with a nested python expression instead of the get method... If you're using a variable other than 'request' (which we know will exist), you'll get an exception if that variable doesn't exist. The path() function handles this gracefully and returns nothing. So, how would you write the following more elegantly to handle when 'somevar' doesn't exist? "python:test('A' in path('somevar/letters' | python:[]'), 'checked', nothing)" _______________________ Ron Bickers Logic Etc, Inc.
On Thu, Aug 07, 2003 at 03:44:30PM -0400, Ron Bickers wrote:
I remember now why I used the path() function with a nested python expression instead of the get method...
If you're using a variable other than 'request' (which we know will exist), you'll get an exception if that variable doesn't exist. The path() function handles this gracefully and returns nothing.
So, how would you write the following more elegantly to handle when 'somevar' doesn't exist?
"python:test('A' in path('somevar/letters' | python:[]'), 'checked', nothing)"
I'd make sure it exists :-\ Seriously, when is this a problem? If somevar is at the top level, you've either defined it somewhere or it's one of the built-in names. If it's not either one, it must be a mistake. What am I missing? -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's UNGODLY FIST CAPTAIN! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Paul Winkler
So, how would you write the following more elegantly to handle when 'somevar' doesn't exist?
"python:test('A' in path('somevar/letters' | python:[]'), 'checked', nothing)"
I'd make sure it exists :-\ Seriously, when is this a problem? If somevar is at the top level, you've either defined it somewhere or it's one of the built-in names. If it's not either one, it must be a mistake. What am I missing?
Ah. My explanation wasn't correct. I'll try again... If I define somevar as follows, which I commonly do: define="somevar session/somevar | nothing" Then yes, somevar will exist, but if it's 'nothing', it won't have a get method. That's when it will raise the exception if I use your code to check it. Hmmm... Should I define somevar like this instead? define="somevar session/somevar | python:{}" _______________________ Ron Bickers Logic Etc, Inc.
On Thu, Aug 07, 2003 at 04:22:01PM -0400, Ron Bickers wrote:
If I define somevar as follows, which I commonly do:
define="somevar session/somevar | nothing"
Then yes, somevar will exist, but if it's 'nothing', it won't have a get method. That's when it will raise the exception if I use your code to check it.
Hmmm... Should I define somevar like this instead?
define="somevar session/somevar | python:{}"
maybe... sometimes... i dunno? i think i've reached the end of my ability to generalize about this topic :-) - Paul Winkler http://www.slinkp.com Look! Up in the sky! It's NEGA <I>N</I> + 1 MANTICORE! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Paul Winkler
On Thu, Aug 07, 2003 at 04:22:01PM -0400, Ron Bickers wrote:
If I define somevar as follows, which I commonly do:
define="somevar session/somevar | nothing"
Then yes, somevar will exist, but if it's 'nothing', it won't have a get method. That's when it will raise the exception if I use your code to check it.
Hmmm... Should I define somevar like this instead?
define="somevar session/somevar | python:{}"
maybe... sometimes... i dunno? i think i've reached the end of my ability to generalize about this topic :-)
Ok. I'm actually in the middle of working on a form-heavy site where this type of stuff is needed a lot, thus my interest in this in a non-generalized fashion. I changed my somevar definition as I suggested to myself above and used your simplified versions. All is working well and I like it much better. For the record and the archives... I just realized that in my examples I specified None as the optional second argument to get(), forgetting that None is the default, so it can be left out. Thanks for your input, Paul. _______________________ Ron Bickers Logic Etc, Inc.
Paul Winkler wrote:
1) It's surprising - other attributes don't behave this way.
Not very. The attributes it applies to need this, and I think it only happens if the content type of the ZPT is text/html. Try doing a checkbox withotu this feature ;-)
2) It's undocumented AFAICT.
Hmm... try the Zope 2.6 Book, I know I've read this documentation in the language specs somewhere...
3) It's specific to XHTML and likely to be problematic when using ZPT to generate other flavors of XML. I notice that this special behavior is applied regardless of what tag you put these attributes in.
See note about content type above.
There is of course the common idiom of writing the entire tag twice with two opposing "tal:condition"s, but that often leads to redundant html as well as redundant tag contents.
Erg! Ug! Yuk! People do this?!
<input type="checkbox" tal:conditional_attributes="checked request/some_var | nothing" />
I suspect that will work as expected if you remove the conditional_ prefix... do let me know though! cheers, Chris
On Thu, Aug 07, 2003 at 06:00:05PM +0100, Chris Withers wrote:
Paul Winkler wrote:
1) It's surprising - other attributes don't behave this way.
Not very. The attributes it applies to need this, and I think it only happens if the content type of the ZPT is text/html. Try doing a checkbox withotu this feature ;-)
hmm. OK that sounds sensible. If this is the case, and given the omit-"nothing" behavior that I didn't know about, my whole proposal is probably unnecessary. Whew. :-) But when I try setting the content-type to text/xml, the tal:attributes are not evaluated at all! I see the raw tal:attributes expressions in the output! wha???? It does seem a bit odd that "selected" and "checked" can be omitted when the expression returns *any* pythonically false value, while other attributes only behave this way when the return value is pythonically None (aka nothing). But i guess that's a quibble.
2) It's undocumented AFAICT.
Hmm... try the Zope 2.6 Book, I know I've read this documentation in the language specs somewhere...
Looking again, I see that the delete-when-"nothing" behavior is documented, in both the Advanced Page Templates chapter and the ZPT reference. Hmm, I should read those again. :-) It's also possible to keep the value of an attribute when the expression evaluates to "default". neat! However, there is no mention of this special behavior for checked & selected - that true values are discarded and replaced with the name of the attribute.
3) It's specific to XHTML and likely to be problematic when using ZPT to generate other flavors of XML. I notice that this special behavior is applied regardless of what tag you put these attributes in.
See note about content type above.
see weird result above :)
There is of course the common idiom of writing the entire tag twice with two opposing "tal:condition"s, but that often leads to redundant html as well as redundant tag contents.
Erg! Ug! Yuk! People do this?!
Erg ug yuk, indeed... but it was posted as a suggestion earlier in this very thread, and I've seen it a lot.
<input type="checkbox" tal:conditional_attributes="checked request/some_var | nothing" />
I suspect that will work as expected if you remove the conditional_ prefix... do let me know though!
Well, it sort of does. Discarding the return value still seems icky to me. I guess it was considered necessary, to avoid the need for a python expression like so: <input type="checkbox" checked="checked" tal:attributes="checked python:request.get('some_var') and default or nothing" /> But that could be avoided more cleanly if there were an "and" operator, something like: <input type="checkbox" checked="checked" tal:attributes="checked request/some_var & default | nothing" /> ... but that's another proposal for another day ;-) -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's SUPER MATHEMATICIAN OF WANKFORDSHIRE! (random hero from isometric.spaceninja.com)
-----Original Message----- From: zope-bounces@zope.org [mailto:zope-bounces@zope.org]On Behalf Of Chris Withers
Paul Winkler wrote:
1) It's surprising - other attributes don't behave this way.
Not very. The attributes it applies to need this, and I think it only happens if the content type of the ZPT is text/html. Try doing a checkbox withotu this feature ;-)
Now that we've determined that it's pretty easy to do a checkbox without this feature, should it still be used/abused? Any reason this behavior would be removed from a future Zope, or is this a (not well-documented) convenience that will stay? _______________________ Ron Bickers Logic Etc, Inc.
participants (12)
-
Chris Bruce -
Chris Withers -
Paavo Parkkinen -
Paul Winkler -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers