Wicket model window throw error when first open in new tab by right click and then click on model window link - wicket

When i am going to one page(A) to another page(B) using Ajax link URL show like ...?wicket:interface=:58::::#
On B page i have a link for open model window.when we direct click on link of model window its working fine but when first open link in new Tab by right click and then click on model window link its throwing an error.
I am using setResponsePage( new B(variable)) for come to another page.when i am using setResponsePage(B.class) instead of setResponsePage( new B(variable)) its working fine.
Note : I don't want to use pageparameter with bookmarkable and setResponsePage.
Error is :
org.apache.wicket.WicketRuntimeException: component listForm:group:issueList:1:editStatus not found on page com.B[id = 18], listener interface = [RequestListenerInterface name=IBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
org.apache.wicket.protocol.http.request.InvalidUrlException: org.apache.wicket.WicketRuntimeException: component listForm:group:issueList:1:editStatus not found on page com.B[id = 18], listener interface = [RequestListenerInterface name=IBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
at ...........................
... 27 more
"editStatus" is a link name on model window.
Code that i am using Class A
class A extends WebPage {
Link<String> escalated = new Link<String>("escalated") {
public void onClick() {
setResponsePage(new B(Variables));
} };
}
class B extends WebPage {
public B(variables..) {
}
final ModalWindow model = new ModalWindow("UpdateModel");
model.setContent(new C(model,variables,model.getContentId()));
item.add(new AjaxLink<Void>(**"editStatus"**) {
public void onClick(AjaxRequestTarget target) {
model.show(target);
}
}.add(new Image("edit_icon", "image/edit.png")));
}
}
class C extends Panel {
public C(.....) {
}
}

I have solved this issue.Error was relating with state of wicket component.
Use StatelessLink instead of Link.
correct code :
class A extends WebPage {
StatelessLink escalated = new StatelessLink("escalated") {
public void onClick() {
setResponsePage(new B(Variables));
} };
}
it would also removed "...?wicket:interface=:58::::#" from url.
when we used Link,AjaxLink it would maintain state.so when we open any link in new tab it would changed state on server side(change ids of component) but on client side it would remain same. so when we click any link on same page there are no information of updated ids and it would have thrown an error.

Related

Spotfire Redirecting to home after link click

Ask: Have a button that when clicked downloads a file from a folder on the server and remains on the current page.
Current state and problem: I have a CustomWizardPromptControlPage that writes a simple button to the HTMLTextWriter. The onclick event for the button fires off a window.open(urlToDocument, '_blank'). By doing the button with the onclick it does actually allow me to download the file, however the parent page redirects to the home page.
Already tried: href - didn't download the file and redirected me to the home page. form submit - didn't do anything.
If anyone can give me some insight as to why Spotfire does this and what I can do to stop it from happening it would be greatly appreciated
--Follow up with working code sample for comments request
namespace ACompanyName.SpotFire.ExportWithFilters
{
public class ExportWithFiltersWebPromptControl : CustomWizardPromptControl
{
public ExportWithFiltersWebPromptControl(ExportWithFiltersFileSettings settings)
{
this.AddPage(new ExportWithFiltersPage(settings));
}
private class ExportWithFiltersPage : CustomWizardPromptControlPage
{
private readonly ExportWithFiltersFileSettings _settings;
public ExportWithFiltersPage(ExportWithFiltersFileSettings settings) : base("Export with Filters")
{
_settings = settings;
}
protected override void OnGetContentsCore(HtmlTextWriter writer)
{
var domain = "https://dev.AURL.com";
var filename = _settings.ExportWithFiltersFileInfo.Name;
var fullFilePath = string.Format("{0}/{1}/{2}", domain, "Exports", filename);
writer.WriteLine("Download Export with Filters", fullFilePath);
}
protected override void OnGetScriptsCore(StringBuilder builder)
{
}
protected override void OnLeavePageCore(FormData data)
{
}
protected override bool OnValidatePromptCore(FormData data)
{
return true;
}
}
}
}
Turned out that Spotfire didn't like putting <button> into the page. Swapped it out with an hyperlink with a target of blank and it worked like a charm. If a button is still desired, stylized div should do the trick.

Link to last version of stateful page

I have a number of stateful pages with some state for each page. For example each page has a form that was submitted.
How can I organize a menu with links to last versions of these stateful pages? Should I store anywhere (may be in the session) reference to appropriate object for each page? If I use
onClick() { setResponsePage(MyPage.class); }
than I lose the previous state of the page. I want to link to last state of the page.
Each time the page is rendered store the page's id in the session.
int pageId = pageInstance.getPageId();
A list or stack data structure could be used to hold the identifiers.
You can implement the navigation menu using a repeater (RepeatingView or such) that creates a new link for each page id in the session.
In the link's click handler you can redirect the user as follows:
Page pageInstance = (Page) new PageProvider(pageId, null).getPageInstance();
setResponsePage(pageInstance);
pageId = this.getPageId(); // get current version of lets say a HomePage
//OnClick for Link
public void onClick()
{
WebPage homePageInstance =
(WebPage) new PageProvider(HomePage.pageId, null).getPageInstance();
setResponsePage(homePageInstance);
}
});
I make it passing int previousId parameter via constructor :
#MountPath(value = "editSomethingPage")
public class TestPage extends WebPage {
int previousPageId = 0;
public TestPage(int previousPage) {
super();
this.previousPageId = previousPage;
}
#Override
protected void onInitialize() {
super.onInitialize();
add(new Link("goBack") {
#Override
public void onClick() {
if (previousPageId != 0) {
setResponsePage((Page) AuthenticatedWebSession.get().getPageManager().getPage(previousPageId));
} else {
setResponsePage(PreviousPage.class);
}
}
});
}
}
It prevents creation of new page instance and keeps all states of page made by user.

