JSF 1.2 DataTable management during view creation - jsf-1.2

I have a question on how JSF 1.2 manages DataTable exactly. Consider this table (suppose that tableList.persone has 3 items):
<h:dataTable id="tablePersone" value="#{tableList.persone}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="STATO" />
</f:facet>
<h:inputText value="#{item.stato}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="CODICE" />
</f:facet>
<h:inputText value="#{item.codice}" />
</h:column>
</h:dataTable>
I read that jsf iterates over the items of the list during the render response phase, in fact, "item" is not available when the view is built.
Does it means that jsf does not duplicate the content of the table for each item in the list when creating the tree component?
In the table above, each row has 2 inputText. If jsf does not create a couple of inputText objects for each row, how jsf handles all the 6 request parameters when the form is submitted (in particular during the apply request values phase).
Thanks a lot,
Nico

If I am not wrong
Restore View phase - in this phase retrieves the component tree for the requested page if it was displayed previously or constructs a new component tree if it is displayed
for the first time. If the page was displayed previously, all components are set
to their prior state. This means that JSF automatically retains form information.
For example, when a user posts illegal data that is rejected during decoding,
the inputs are redisplayed so that the user can correct them.
Apply Request Values phase- In this phase, the JSF
implementation iterates over the component objects in the component tree. Each
component object checks which request values belong to it and stores them.
Process Validations phase, the submitted string values are first converted
to “local values,” which can be objects of any type. When you design a JSF
page, you can attach validators that perform correctness checks on the local
values. If validation passes, the JSF life cycle proceeds normally. However,
when conversion or validation errors occur, the JSF implementation invokes
the Render Response phase directly, redisplaying the current page so that the
user has another chance to provide correct inputs.
Update Model Values phase- in this phase the
local values are used to update the beans that are wired to the components.
Invoke Application phase the action method of the button or link component
that caused the form submission is executed
Render Response phase - encodes the response and sends it to the
browser.

Related

How can values in the Alfresco pooled tasks table be changed?

I would like to change the data that is displayed in one of the Pooled Tasks
columns. It's not clear where does that data comes from.
For example, in my pooled-tasks-todo-dashlet.jsp file it has this section:
<%-- Status column --%>
<a:column id="col6" style="padding:2px;text-align:left">
<f:facet name="header">
<a:sortLink id="col6-sort" label="#{msg.status}" value="bpm:status" styleClass="header"/>
</f:facet>
<h:outputText id="col6-txt" value="#{r['bpm:status']}" />
</a:column>
Where is the status value "#{r['bpm:status']}" stored?
How do you add a new value that is not already defined?
Thanks
The object #{r} is the current node object iterated over the Alfresco JSF component a:richList. The value of this component is set by a JSF Bean, thus if you want to add a new property to #{r} I think the better way is by adding it in the Java bean that populates the richlist.
If you are only interested in modifying the values of the property jbpm:status, I guess it is bpm engine specific (it can be either jbpm or activity).
I have done it in one of my project.
If you observe jsp page in rich list tag you will find this
value="#{WorkflowBean.pooledTasks}
The bean which populate the rich list is workflowBean
which points to this class org.alfresco.web.bean.workflow.WorkflowBean
and this API get called when dashlet is open
List getPooledTasks()
It populates the pooledTask List then just like for loop we iterate the nodes one by one with r pointing to current workflow node.

Can I separate a spring form?

I am using tiles, Spring MVC, Spring form tag. I want to make a form that step by step. When click a button, show more inputs from another tiles definition. But throw a exception can not find "Neither BindingResult nor plain target object for bean name " , It looks the "more inputs" can not get bindle object from previous request, is it right?
Source code:
<form:form action="/saveTicker.do" commandName="ticker" modelAttribute="ticker" method="post">
...
<form:input path="name" id="name"/>
Confirm
<div class="row" id="filelist">
</div>
</form>
js
var confirmTicker=function(){
var ticker=$('input:text').val();
$.get("/confirmTicker.do",{ticker:ticker}).success(function(data){
$('#filelist').html(data);
});
}
want to import another file
<table class="table ">
<c:forEach var="f" items="${fileList}">
<tr>
<td>
<form:checkbox path="files" value="${f}"></form:checkbox>
</td>
</tr>
</c:forEach>
</table>
The error is
Neither BindingResult nor plain target object for bean name 'files' available as request attribute
If I am reading this correct, what you want is a "wizard" form where the user is passed from one form to the next as a series of steps. First, I believe Spring Web Flow does this out of the box, but, if like me, you cannot use Spring Web Flow you can do this manually.
First, you need a Form Bean (read Command object) that has all the possible inputs from all the forms.
Next, you will either have one Controller method that accepts your Form Bean and returns the proper step (this is what I did), or you can have multiple methods...it doesn't matter. You will use the #ModelAttribute annotation on the handler method to bind the Form Bean to the view form. Also, #SessionAttributes annotation at the top of the controller to set the Form Bean as a session attribute. Make sure the name of the #ModelAttribute, #SessionAttribute, and the view all correspond to the same attribute name.
Last, create multiple views, each with the same , but each with only the pieces you want to set on the FormBean at that point. You cannot use JSR 303, or at least I don't know how you can, since you can't have validation done between steps. You will have to handle validation at the end on your own.

p:commandButton doesn't execute f:setPropertyActionListener in JSF 2

