How to keep track of history in Wicket? - wicket

When using setResponsePage(Somepage.class) or setResponsePage(new Somepage()) I want to know the page where the setResponsePage(...) is called from in the Page I'm going to.
setResponsePage in Component is final so I can't override it.
I don't want to set the current page in the next one manually like so:
Page page = new Somepage();
page.setReturnPage(new Returnable() {
#Override
public BasePage onReturn() {
// use some local final variable to create a new instance of this previous page
}
});
setResponsePage(page);
I just want it to be available. I do want to be able to manually change the "returnpage" if I want.
I tried to keep track of this using the Session but that didn't work.
I'm currently trying to figure out if this is possible using an IRequestCycleListener but I can't determine the Page I'm coming from in the RequestCycle.
Any help is appreciated!

You can design your page to take a PageReference argument in its constructor. Every Page descendant has getPageReference() method to return this for you.
public SomePage(PageReference pageRef) {
this.pageRef = pageRef;
}
Then when you need to return to the previous page you can simply call
setResponsePage(this.pageRef.getPage());

Related

WizardNewFileCreationPage order

I'm creating an Export wizard, including the possibility for the user to choose the format of the export and then to choose the location of the export with WizardNewFileCreationPage.
To do so, I've created 3 pages, one extending wizardPage with a radio to set the next page to call, and 2 others pages pending the format and extending WizardNewFileCreationPage.
It's working almost perfectly, my only problem concerns the "Finish" button, which requires to be clickable that all export format are fulfilled even if I overrided the function isPageComplete to limit the page validation only to the function validatePage.
It looks like the function validatePage doesn't valid only it's own control but also all the control implemented by the class WizardNewFileCreationPage in the Wizard.
Am I going wrong somewhere and does anybody know a solution ?
Regards,
Waldo
The WizardDialog showing the dialog drives button enablement. At various points it calls its updateButtons method. This in turn calls the Wizard canFinish method to set the Finish button state.
The default for canFinish is to call the WizardPage isPageComplete method for every page even for pages which are not currently active.
For WizardNewFileCreationPage the isPageComplete method consults the result of the validatePage method.
So you can override the Wizard canFinish method to only test the pages you care about. Or you can override the individual page isPageComplete methods to return the result you want.
So, I think my problem came from the fact I wasn't implementing canFinish method that's requires in it's default implementation that all page contained in the Wizard are fulfilled. To avoid my problematic, I did it this way :
#Override
public boolean canFinish() {
if (this.getContainer().getCurrentPage() == mainPage)
return false;
return this.getContainer().getCurrentPage().isPageComplete();
}
Note : My "mainPage" attribute is theone defining the format of the export and then the nextPage to use.
Also, I kept verifying if my page was complete this way by calling the WizardNewFileCreationPage this way :
#Override
public boolean isPageComplete() {
return this.validatePage();
}

GWTP Presenter prepareFromRequest - load data into form retrieved from event

