I am working on one old application which is developed in JSF. In that, there is first page on which user fills details and clicks on next button. One filled values, it displays values on second page.
Here one bean is created who is holding first page values and it's request scoped. The page having bean of session scoped. I'm trying to access it using below code:
try {
if (obj == null) {
Application application = FacesContext.getCurrentInstance().getApplication();
appReqDetails = (ClassName) application.createValueBinding("#{obj}")
.getValue(FacesContext.getCurrentInstance());
}
} catch (Exception e) {
logger.error("Error/Exception occured:", e);
}
But approx. out of 100 users, 2-3 users are facing issue of values are not populating.
How to resolve this? Can I change scope of obj? Or any other way to get request scoped object into session scoped class?
Related
On an xpage I calculate the message for an xp:confirm control:
var arr = viewScope.get("attachmentsAll");
if(arr.length>0){
return "";
}else{
return arr.length + " Are you sure want to upload the file?";
}
the viewScope is being updated after the event has been executed. I check this via a xp:text and I notice that this assumption is true.
<xp:text escape="true" id="computedField1"><xp:this.value><![CDATA[#{javascript:var arr = viewScope.get("attachmentsAll")
return arr.length + " number?"}]]></xp:this.value></xp:text>
The xp:confirm and xp:text reside in the same panel that is being partially updated after the event.
Can anyone explain me why the value for the viewScope variable is updated in the xp:text control and not in the xp:confirm control?
The main idea of my answer to your previous question was to put hidden input with computed value. What if you try to use <xp:this.script> instead of xp:confirm, and get the confirmation message from that hidden input the same way?
Update
The reason and the alternative solution that does not require to make any changes to existing xpage
It came out that the back-end instance of xp:confirm evaluates the new message correctly. The new value is even being sent to the browser with the response to ajax request. But one of the functions of XSP client module is built so that it won't update the querySubmit listener function if there already exists one with the same name. So, we are stuck with the old confirmation function that contains the old message. There is a way to override this behavior without breaking any other features. I have tried this and it works for me.
Create a new JavaScript library (client-side). Add the code:
if (!XSP._pushListenerTuned) {
XSP.__pushListener = XSP._pushListener;
XSP._pushListener = function x__pl(listeners, formId, clientId, scriptId, listener) {
if (scriptId && scriptId.endsWith("_confirm")) {
for (var i = 0; i < listeners.length; i++) {
if (scriptId == listeners[i].scriptId) {
listeners.splice(i, 1);
}
}
listeners.push(new this._SubmitListener(formId, listener, clientId, scriptId));
} else {
XSP.__pushListener(listeners, formId, clientId, scriptId, listener);
}
}
XSP._pushListenerTuned = true;
}
Attach your new library as resource globally via theme or as page resource on required page. I guess placing the above code as scriptBlock on a required page should also work. Now, any xp:confirm component on any page (if you used theme resource), or on particular page and everywhere after visiting this page (if you used page resource or scriptBlock), will work as naturally expected.
I searched the whole web and I couldn't found any good topic which expose the proper way to do it.
I have a very simple web which I developed using Kentico 9 CMS. This web only contains two subpages and a header to navigate between those.
The "Home" subpage contains a custom form which remains connected to a SQL table which is populated every time you press submit with certain data.
On the other hand, the other page, shows the stored data by using a custom web part which connects to the DB by using BizFormItemProvider and this object is used as a layer to binding the data in a control.
Now is my point. If you see, there is a button to "Edit" a certain row and my intention is to Redirect to "Home" (which contains the form) and sending via QueryString the ID of the row attempted to edit.
I was unable to understand how can you re-fill the form with its data using an ID.
Maybe because I never worked with a CMS before, I'm looking the development such as pure ASP.NET and it could not be the correct one.
Custom
Given that your solution uses a custom form for entering the data, as well as a custom web part for listing the stored data, you will need to use a custom solution to handle the editing of data, as well.
In the custom webpart on the Home page, in a load event, you can retrieve the form data and set the values on the form controls.
protected void Page_Load(object sender, EventArgs e)
{
// Ensure that the form is not being posted back,
// to prevent entered data from being overwritten
if(!IsPostBack)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
txtFirstName.Text = bizFormItem.GetStringValue("FirstName", string.Empty);
}
}
}
Similarly, when Submit is clicked, you can update the existing form item with the new data
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Retrieve the existing biz form item,
// and update it from the form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
bizFormItem.SetValue("FirstName", txtFirstName.Text);
bizFormItem.Update();
}
else
{
// Your code for inserting a new form item...
}
}
The Kentico way
You should really consider using the Kentico form engine for accomplishing this task. Instead of using a custom form for entering the data, use the built-in On-line form webpart.
The benefits are numerous, such as:
Ability to set the form layout through the CMS, and use alternative layouts
Automatic confirmation email to the submitter of the form, as well as notification emails to the administrators
To accomplish your task, you can customise the On-line form webpart to support loading of existing data.
In the bizform.ascx.cs file, add code to the SetupControl method:
protected void SetupControl()
{
if (StopProcessing)
{
// Existing code...
}
else
{
// Existing code...
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
if(bizFormItem != null)
{
// Set the item ID
viewBiz.ItemID = bizFormItem.ItemID;
}
}
}
}
This will automagically switch the form to Edit mode, instead of Insert mode, as soon as you set the ItemID property. Clicking the Submit button will save changes on the existing form item.
You will not need to worry about validation in your code, and inserting data will still work.
Is this a contact form that you are using Kenticos built in form application for, or is it a custom form? If it is a custom form you can create a transformation with a link that will contain the ID. If it is a biz form, you can still create a transformation in Page Types (create a new page type and select "The page type is only a container without custom fields"), then write a custom query to get the biz form data, and use a repeater to display the data with that transformation.
I received a ConcurrentNodificationException when I implemented a rich:tree with dynamic loading of the nodes.
I'm using JSF1.2, Tomcat 6.0, RichFaces 3.3.3, and Java 6u31.
in JSF page I have this rich tree component
<rich:tree id="treeAreas" value="#{areaArmazenamento.treeAreas}"
var="node"
adviseNodeOpened="#{storageArea.adviseNodeOpenedTreeAreas}"
adviseNodeSelected="#{storageArea.adviseNodeSelectedTreeAreas}"
ajaxSubmitSelection="true"
componentState="#{storageArea.treeAreasState}"
nodeSelectListener="#{storageArea.selectNodeArea}"
nodeFace="#{node.type}" similarityGroupingId="true"
ondragstart="hideContextMenu();" disableKeyboardNavigation="true"
rightClickSelection="true" toggleOnClick="true" requestDelay="150"
changeExpandListener="#{storageArea.expandNodeListener}">
In Managed Bean storageArea I'have the code that load nodes, and on first time the method is called the first level of nodes is loaded, when a click in a node the substructure of this node is loaded.
On load the first level is validated the user's permissions, and this validation use the iterator of list that stores the tree nodes, this validation remove nodes that the user access is denied. some like this:
List<AreaArmazenamento> areas = root.getPastas();
synchronized (areas) {
Iterator<AreaArmazenamento> it = areas.iterator();
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove();
}
}
}
When I click on any node, I select the sub nodes of database and add the substructure in selected node, this working but sometimes on select node is throwed a ConcurrentNodificationException on Hashtable which is in TreeDataModule of Rich Tree.
This is a trace of exception:
Caused by: java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1031)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:136)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.walk(TreeDataModel.java:178)
at org.richfaces.component.UITree.walk(UITree.java:422)
at org.richfaces.renderkit.TreeRendererBase.writeContent(TreeRendererBase.java:683)
anything about it may be causing this error? and why?
I Found the problem...
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove(); //problem here
}
}
I was removing items from the list on iteration...
Have you tried using a4j:queue ?
Here is what I am trying to do.
I want the data from jsf page1 to be available in jsf page2 which is a popup window opened by page1.
Both have separate managed beans.
I tried using sessions but it resulted in null pointers.
I somehow managed to get the data in page2 using window.opener() in javascript.
Now I want this data to be available in the processAction() method of FacesPortlet.
Tried using request.getParameter, request.getAttributes, all in vain.
After a lot of research I somehow managed to send some hard coded data in processAction() method. But I am unable to send the value from page1.
Here is how I am sending the hardcoded value.
<form name="uploadbaseline" method="post"
enctype="multipart/form-data" action="<portlet:actionURL><portlet:param name = "page" value = "someval"/></portlet:actionURL>">
This is followed by the other fields inside the form.
I get the value in processAction() method like this
System.out.println("valuefrompage1"+request.getParameter("page"));
This returns "someval".
Now I try to assign the value from page1 using javascript using the following code.
var val = window.opener.document.getElementById("BaseLine:EngineModel").value;
var actionval = "<portlet:actionURL><portlet:param name='page' value=" + val.value + "/></portlet:actionURL>";
document.uploadbaseline.action = actionval.value;
document.uploadbaseline.submit();
This returns the value "+ val.value +" as it is and not the actual value in the "val" variable.
Please guide me in the right direction.
Keenly looking forward to your replies.
Thanks.
Found the solution finally.
The problem lies in the enctype attribute of my form.
This prevents me from accessing the page fields using the regular request.getParameter.
This needs to be handled in a different way.
Here is how.
for (Iterator requestItems = upload.parseRequest(request).iterator(); requestItems.hasNext();) {
item = (FileItem) requestItems.next(); // Get each item in the request
if (!item.isFormField()) {
//handle the file data
} else {
System.out.println((String)item.getString());
}
}
Well, I'm developing a app in my cellphone that is going to connect to my PC, the problem is that everytime that I return a URLRequest to the cellphone, it shows the previous Form on the screen and not de actual one, for example this is what goes in my actionListener:
public void actionPerformed(ActionEvent ae) {
if (ae.getCommand() == guiaUtil.cSelecionar()) {
LoginRemote loginRemote = new LoginRemote();
try {
//This is the request, returns true or false, does not affect the form
loginRemote.login(tLogin.getText(), tPassword.getText());
} catch (Exception e) {
GuiaUtil.error(e);
return;
}
guiaUtil.mainApp().startMenu();
}
}
Then in the "guiaUtil.mainApp().startMenu()" I have this
public void startMenu() {
if (itemsMenu == null) {
itemsMenu = new List();
itemsMenu.setWidth(320);
itemsMenu.addItem("Sincronize Spots");
itemsMenu.addItem("Find Spots");
itemsMenu.addItem("Work");
itemsMenu.setFocus(true);
this.addComponent(itemsMenu);
this.addCommandListener(this);
this.addCommand(guiaUtil.cSelect());
Form form = new Form();
form.addComponent(itemsMenu);
}
form.show();
}
Anyway, after the request returns, it shows my Login form again, instead of showing the Menu List
Maybe what is going is that you are getting an exception, treating it with GuiaUtil.error and returning from actionPerformed without calling startMenu.
I would move guiaUtil.mainApp().startMenu() inside the try/catch block.
Not sure what happens in loginRemote.login(tLogin.getText(), tPassword.getText());
If you access the network, I would put that part in a different thread.
Inform the main thread by some kind of callback when the "remote login" is done,
you can show the menuForm from the edt then.
You have to put the following code outside the if condition.
Form form = new Form();
form.addComponent(itemsMenu);
You are having two form object. one inside if and another one outside of if. Object created inside the loop will loses the scope inside if. You are showing form object outside if. That's why, menu list screen was not displayed.