Apache Wicket bookmarkable url added one additional parameter to the link, why?

my map is
mountPage("/page/#{code}/#{name}", Page.class);
but when I click on the link
localhost/page/10/toy?2
wicket add also one parameter like a counter, when I refresh the page I have
localhost/page/10/toy?3
why?
This is because your page are stateful, Wicket manages its own states to your page by appending this "counter". This way, when your user navigate backward using its browser built-in functionnality, the page is displayed has it has been previously.
If you don't want such a parameter in your URL, you'll need to dig out and eradicate every stateful component in your pages.
You can create
public class MountedMapperWithoutPageComponentInfo extends MountedMapper {
public MountedMapperWithoutPageComponentInfo(String mountPath, Class<? extends IRequestablePage> pageClass) {
super(mountPath, pageClass, new PageParametersEncoder());
}
#Override
protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
}
#Override
public Url mapHandler(IRequestHandler requestHandler) {
if (requestHandler instanceof ListenerInterfaceRequestHandler) {
return null;
} else {
return super.mapHandler(requestHandler);
}
}
}
and map page on Application class like this
mount(new MountedMapperWithoutPageComponentInfo("/page/#{code}/#{name}", Page.class));

How to implement content assist's documentation popup in Eclipse RCP

I have implemented my own editor and added a code completion functionality to it. My content assistant is registered in source viewer configuration like this:
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
if (assistant == null) {
assistant = new ContentAssistant();
assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
assistant.setContentAssistProcessor(getMyAssistProcessor(),
MyPartitionScanner.DESIRED_PARTITION_FOR_MY_ASSISTANCE);
assistant.enableAutoActivation(true);
assistant.setAutoActivationDelay(500);
assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
}
return assistant;
}
When I press Ctrl + SPACE inside the desired partition, the completion popup appears and works as expected.
And here's my question.. How do I implement/register a documentation popup that appears next to completion popup? (For example in java editor)
Well,
I'll answear the question myself ;-)
You have to add this line
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
to the configuration above. Then when creating CompletionProposals, the eighth (last) parameter called additionalProposalInfo of the constructor is the text, which will be shown in the documentation popup.
new CompletionProposal(replacementString,
replacementOffset,
replacementLength,
cursorPosition,
image,
displayString,
contextInformation,
additionalProposalInfo);
More information about can be found here.
Easy, isn't it.. if you know how to do it ;)
For the styled information box (just like in JDT).
The DefaultInformationControl instance need to received a HTMLTextPresenter.
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
public class MyConfiguration extends SourceViewerConfiguration {
[...]
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
if (assistant == null) {
[...]
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
}
return assistant;
}
#Override
public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
return new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell parent) {
return new DefaultInformationControl(parent,new HTMLTextPresenter(false));
}
};
}
}
Proposals can then use basic HTML tags in the string from method getAdditionalProposalInfo().
public class MyProposal implements ICompletionProposal {
[...]
#Override
public String getAdditionalProposalInfo() {
return "<b>Hello</b> <i>World</i>!";
}
}