I have been trying GWTP for the past couple of weeks and building a small project with it.
Here's the question :
I have a grid widget (attached screenshot) which shows a list of data. On selection of a checkbox of a row and clicking on Edit Request, I get into a detail page.
Since I have all the data (model) to be shown in the detail page in the summary screen presenter itself, I don't want to fetch it from the database again.
So, I did the following :
On selection and clicking edit request, I get the selected model
Make a place request to the detail page
Fire an edit event and pass the selected model as parameter.
I understand that I am doing it wrong because when I select an item and hit Edit Request, the detail page does not receive the selected item yet. It just shows a blank page with no data filled in (obviously, because the place has been reached much before the event has been fired).
Current code :
RequestModel selectedItem = getView().getGrid().getSelectionModel().getSelectedItem();
PlaceRequest placeRequest=new PlaceRequest(NameTokens.initiationedit);
getEventBus().fireEvent(new RequestEditEvent(selectedItem, PHASE_INITIATION));
placeManager.revealPlace(placeRequest);
Personally thought solution : Instead of firing an event, I could make a placerequest with a parameter of the selected item's id and then override the useManualReveal and the prepareFromRequest to fetch data fresh from database.
But is there a way I could avoid database call for the pre-existing data.
If you want to keep your current "RequestEditEvent" solution, then make sure to use #ProxyEvent (see http://code.google.com/p/gwt-platform/wiki/GettingStarted?tm=6#Attaching_events_to_proxies).
Another possibility may be to invert the direction of the event: In your details presenter, fire an event which requests data from the overview presenter.
However, when using the same data across multiple presenters, then it may be a good idea to keep the data in a central model: Create a model class (#Singleton) and inject it everywhere you need it. Then you can make a lookup (by id) from that local model instead of asking the server. In this case, you don't need any events - just the id somewhere, e.g. as a place parameter, or even as a "currentItemId" in the model.
Based on the answer by #Chris Lercher, I used the ProxyEvent. The implementation details are as follows.
In my RequestEditPresenter (the details presenter), I implemented the event handler RequestEditHandler as in
public class RequestEditPresenter extendsPresenter<RequestEditPresenter.MyView, RequestEditPresenter.MyProxy> implements RequestEditHandler{
then in the same RequestEditPresenter override the method in the RequestEditHandler as in
#Override
#ProxyEvent
public void onRequestEdit(RequestEditEvent event) {
getView().setModelToView(event.getRequestModel());
...various other initiation process...
placeManager.revealPlace(new PlaceRequest(NameTokens.initiationedit));
}
Since the Details presenter was a Place, I used the placeManager. For presenters that do not have a NameToken, just call the forceReveal() method

How can I tell from a Wicket Page object that it has changed?

Here's my scenario. I'm testing a Wicket app, and I'm parsing the page text wicktetTester.getServletResponse.getDocument as XML in order to find components with XPath. This is quite expensive, so I'd like to keep the dom4j.Document until the page changes, then rebuild it.
I know the current page - wicketTester.getLastRenderedPage but if I for example submit a form and stay on the same page, the Page object is the same object. What property of the page can I query to know that it has been re-rendered and that I need to rebuild my DOM?
public Document getDocument() {
if (tester.getLastRenderedPage() != lastPageParsed && SOME_OTHER_TEST) {
cachedDocument = parse(tester.getServletResponse().getDocument();
lastPageParsed = tester.getLastRenderedPage();
}
return cachedDocument;
}
Better see TagTester. I guess it will serve you better than XPath.

Redirect back to list on syfmony generated form?

I've generated an admin section with Propel on syfmony. When I have added an item I wish it to redirect back to the list, and not to an edit view.
In fact, I actually want to remove the edit page as for these objects only new instances are allowed - no deletions or editing.
How do I achieve this?
probably the best way to do this is to override the Create action, but for your specific case though there is easier (but no so clean) solution.
Since you don't want to use edit action you can remove it from generator.yml list actions and then override '[YOUR_ITEM]_edit' route to point to items list page.
This way when new item is added you will be redirected back to items list page (overridden edit route) and also manual try to access edit action will redirect to items list page.
What you think?
I found the best way for this is to edit the form as such:
class CouponForm extends BaseCouponForm
{
public function configure()
{
$this->getValidator('used')->setOption('required', false);
$this->getValidator('valid_until')->setOption('required', true);
$this->getValidator('created_at')->setOption('required', false);
$this->getValidator('updated_at')->setOption('required', false);
}
}
and then in the generator.yml file edit the 'edit' actions:
edit:
actions: { _list: ~ }

Showing an initially selected object in an ObjectAutoCompleteField on page load in Wicket

I've followed the Wicket by Example guide to get the ObjectAutoCompleteField working, and it does so quite nicely.
I have a huge problem, though, and that is to show an initially set object in the field when the page loads. The object is retrieved from a model I use for the form where the ObjectAutoCompleteField is used. Changing the ObjectAutoCompleteField changes the model attribute it is "connected" to, and any subsequent changes in the field shows the appropriate label in its place, just not the initial one when the page loads—the only thing that shows is the edit link (to get to the autocomplete functionality).
I've looked around in the documentation for the ObjectAutoCompleteBuilder but haven't found any corresponding method to even set the initial value explicitly on page load.
I finally managed to find a solution by looking through the classes relating to ObjectAutoCompleteField.
The ObjectAutoCompleteField is constructed by the build method in ObjectAutoCompleteBuilder. So, by calling the readOnlyRenderer method on the builder, creating a new ObjectReadOnlyRenderer creating a label inside its getObjectRenderer, I got the ObjectAutoCompleteField to render a preselected object on page load.
ObjectAutoCompleteBuilder<Author, Long> builder = new ObjectAutoCompleteBuilder<Author, Long>(provider);
builder.readOnlyRenderer(new ObjectReadOnlyRenderer<Long>() {
public Component getObjectRenderer(String id, IModel<Long> pModel, IModel<String> pSearchTextModel) {
return new Label(id, new PropertyModel<Author>(model, "author"));
}
});
One would think that this was the standard behaviour, but now I know for future reference.