I work with JSF2 and PrimeFaces and I want to go to another page with this button:
<p:column>
<h:commandButton action="userCommand" value="list of commands" >
<f:setPropertyActionListener value="#{car}" target="#{userController.u1}" />
</h:commandButton>
</p:column>
On the target page I use some information from userController.u1, but the <f:setPropertyActionListener> tag doesn't seem to be executed.
I thus get the following exception:
java.lang.NullPointerException
In response to Arjan, thank you for your detailed response, but I think there is another method to do this, instead of using a new managedBean as I did in my question, I use one (sessionScoped) that is already instantiated and then I called it in the new constructor to retrieve the value,
How do you find this solution? Can you help me to call the other managedBean from the constructor of the new managedBean?
Because I tested this :
ELContext elContext = context.getELContext();
Application application = context.getApplication();
String userid = (String) application.evaluateValueExpressionGet(context,
"#{userBean.userid}", String.class);
but I have a problem with "context". Do you have any idea?
It depends on how you setup the corresponding navigation rule for userCommand and/or the scope of userController if this is going to work at all.
The action listener sets a value in the bean before navigation happens. If the navigation causes a redirect to happen, then the bean must be in a scope that's available after this redirect. Without having added any additional scopes, this would be the application scope and session scope.
If the bean was in request scope or view scope, your value would be set in the bean corresponding to the request before the redirect took place. After the redirect a new request to a new page is done, and hence a new request scope or new view scope starts. This means your value will be lost.
Using the application scope or session scope would theoretically fix this, but you would run into major problems if your application had multiple users (very likely) or if a single user has multiple windows/tabs open.
In case your navigation rule does not use a redirect, it should actually work. The problem now is that you'll be suffering from the "one URL behind problem": the address bar of the browser will still show the old page.
Since you're not really executing any action and just want to go to a new page, a better approach is to link directly to that page using an <h:button> or <h:link> and provide the If of said car as a parameter.
This will issue a GET request, which has the additional benefit of being bookmarkable. If you were doing the Post-Redirect thing, it will also initially perform better. On the target page, you do have to be prepared to convert the parameter back into the car instance. For this you can use the <f:viewParam> tag.
Example for linking:
<p:column>
<h:button outcome="userCommand" value="list of commands">
<f:param name="car_id" value="#{car.id}"/>
</h:Button>
</p:column>
Example for target page:
<f:metadata>
<f:viewParam name="car_id" value="#{userController.u1}" converter="#{carConverter}" />
</f:metadata>
For a working example of this see index.xhtml and user_edit.xhtml in this example CRUD application.

Customizing sublayout caching in Sitecore

When using WebControls in Sitecore, there is a way to customize caching behavior - override GetCachingID method.
Is there a way to achieve something like this with Sublayouts(UserControls)? I'd like to add custom "VaryBy" options(example - "Vary By Moon Position").
Yes, sublayout caching can vary by several different criteria by default. You can leverage varying by parameters to do this. The vary-by's are:
Vary by Data
Vary by Device
Vary by Login
Vary by Parameters
Vary by Query String
Vary by User
The approach for you to customize here is Vary by Parameters and YOU define what the parameters are. You can do this in Presentation Details where you dynamically assign a sublayout to an item (there is a section at the bottom of the control properties to define parameters) or you can set this via C# code. Here an example using C# code to statically assign a sublayout into my layout:
<h1>My website</h1>
<h2>My site is great</h2>
<sc:Sublayout ID="slMyControl" path="~/path/to/my/control.ascx" VaryByParm="true" Cachable="true" runat="server" />
(One thing to note in the above code, the attribute for VaryByParam is actually VaryByParm in Sitecore, which is obviously a typo in their code.)
Now in the C#, set the parameters programatically:
slMyControl.Parameters = "myKey1=MyVal1&myKey2=myVal2";
If you can get a Moon Position in C#, then convert it to a string and assign it to the parameters:
slMyControl.Parameters = "position=" + getMoonPosition().ToString();
I recently cached a calendar by the month and year which appear in the query string. Simple example with no error handling:
slEventCalendar.Parameters = string.Format("m={0}&y={1}", Request.QueryString["m"], Request.QueryString["y"]);
The parameter string you end up with eventually becomes part of the actual cache key. Coupling this with other vary by options just making a more complex cache key with more criteria and thus more cached instances. The general rule is, cache by the least amount of criteria you need to which will result in the most amount of use from that cached instance.

How Can I Make the XmlIgnore Attribute Method-Specific in a WebService (ASP.Net)?

I understand that I can make the property nullable or use a bool called [PropertyName]Specified to determine whether the property is serialized to XML, but I would like the auto-generated examples to hide these elements in one method's definition, and show them in another. This way the user knows whether they'll be there or not.
For example,
here is what displays now (same for both):
Web Service Method1 Example
...
<Object>
<Column Value="int" xsi:nil="true" />
</Object>
...
Web Service Method2 Example
...
<Object>
<Column Value="int" xsi:nil="true" />
</Object>
...
here is what I want to display:
Web Service Method1 Example
...
<Object>
<Column Value="int" />
</Object>
...
Web Service Method2 Example
...
<Object />
...
Is this even possible without creating different Classes?
No, it's not. You're serializing instances of classes. This is independent of web methods.
The web service infrastructure doesn't fit what you're looking for. In WSDL, an operation uses messages which have parts which are of types which are described in an XML schema. In order for two operations to be the same except for one element (column), they must use messages referring to different types.
Alternatively, you could have one of your methods accept a parameter of a class without the extra column, and have the other use that same parameter, plus a separate parameter which is just the extra column.
Best way, then, is just to have one class inherit the other and add the Column property.

Resources