jsf - commandLink doesn't call bean method - forms

My h:commandLink doesn't work. I've got a navigation rule in the faces-config.xml and a String method doSave() in my bean. I don't know why It only reloads the page without jumping into the doSave() method.
jsf-page
<h:form id="surveyForm">
<div class="srvButton">
<h:commandLink action="#{surveyBean.doSave}" value="#{msg.srvButton}" />
</div>
</h:form>
faces-config
<navigation-rule>
<from-view-id>/pages/survey.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/pages/surveyFinish.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
bean
public String doSave() {
// Kundendaten speichern
saveCustomer();
return "success";
}
I cleaned the content in the jsf-page for a better view, but all you need to know is the form and button I think.

I just solved my problem. I replaced all my c:if tags with ui:fragment tags and it worked! Maybe, this could interest you c:foreach vs ui:repeat
Thanks #matthandy for his effort..

Related

redirect to list page after clicking on add button in JSF and html page [duplicate]

I have three XHTML pages;
index.xhtml
page_1.xhtml
page_2.xhtml
In the index.xhtml page, I have a commandButton which sends the user to page_1.xhtml. All this is done in the navigation rule in faces-config.xml.
How would I redirect the user to page_2.xhtml from the index.xhtml using another commandButton assuming that both commandButtons' actions are linked to a backing Java class?
Just bind the buttons to different action methods which each return a different outcome.
<h:commandButton value="Go to page 1" action="#{bean.goToPage1}" />
<h:commandButton value="Go to page 2" action="#{bean.goToPage2}" />
with
public String goToPage1() {
// ...
return "page_1";
}
public String goToPage2() {
// ...
return "page_2";
}
Navigation cases are not necessary. JSF 2.0 supports implicit navigation. The navigation outcome can just be the path/filename of the desired target view. The file extension in the outcome is optional.
If you don't necessarily need to perform any business action on navigation, or you can do it in the (post)constructor of the backing bean of the target page instead, then you can also just put the outcome value in the action directly.
<h:commandButton value="Go to page 1" action="page_1" />
<h:commandButton value="Go to page 2" action="page_2" />
A <h:commandButton> will however not perform a redirect, but a forward. The enduser won't see the URL being changed in the browser address bar. The target page isn't bookmarkable. If you can, I'd suggest to use <h:button> instead.
<h:button value="Go to page 1" outcome="page_1" />
<h:button value="Go to page 2" outcome="page_2" />
Or if you really need to invoke a business action, but would like to perform a real redirect, then append faces-redirect=true as query string to the outcome value.
public String goToPage1() {
// ...
return "page_1?faces-redirect=true";
}
public String goToPage2() {
// ...
return "page_2?faces-redirect=true";
}
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?
You can also do this, in any part of your code to be redirected to "example.xhtml"
ExternalContext ec = FacesContext.getCurrentInstance()
.getExternalContext();
try {
ec.redirect(ec.getRequestContextPath()
+ "/faces/jsf/example.xhtml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Add two navigation cases as shown below. In the action methods, return outcomes corresponding to the buttons.
<navigation-rule>
<from-view-id>index.html</from-view-id>
<navigation-case>
<from-outcome>page1</from-outcome>
<to-view-id>page_1.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>page2</from-outcome>
<to-view-id>page_2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>

javafx how to reuse custom component in different FXML

After several searching i could find any solution for this and would like to ask for help. Thanks in advance.
I have a FXML with HBox with several buttons (new, show, edit). Each button has onAction method. It is used in other 2 FXML (A & B) and I would like to reuse such HBox.
Other 2 FXML (A, B) have some controls (tableview, ...)
This is what i tried:
1) import HBox FXML is not an option as changes must be performed in all FXML (a & b).
2) include using fx:id: I will have a dedicated controller for HBox and I would like to have controls and methods on A, B controllers.
3) include using fx:root: I think this is the way to achieve this but i have errors.
Navigation.fxml file:
<fx:root spacing="5.0" type="HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button fx:id="btnOpen" mnemonicParsing="false" onAction="#onActionOpen" text="Open" />
<Button fx:id="btnSave" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionSave" text="Save" />
<Separator visible="false" HBox.hgrow="ALWAYS" />
<Button fx:id="btnClose" layoutX="62.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionClose" text="Close" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</fx:root>
Pane1controller.java:
public Pane1Controller() {
System.out.println("Pane1_Controller");
NavigationController nav = new NavigationController();
System.out.println("NavigationController ... done");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("pane1.fxml"));
System.out.println("setting root");
fxmlLoader.setRoot(this);
System.out.println("setting controller");
fxmlLoader.setController(this);
try {
System.out.println("loading fxml");
pnlMain = fxmlLoader.load();
System.out.println("done");
} catch (IOException exception) {
System.out.println("exception");
pnlMain = null;
throw new RuntimeException(exception);
}
System.out.println("done");
} ...
}
using setRoot ....
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root
value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run573616745/Testfx_fxroot.jar!/testfx_fxroot/pane1.fxml
removing setroot
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run2127482879/Testfx_fxroot.jar!/testfx_fxroot/Navigation.fxml
Which is the correct way to achieve this?
Thanks for your support.
BR
This must be caused due to the <fx:root> tag
I've created a sample project for the above task. Visit GitHub for the project. Clone it and refer. I think you can understand it. Link

