CSS-bound screens

294 views
Skip to first unread message

Nolan Darilek

unread,
Jul 17, 2012, 11:14:13 AM7/17/12
to Lift
I just used my first CSS-bound screen yesterday and had a couple questions.

What is formName and where is it used?

Also, I had to include this:

override val allTemplate = defaultAllTemplate

What is an allTemplate, and is there a reason that defaultAllTemplate
isn't the, uh, default allTemplate already? :) If I don't include that,
wizard-all.html doesn't render.

Thanks, this looks interesting once I wrap my head around the new features.

Stefan Bradl

unread,
Jul 17, 2012, 12:11:55 PM7/17/12
to lif...@googlegroups.com
+1 for making defaultAllTemplate the default :)

I also used CSS-bound screen for the first time the day before yesterday. I really like it. 
Maybe a little documentation would be nice. I stumbled over a little problem when trying to use it with twitter bootstrap because the labels have class "label" by default which caused them to be rendered with the bootstrap label class (which is not meant for forms). But this could be solved by overriding cssClassBinding.

2012/7/17 Nolan Darilek <no...@thewordnerd.info>


--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

Nolan Darilek

unread,
Jul 17, 2012, 12:15:29 PM7/17/12
to lif...@googlegroups.com

Mind sharing the wizard-all.html that you used with Bootstrap?

I grabbed it from the demo project and snipped out the tables, intending to make a horizontal form. Nothing I did worked, though. I'm wondering if it is as simple as the labels having the label class? My markup looked fairly close to that of the examples, but I could never get the controls on the same line as the labels.

Stefan Bradl

unread,
Jul 17, 2012, 12:55:17 PM7/17/12
to lif...@googlegroups.com
This is what I came up with:

<div>
<div class="screenInfo">
Page <span class="screenNumber"></span> of <span class="totalScreens"></span>
</div>
<div class="wizardTop"></div>
<div class="screenTop"></div>
<div class="globalErrors">
<div class="error"></div>
</div>
<fieldset class="fields form-horizontal">
<div class="fieldContainer">
<div class="control-group">
<label class="control-label"></label>
<div class="controls">
<span class="value input-xlarge"></span>
<ul class="errors help-inline">
<li class="error"></li>
</ul>
</div>
</div>
</div>
</fieldset>
<div class="form-actions">
<button class="btn prev"></button>
<button class="btn cancel"></button>
<button class="btn btn-primary next"></button>
</div>
<div class="screenBottom"></div>
<div class="wizardBottom"></div>
</div>


2012/7/17 Nolan Darilek <no...@thewordnerd.info>

Stefan Bradl

