<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Martin -<br>
<br>
Martin Marinschek wrote On 4/7/2009 8:43 AM ET:
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <pre wrap="">Hi Andy,

thanks for your very long and extensive mail - you covered everything.
  </pre>
</blockquote>
<br>
Thanks for reading through my long email and for the comments! :-)&nbsp;
Sorry I wasn't able to follow up on this last week...<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite"><br>
  <pre wrap="">cs-JSF deals with this. What we do is we encode params into the
button-value, and decode these params in a request-parameter map
wrapper so that they are available to the rest of the lifecycle just
as if they were normal params.
  </pre>
</blockquote>
<br>
Cool, makes sense.<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <blockquote type="cite">
    <pre wrap="">
The main use case for 3B is master-detail components.
    </pre>
  </blockquote>
  <pre wrap=""><!---->

.. and a lot of other stuff - it is the most-used use-case for us for
partial page update with regards to input-components. You change some
input, and somewhere else, some input shows up, vanishes, gets
disabled enabled, etc.
  </pre>
</blockquote>
<br>
Right, agree completely.&nbsp; When I used the term "master-detail", I
should have said that I was using this loosely - ie. I just meant any
case where updating one (master) component results in other (detail)
components somewhere else on the page being updated (or hidden/shown).<br>
<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <blockquote type="cite">
    <pre wrap="">
One concern that I have about this approach is that it means that the Behavior implementation needs to be familiar with the component - and possibly the component's content - to know when to render, or whether to render anything at all. &nbsp;For example, if the Behavior is attached to an &lt;h:selectOneMenu&gt;, then it might want to render a "Refresh" button. &nbsp;However, if the Behavior is attached to an &lt;h:commandButton&gt; (or some other component, like an &lt;h:panelGrid&gt;), then no "Refresh" button should be rendered.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
you are right - it is component dependent. but don't we have several
decisions already in the behaviour classes, depending on the
component-type? e.g. the default event-type (onclick, onchange, etc.).
So how is this different?
  </pre>
</blockquote>
<br>
<br>
In the initial non-generic/Ajax-specific design we did have assumptions
based on the component type - ie. &lt;f:ajax&gt; only supported
"action" events for command components and "valueChange" events for
editableValueHolders.&nbsp; This was awful - and one of the main reasons why
we decided to move forward with the generic Behavior solution.<br>
<br>
With the current solution, the component identifies the set of
supported events as well as the default event via the
ClientBehaviorHolder interface.&nbsp; This allows ClientBehavior
implementations (such as AjaxBehavior) to avoid making assumptions
based on the component type, which is important for interoperability -
ie. this allows us to write ClientBehavior implementations which are
not specific to a known set of components - but can work with arbitrary
components from different component providers (eg. RichFaces, IceFaces,
Trinidad, ADF Faces, etc...).<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <blockquote type="cite">
    <pre wrap="">I would prefer that we come up with a solution where the component Renderer decides when/where to have the Behavior render its fallback content, since the component Renderer knows both whether it requires fallback content at all and also knows where the best placement of the fallback content might be.
    </pre>
  </blockquote>
  <pre wrap=""><!---->

ok, but with the same argument we could have said that ajax-rendering
should be happening directly in the renderer from the beginning,
right? The idea is that any component can be AJAX enabled, now when
JavaScript is disabled, the arbitrary component will not have any idea
that AJAX was enabled from the beginning, so also not any knowledge at
all that it should render a fallback now.
  </pre>