MVC form not submitting to correct action

I have a simple partial with a form inside which is used as a search bar.
#using (Html.BeginForm("Details", "Projects", FormMethod.Get))
{
<div class="row" style="margin-bottom: 20px;">
<div class="col-lg-3 pull-right">
<input type="search" class="form-control" placeholder="Search Code" id="projectSearch" name="code" />
</div>
</div>
}
This should post to my Projects Controller Details Action, however this isn't happening, and I believe this because of the [Route] attribute that is applied to the action, as when I comment this out, the form posts correctly. However I want to use the [Route] attribute.
The action looks like this:
[HttpGet]
[Route("{code}/Details")]
public ActionResult Details(string code)
{
if (code == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
...
return View(viewModel);
}
When the attribute is in use the form will post to this url:
/Projects/Details?code=PP61
which doesn't map to the correct action. Instead I get a resource cannot be found error.
The expected/desired url should look like
/Projects/PP61/Details
This works fine if I create a Url.Action or browse to the URL, so I know this action works, however it doesn't work with a form post. Any ideas why?
Thanks.
Change [HttpGet] to [HttpPost] on the controller and FormMethod.Get to FormMethod.Post in the view.
I have one solution to the problem, it doesn't however answer why this wasn't working in the first place. I have created a separate action which is for the search bar to POST to, this action then redirects to the GET action which I was trying to reach in the first place.
[HttpPost]
public ActionResult ProjectSearch(string code)
{
if (code != "")
{
return RedirectToAction("Details", new { code });
}
else
{
return RedirectToAction("Index");
}
}
This now works correctly, but I would still love to know why this didn't work to begin with if any body has any ideas. Cheers.

dynamic value to uibinder in gwt

I am new to GWT and trying to making a page which is trying to inherit a composite widget but the value of the composite widget is dynamic.
My main page is somehting like:
.....
.....
<g:Button>Open composite widget</g:button>
.....
.....
which is opening an another popup panel which is something like:
.....
<table>
<tr><td>Top: <myCompany:userMeasurementUnit/> </td></tr>
<tr><td>Bottom: <myCompany:userMeasurementUnit/> </td></tr>
<tr><td>Left: <myCompany:userMeasurementUnit/> </td></tr>
<tr><td>Right: <myCompany:userMeasurementUnit/> </td></tr>
</table>
the above should show us
top (cm)
bottom (cm)
left (cm)
right (cm)
But I don't know how to pass the values from main page to custom widget i.e usermeasurementunit
<myCompany:userMeasurementUnit/>
My usermeasurementunit is something like:
UIBinder:
<htmlpanel tag="span" ui:field="unit"/>
and the composit widget is
usermeasurementunit extends Composite {
public usermeasurementunit(){
initwidget...
}
public onload() {
...
}
}
Now I want to pass any measurement unit cm or inches or meters upon clicking button. I tried it using the event bus but it didnt help because when I click the button popuppanel is not on the screen and its not catching the event. If any one of you can help me regarding this I would be really thankful as I am really struggling with this thing.
kind regards
First of all, you need to understand the object instantiation flow in GWT.
They call it "delayed binding", not "dynamic binding".
Uibinder xml file is a layout template. And the JAva source bean behind it is known in general programming terms as the "code-behind".
The role or purpose of the uibinder layout template is to off-load the laying-out (on the internet many non-English speaking programmers write "lay-outing" which, though syntax-wise amusing, is the same thing) so that the code-behind could be focused on controlling the layout's responses.
It's akin to the MVP attitude. View implementation separated from presentation control. You can write the code-behind error free without even knowing exactly the positions where those fields are laid out. You could even simply supply a template where the ui elements are not properly laid out so as to concentrate on your code-behind first. Perhaps after that. one uibinder template for mobile while another for desktop - but they can share the same code-behind.
The values displayed effected by the uibinder template is determined once-and-for-all during uibind. There is no dynamic binding of a uibinder field to the ever changing value of an object/variable declared in the code-behind.
To dynamically change/propagate the values of a uibinder field after uibind, you have to deliberately set its value in the code-behind or write a listener to detect its change.
public class Graceland {
#UiField
Label pressure;
#UiField
Button reset;
public void setPressure(int value) {
pressure.setText(value);
}
#UiHandler("reset")
void nameDoesNotMatter(ClickEvent ev) {
pressure.setText(default);
}
}
GWT.create() generates the Java source for the template during compile time. GWT.create is not a run-time function.
#UiField and #UiHandler are bound to the uifield in the template during uibind.
The role of uibind() is mostly not run-time but compile time too. Though, its finality is realised during run-time, all the javascript code and respective values to construct the objects are generated during compile time and executed once and only once during uibind at run-time.
Therefore, the intention is not to be able to completely replace the dynamic role of the code-behind but simply to free it from the task of laying-out, so that we the programmer could have a clean piece of code-behind being smudged as little as possible with the spaghetti source of the layout.
However, if you wish to "dynamically" affect the value of a uibinder field during bind time,then Ui:with is your friend.
package z.mambazo;
public class Graceland {
....
String initialPressure(){
/* "dynamically" obtain the pressure from the
* pressure gauge in the petroleum distillation stack
* during uibind
*/
}
}
Graceland.ui.xml:
<ui:UiBinder blah...blah>
<ui:with type="z.mambazo" field="zulu"/>
<g:VerticalPanel>
<g:Label
ui:field="pressure"
text="the temperature is :{zulu.initialPressure}"/>
</g:VerticalPanel>
</ui:UiBinder>
The ui:with bean does not have to be the template's code-behind. Either the ui:with bean has an no-argument constructor or you have to supply ui:with tag with attributes corresponding to the constructor arguments.
You have to take note that in order to use ui:with, the init value must be declared in the value attribute not in the tag text.
<g:Label
ui:field="pressure"
text="the temperature is : {zulu.initialPressure}"/>
Not
<g:Label ui:field="pressure">
the temperature is : {zulu.initialPressure}
</g:Label>
The second way, would simply reproduce the text as is.
However, you could also do it this way:
<g:HtmlPanel>
the temperature is :
<g:Label ui:field="pressure"
text="{zulu.initialPressure}"/>
</g:HtmlPanel>
Also, be reminded that all GWT UI Java code, even the interim generated ones, are all translated into browser Javascript. So, whatever class you reference with ui:with must be in Java source code not Java byte code. And those source code must not at any time down the calling chain call byte code.
What you need are shared resources. Here is an example:
MeasurementConstants.java:
package com.acme.client;
public class MeasurementConstants {
private final String measurementUnit;
public MeasurementConstants(String measurementUnit) {
this.measurementUnit = measurementUnit;
}
public String measurementUnit() {
return measurementUnit;
}
}
UiBinderMeasurement.java:
package com.acme.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
public class UiBinderMeasurement extends Composite {
private static UiBinderI18nUiBinder uiBinder = GWT
.create(UiBinderI18nUiBinder.class);
private MeasurementConstants constants;
interface UiBinderI18nUiBinder extends UiBinder<Widget, UiBinderMeasurement> {
}
public UiBinderMeasurement(MeasurementConstants constants) {
this.constants = constants;
initWidget(uiBinder.createAndBindUi(this));
}
#UiFactory
public MeasurementConstants getConstants() {
return constants;
}
}
UiBinderMeasurement.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with type="com.acme.client.MeasurementConstants" field="constants"></ui:with>
<g:HTMLPanel>
<table>
<tr><td><g:Label text="Top ({constants.measurementUnit}):" /> </td></tr>
<tr><td><g:Label text="Bottom ({constants.measurementUnit}):" /> </td></tr>
<tr><td><g:Label text="Left ({constants.measurementUnit}):" /> </td></tr>
<tr><td><g:Label text="Right ({constants.measurementUnit}):" /> </td></tr>
</table>
</g:HTMLPanel>
</ui:UiBinder>
Now you can call it like this:
new UiBinderMeasurement(new MeasurementConstants("cm"))

Replace marker in nested UIBinder Structure / Error handling with MVP

I am using DockLayoutPanel as my main panel.
Dependent of the menu I click I change the center-part of the DLP.
For example I change either to form1.ui.xml or to form2.ui.xml.
Both of these forms have a "marker" implemented to display an error message:
<g:HTMLPanel ui:field="messageblock"/>
I am following the MVP Pattern (I use EventBus for communication) and so far everything works great. The only thing I can't figure out is how to replace the content of messageblock. Or to be more concret how to get access to messageblock from my MainPresenter. The main idea behind this stuff is to bundle the error-handling in one presenter...
I am looking for something like
final Panel panel = DockLayoutPanel.get("messageblock");
panel.add(subwidget);
I appreciate every hint...
You could either make the Display responsible for rendering the error (make some interface with a renderError(Error) method) or make the Display return an HTMLPanel that something else can render the error into (some interface with a HTMLPanel getErrorPanel() method). The latter is closest to what you're talking about. Have Form1 and Form2 both implement HasErrorPanel and then call getErrorPanel().add(subWidget).
Here is the conclusion I came to. Maybe it helps someone else.
It's based on what Riley Lark recommended - Thanks to Riley btw.
RegistrationPresenter here is responsible for the registration process and shows a registration form to the user. The error-message should be displayed as close as possible to the place where the error occurred.
Without error http://www.mikemitterer.at/fileadmin/stacktrace_imagehosting/screenshot-778.jpg
An error occurred:
Error popped up http://www.mikemitterer.at/fileadmin/stacktrace_imagehosting/screenshot-780.jpg
Here now a rough description how I implemented this behavior:
public class RegistrationPresenter implements Presenter {
public interface Display extends StatusDisplay, HasMessageBlock {
Widget asWidget();
void setData(RegistrationTO registration);
}
private final Display display;
private final EventBus eventBus;
...
as you can see it's Display implements HasMessageBlock:
public interface HasMessageBlock {
void showMessage(Message message);
void hideMessage();
}
There exists a UIBinder-Widget MessageBlock (MessageBlock.ui.xml + MessageBlock.java)
(messageblock will be turned to invisible in it's constructor)
<g:HTMLPanel styleName="errorblock" ui:field="messageblock">
<div id="errorMsg" class="flurid">
<div class="row">
<div class="column width_15/16">
<h3><ui:msg key="errorblock.headline">An error occurred...</ui:msg></h3>
</div>
<div class="column orientation-right islink width_1/16">
<g:Image resource='{res.xgray}' ui:field="image" />
</div>
...
The Registration-Widget now includes MessageBlock
<g:HTMLPanel styleName="registration" ui:field="panel">
<div class="uniForm maxgrid700">
<h1>
<ui:msg key="registration.headline">Registration</ui:msg>
</h1>
<c:MessageBlock ui:field="messageblock"/>
<div class="ctrlHolder">
<p class="label">
<em></em>
<ui:msg key="registration.name">Name:</ui:msg>
</p>
...
Now, if someone fires a Message
eventbus.fireEvent(new MessageEvent(new MessageImpl(Message.MESSAGETYPE.ERROR, "Server Error Message")));
every Presenter which has "HasMessageBlock" for it's Display can process/display the message:
eventBus.addHandler(MessageEvent.TYPE, new MessageEventHandler() {
#Override
public void execute(final MessageEvent event) {
display.showMessage(event.getMessage());
}
});