unread,
Jul 17, 2012, 12:57:16 PM7/17/12
to lif...@googlegroups.com
But I could not get the for validation to work. For this it would be necessary to add the error class to the control-group element :(

2012/7/17 Stefan Bradl <madre...@gmx.de>

Peter Brant

unread,
Jul 17, 2012, 1:01:11 PM7/17/12
to lif...@googlegroups.com
@Nolan --

The basic assumption was that if you're using CssBoundLiftScreen, you have some custom layout requirements so it uses the snippet's children as the template by default.  It's certainly beneficial to have something that works out of the box though so if this proves to be a common stumbling block, I have no objection to changing it.

formName is used to create field IDs that are used as binding points when a one-sized-fits-all field template doesn't work anymore.  There are some examples in the demo.  It's also a handy way to manipulate the field using client side JavaScript.

Also, if you turn on trace level logging for your screen, you'll get voluminous logging about what's being bound where.

Regarding the field templates themselves, everything is based on CSS classes.  By default, labels are bound to class="label" / ".label" #> ... (but as Stefan noted, this can be changed if necessary).

@Stefan -- 

I have been pondering a series of LiftScreen Lift Cookbook entries.  Overriding cssClassBinding seems a like a good candidate for one.  This is mentioned in the demo too.

Pete

Peter Brant

unread,
Jul 17, 2012, 1:02:55 PM7/17/12
to lif...@googlegroups.com
Could you elaborate?

Pete

Stefan Bradl

unread,
Jul 17, 2012, 2:08:28 PM7/17/12
to lif...@googlegroups.com
Elaborate the problem with form validation?

Here you can find how form validation in bootstrap works: http://twitter.github.com/bootstrap/base-css.html#forms
Basically you have a css-class "control-group". This is a container for the label and the input field. For the bootstrap form validation to work the css-class "error" needs to be added to the control group when a validation error occurs. I found a function "additionalCssSelectors" or so, maybe this can be used for this? Or maybe it is already working and I just couldn't figure out how :P

2012/7/17 Peter Brant <peter...@gmail.com>

Peter Brant

unread,
Jul 17, 2012, 2:45:24 PM7/17/12
to lif...@googlegroups.com
This thread might help: https://groups.google.com/forum/?fromgroups#!topic/liftweb/nI9Hf8k5aa8

(in a nutshell, you can edit the rendered field using a CssSel by adding a FieldTransform parameter to the field definition)

additionalFormBindings (whose name could be improved perhaps) is a CssSel applied to the form as a whole (&'d together with the main transform).  It's handy for binding things that aren't field related (for example attaching a local action to a button), but it can't modify field content because it's not there yet.

Pete

Stefan Bradl

unread,
Jul 17, 2012, 2:58:11 PM7/17/12
to lif...@googlegroups.com
I watched at the thread. I think using FieldTransform is not quite right for me because I am using addFields. But I found another solution which works fine for me:

I override validate in a base class for my screen like this:

override def validate = {
    val errors = super.validate
    
    for(error <- errors) {
      error.field.uniqueFieldId match {
        case Full(fieldName) => S.appendJs(JsCmds.Run("$('[for=\"" + fieldName + "\"]').parent().addClass('error')"))
        case _ =>
      }
      
    }
    
    errors
  }

But this is solution is specific to my template. So maybe it needs some tweaking to be usable in a general case.

2012/7/17 Peter Brant <peter...@gmail.com>

Stefan Bradl

unread,
Jul 17, 2012, 3:00:43 PM7/17/12
to lif...@googlegroups.com
What about making a lift module which has a BootstrapCssBoundScreen or so and a bootstrap-optimized template? Or maybe it would fit into FoBo?

Nolan Darilek

unread,
Jul 17, 2012, 11:19:19 PM7/17/12
to lif...@googlegroups.com
On 07/17/2012 12:01 PM, Peter Brant wrote:
> @Nolan --
>
> The basic assumption was that if you're using CssBoundLiftScreen, you
> have some custom layout requirements so it uses the snippet's children
> as the template by default. It's certainly beneficial to have
> something that works out of the box though so if this proves to be a
> common stumbling block,

Actually, I was a bit surprised that the CSS binding wasn't rolled into
default LiftScreen. Initially I dumped the template from the demo
project into mine and attempted to use it unmodified, then ran into the
allTemplate = defaultAllTemplate issue after discovering that I had to
pick a different screen superclass.

Is the CSS-bound screen equivalent to LiftScreen in every other way if
the newer style template is used? Given Lift's general trend toward CSS
binding and away from namespaced attributes, I wonder if it might be
worth making the CSS-bound screens as much of a drop-in replacement for
LiftScreen as possible such that the default case just works, then
deprecating LiftScreen a few major versions down the road? The old
wizard-all.html is such an anachronism next to the newer, nicer
templates, so it makes sense to gradually phase out the older
implementation if the newer one can be made as compatible and easy as
possible. I'm not using the newer CSS screens because I have strict
template requirements. I'm using it because I want to use CSS binding
across all my codebases, and wizard-all.html was the one place that
couldn't be done (that I know of, anyway.)

Thanks.

Jeppe Nejsum Madsen

unread,
Jul 18, 2012, 3:54:25 AM7/18/12
to lif...@googlegroups.com
Peter Brant <peter...@gmail.com> writes:

> @Nolan --
>
> The basic assumption was that if you're using CssBoundLiftScreen, you have
> some custom layout requirements so it uses the snippet's children as the
> template by default. It's certainly beneficial to have something that
> works out of the box though so if this proves to be a common stumbling
> block, I have no objection to changing it.

I think it makes good sense to provide some reasonable defaults
ootb. It always makes tinkering easier when you can adjust a few
parameters on something that already works.

/Jeppe

Peter Brant

unread,
Jul 18, 2012, 6:51:32 PM7/18/12
to lif...@googlegroups.com
The functionality provided by CssBoundLiftScreen is a proper superset of LiftScreen's.  If you just want to use it for CSS style one size fits all templating, that works.  If you have more involved requirements, it has a number of features to support this.

Pete

Reply all
Reply to author
Forward
0 new messages