</blockquote>
<br>
<br>
Right.&nbsp; The component renderer knows:<br>
<br>
- Whether or not a particular event exposed via the
ClientBehaviorHolder contract is worthy of fallback behavior.&nbsp; For
example, the renderer for &lt;h:inputText&gt; knows that the
"valueChange" event is special compared to, say, the "mouseOver" event
- ie. that fallback behavior should be provided (if available) for the
"valueChange" event, but not for the "mouseOver" event.<br>
- Where fallback content should be placed (if available).<br>
- Whether any ClientBehaviors are available for an event that warrants
fallback behavior.<br>
<br>
As you point out, however, the component renderer does not currently
know whether a ClientBehavior or ClientBehaviors attached to such
events are capable of producing fallback content.&nbsp; So, if we want to
support fallback content rendering in a generic way, we could add two
new methods to ClientBehavior:<br>
<br>
1. public boolean isFallbackAvailable()<br>
2. public void renderFallback(BehaviorContext)<br>
<br>
ClientBehaviors that are capable of providing fallback content would
implement isFallbackAvailable() to return true.&nbsp; Component renderers
that care about providing fallback content would:<br>
<br>
- Check to see whether JavaScript is disabled (need some standard API
for this).<br>
- If so, check to see whether they have any ClientBehaviors attached to
events that warrant fallback content (eg. "valueChange" for
&lt;h:inputText&gt;).<br>
- If so, check to see whether any of these ClientBehaviors have
fallback content available by calling isFallbackAvailable().<br>
- If fallback content is available, figure out where to render the
fallback content (this may involve altering the component's own
rendered content - eg. may mean rendering rendering additional layout
elements or styles).<br>
- Finally, call renderFallback() to allow the ClientBehavior to produce
the fallback content (eg. a "Refresh" button).<br>
<br>
If it is too late to get something like this in for 2.0 - ie. if we
cannot add these two methods to ClientBehavior, then we can still solve
this problem in 2.1 by introducing a FallbackClientBehavior interface.&nbsp;
This means that renderers will need to do an "instanceof
FallbackClientBehavior" test when trying to determine whether fallback
content is available, but this seems reasonable to me.<br>
<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <pre wrap=""><!---->
in this case, we would really need to provide something in the spec
which checks if javascript is enabled. Can we really still do this for
2.0?
  </pre>
</blockquote>
<br>
I know that the 2.0 spec has been handed off to the JCP - not sure how
much leeway we have to add new APIs at this point.&nbsp; Were you thinking
of new methods on FacesContext?&nbsp; Perhaps something like:<br>
<br>
- public boolean isClientScriptingDisabled()<br>
- public void setClientScriptingDisabled()<br>
<br>
This might be useful even if we did not provide any automatic detection
for the disabled scripting case, since it would at least provide a
standard way for server-side code (components/renderers/behaviors) to
easily determine whether to script-free content is required.<br>
<br>
I do think it is possible to do everything that we discussed here in
2.1.&nbsp; If it is too late to support this in 2.0, perhaps we should add
"disabled JavaScript support" to our 2.1 feature list - not just for
ClientBehavior/AjaxBehavior - but for the more general
&lt;h:commandButton&gt;/&lt;h:commandLink&gt; case as well.<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite"><br>
  <pre wrap="">ok, now this is not so extremely easy. What we do in cs-JSF is we have
a noscript tag - in this noscript tag, we render content which
displays a modal dialog, telling the user that javascript is disabled
and that he is forwarded to a javascript-free version of the page.
  </pre>
</blockquote>
<br>
Just curious - how do you do the forward?<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <pre wrap="">
I don't see how we can easily do the same in the spec - what we could
do is we could provide some information in the faces-messages section
of the page including a link. This information would only be rendered
in a noscript environment and - on clicking the link - would forward
the user to the script-free version of the page.
  </pre>
</blockquote>
<br>
Yeah - seems like something along these lines would work.&nbsp; Thanks for
suggesting this solution!<br>
<br>
We could consider encapsulating this in a "noscript" component that
renders the appropriate content.<br>
<br>
<blockquote
 cite="mid:5a99335f0904070543y38fa0882v5bb2af3fb86beb07@mail.gmail.com"
 type="cite">
  <pre wrap="">
Without this, we cannot check if javascript is enabled on the first
page, and therefore we cannot make sure that rendering is done
appropriately on the first page. Another option would be to let the
application decide how it detects the JavaScript state</pre>
</blockquote>
<br>
Right.&nbsp; If we provide standard APIs for tracking the disabled scripting
state (eg. FacesContext is/setClientScriptingDisabled()), then we could
simply leave it up to the app developer to figure out when to call
setClientScriptingDisabled(true), at least for the moment.&nbsp; Of course,
it would be good to provide a standard mechanism for automatically
detecting the disabled scripting scenario, though I imagine this would
need to wait until 2.1.<br>
<br>
Andy<br>
<br>
</body>
</html>