How to avoid View specific code in my ViewModel

My application has a menu option to allow the creation of a new account. The menu option's command is bound to a command (NewAccountCommand) in my ViewModel. When the user clicks the option to create a new account, the app displays a "New Account" dialog where the user can enter such data as Name, Address, etc... and then clicks "Ok" to close the dialog and create the new account.
I know my code in the ViewModel is not correct because it creates the "New Account" dialog and calls ShowDialog(). Here is a snippet from the VM:
var modelResult = newAccountDialog.ShowDialog();
if (modelResult == true)
{
//Create the new account
}
how do i avoid creating and showing the dialog from within my VM so I can unit test the VM?
I like the approach explained in this codeproject article:
http://www.codeproject.com/KB/WPF/XAMLDialog.aspx
It basically creates a WPF Dialog control that can be embedded in the visual tree of another window or usercontrol.
It then uses a style trigger that causes the dialog to open up whenever there is content in the dialog.
so in you xaml all you have to do is this(where DialogViewModel is a property in you ViewModel):
<MyControls:Dialog Content = {Binding DialogViewModel}/>
and in you ViewModel you just have to do the following:
DialogViewModel = new MyDialogViewModel();
so in unit testing all you have to do is:
MyViewModel model = new MyViewModel();
model.DialogViewModel = new MyDialogViewModel();
model.DialogViewModel.InputProperty = "Here's my input";
//Assert whatever you want...
I personally create a ICommand property in my ViewModel that sets the DialogViewModel property, so that the user can push a button to get the dialog to open up.
So my ViewModel never calls a dialog it just instantiates a property. The view interprets that and display a dialog box. The beauty behind this is that if you decide to change your view at all and maybe not display a dialog, your ViewModel does not have to change one bit. It pushes all the User interaction code where it should be...in the view. And creating a wpf control allows me to re-use it whenever I need to...
There are many ways to do this, this is one I found to be good for me. :)
In scenarios like this, I typically use events. The model can raise an event to ask for information and anybody can respond to it. The view would listen for the event and display the dialog.
public class MyModel
{
public void DoSomething()
{
var e = new SomeQuestionEventArgs();
OnSomeQuestion(e);
if (e.Handled)
mTheAnswer = e.TheAnswer;
}
private string mTheAnswer;
public string TheAnswer
{
get { return mTheAnswer; }
}
public delegate void SomeQuestionHandler(object sender, SomeQuestionEventArgs e);
public event SomeQuestionHandler SomeQuestion;
protected virtual void OnSomeQuestion(SomeQuestionEventArgs e)
{
if (SomeQuestion == null) return;
SomeQuestion(this, e);
}
}
public class SomeQuestionEventArgs
: EventArgs
{
private bool mHandled = false;
public bool Handled
{
get { return mHandled; }
set { mHandled = value; }
}
private string mTheAnswer;
public string TheAnswer
{
get { return mTheAnswer; }
set { mTheAnswer = value; }
}
}
public class MyView
{
private MyModel mModel;
public MyModel Model
{
get { return mModel; }
set
{
if (mModel != null)
mModel.SomeQuestion -= new MyModel.SomeQuestionHandler(mModel_SomeQuestion);
mModel = value;
if (mModel != null)
mModel.SomeQuestion += new MyModel.SomeQuestionHandler(mModel_SomeQuestion);
}
}
void mModel_SomeQuestion(object sender, SomeQuestionEventArgs e)
{
var dlg = new MyDlg();
if (dlg.ShowDialog() != DialogResult.OK) return;
e.Handled = true;
e.TheAnswer = dlg.TheAnswer;
}
}
The WPF Application Framework (WAF) shows a concrete example how to accomplish this.
The ViewModel sample application shows an Email Client in which you can open the “Email Account Settings” dialog. It uses dependency injection (MEF) and so you are still able to unit test the ViewModel.
Hope this helps.
jbe
There are different approaches to this. One common approach is to use some form of dependency injection to inject a dialog service, and use the service.
This allows any implementation of that service (ie: a different view) to be plugged in at runtime, and does give you some decoupling from the ViewModel to View.