p:dialog show message or reload - primefaces

In a jsf 2.2 primefaces application, I have a link that opens a dialog that has a form. On submission of the form, I want to close the dialog and reload the current page or show an error on the dialog itself.
The managedbean method is a void method that sets the status using RequestContext - addcallbackparam.
As the dialog submission happens using actionlistener and the remainder of the operation happens in javascript, I can’t quite handle this.
I followed the example provided on primefaces website.
https://www.primefaces.org/showcase/ui/overlay/dialog/loginDemo.xhtml
Can anyone provide any information.

Here is something you can try without using addcallbackparam and javascript..
On validation success, hide the dialog & reload page or on failure, set a warning message as below from managed bean:
public void login(ActionEvent event) {
if(username != null && username.equals("admin") && password != null && password.equals("admin")) {
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("PF('dlg').hide()");
pageReload();
} else {
dialogWarning = "Validation failed";
}
}
public void pageReload() {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
try {
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
} catch (IOException ex) {
//catch and log IO exception here
}
}
In the xhtml dialog set dynamic=true and display the warning message as below and add this id to the update attribute in the Login component.
<h:outputLabel id="warnMsgLabel" value="#userLoginView.dialogWarning" />

Related

Handling exceptions from a Method in a dialog that can be model and modeless

This is an extract of a method in CDialog class:
void CDialog1::Method()
{
try
{
// Snip
}
catch (CException* e_)
{
const gsl::not_null<CException*> e{ e_ };
e->ReportError();
e->Delete();
}
catch (const _com_error& e)
{
AfxMessageBox(e.ErrorMessage(), MB_OK | MB_ICONERROR);
}
}
There is no issue with this function when it is ran from an instance of the modal dialog.
But, in another part of my application I load the same dialog as a hidden modeless dialog. And I call the same function. Eg:
void CDialog2::SomeTask()
{
if (m_pDialog1 != nullptr)
{
m_pDialog1->Method();
}
}
In this second scenario there is an issue with Method when an error is encountered. CDialog2 needs to handle the display of the errors from what I understand, because the hidden instance will appear if it shows a messagebox.
How do I get around this? Note that CDialog1 has a boolean method IsHiddenMode so we know if we are running it as a model or not.
What is the easy way to change my methods to cater for both scenarios:
When CDialog1 calls the method in it's modal dialog.
When CDialog2 calls the method using the modeless member variable of CDialog1.
I tend to overcomplicate my explanations so I hope it makes sense.
I adjusted the Method to detect if the dialog was in hidden mode and throw the exception, eg:
catch (const _com_error& e)
{
if (IsHiddenMode())
{
throw;
}
else
{
AfxMessageBox(e.ErrorMessage(), MB_OK | MB_ICONERROR);
}
}
That way, the calling dialog could catch and handle with a try / catch block.

CDHtmlDialog crashes while navigating to pdf after navigating to google

Navigate from www.google.com page to pdf file causes exception in CDHtmlDialog.
This exception is not present while navigating from pages other than google (e.g. www.wikipedia.org).
Overridden "OnBeforeNavigate", "OnNavigateComplete" and "OnDocumentComplete" events. Then found that, in issue scenario, while loading pdf file "OnNavigateComplete" is called twice.
The calling sequence is as follows: OnBeforeNavigate=>OnNavigateComplete=>OnNavigateComplete
As "OnNavigateComplete" is called without calling "OnBeforeNavigate", "m_spHtmlDoc" in CDHtmlDialog does not become NULL and validation causes assertion in "CDHtmlDialog::OnNavigateComplete".
ASSERT(m_spHtmlDoc==NULL);
Header:
class CClientAppDlg : public CDHtmlDialog
cpp:
CClientAppDlg::CClientAppDlg(CWnd* pParent /*=nullptr*/)
: CDHtmlDialog(IDD_CLIENTAPP_DIALOG, 0, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CClientAppDlg::OnBnClickedNavigate()
{
UpdateData(TRUE);
Navigate(m_csNavURL); // Get URL from edit box and navigate
UpdateData (FALSE);
}
void CClientAppDlg::OnBeforeNavigate( LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnBeforeNavigate(pDisp, szUrl);
}
void CClientAppDlg::OnNavigateComplete( LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnNavigateComplete(pDisp, szUrl);
}
void CClientAppDlg::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR szUrl)
{
CDHtmlDialog::OnDocumentComplete(pDisp, szUrl);
}
Why "OnNavigateComplete" is called twice and causing exception?
Why does it happen only while navigating from google page?

getting no such element exception message

i am using eclipse juno and testing the application actitime,which has a check box in login page "keepLoggedInCheckBox"
The HTML source of it,
<input type="checkbox" title="Do not select if this computer is shared"
id="keepLoggedInCheckBox" value="on" name="remember">
I am trying locate the check box "keepLoggedInCheckBox" by using ,
WebElement check = driver.findElement(By.id("keepLoggedInCheckBox"));
But getting this error,
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
Unable to locate element:
{"method":"id","selector":"keepLoggedInCheckBox"}
i tried with xpath (//input[#id='keepLoggedInCheckBox']) ,also getting same error.
please help me, to solve this.
I have faced the same problem. The DOM looses the reference to the element in question. It can either be StaleStateReferenceException or NoSuchElementException. There are two ways to deal with the situation.
(Though my solution is in Java. The underlying concept is the same. )
By using the the following method, you can try clicking an element. If exception is thrown then catch the exception and try to click again until the element is present:
public boolean retryingFindClick(By by) {
boolean result = false;
int attempts = 0;
while(attempts < 2) {
try {
Actions action = new Actions(driver);
WebElement userClick = wait.until(ExpectedConditions.presenceOfElementLocated(by));
action.moveToElement(userClick).click().build().perform();
driver.findElement(by).click();
result = true;
break;
} catch(StaleElementReferenceException e) {
System.out.println("StaleElementReferenceException");
}
catch(NoSuchElementException e) {
System.out.println("No Such Element Found");
}
attempts++;
}
return result;
}
Please try this. I have added implicitlyWait which will allow your DOM content to load.
Note: Please replace Your URL with the exact URL.
WebDriver driver=new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("Your URL");
driver.findElement(By.xpath("//*[#id='keepLoggedInCheckBox']")).click();

Put wizard navbar on top position

I'm working with a wizard component. The navbar is in the botton but my boss wants me to put it in the top of the wizard,I thought that it was an attribute or tag to do it straight forward but I have been reviewing the documentation and I should be wrong (I only found the showNavBar tag).
Is there a way to do it without css or jquery? (we have some problems in the application setting css when working with some components so I would like to avoid it).
Thank you very much
You can achieve this in either of the two ways:
1 - Extending the WizardRenderer
By extending the WizradRenderer you can change the order of the encoding.
In the original Renderer the encodeContent(facesContext, wizard); is called before encodeNavigators(facesContext, wizard); so it's pretty much simple, extend you custom renderer, change the order of the calls.
public class ExNavWizardRenderer extends org.primefaces.component.wizard.WizardRenderer{
#Override
protected void encodeMarkup(FacesContext facesContext, Wizard wizard) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
String clientId = wizard.getClientId(facesContext);
String styleClass = wizard.getStyleClass() == null ? "ui-wizard ui-widget" : "ui-wizard ui-widget " + wizard.getStyleClass();
writer.startElement("div", wizard);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", styleClass, "styleClass");
if(wizard.getStyle() != null) {
writer.writeAttribute("style", wizard.getStyle(), "style");
}
if(wizard.isShowStepStatus()) {
encodeStepStatus(facesContext, wizard);
}
// encode the navigators before the content
if(wizard.isShowNavBar()) {
encodeNavigators(facesContext, wizard);
}
encodeContent(facesContext, wizard);
writer.endElement("div");
}
}
Update your faces-config.xml
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.WizardRenderer</renderer-type>
<renderer-class>com.projectPackage.ExNavWizardRenderer</renderer-class>
</renderer>
</render-kit>
2 - jQuery
In your document.ready you can change the DOM, for example this would do the same as the Renderer:
$('.ui-wizard-step-titles').after($('.ui-wizard-navbar'))

Redirect after Login MyWSAT

I've been testing the example code here http://mywsat.codeplex.com/
In their example they have different buttons to login to either the admin pages or members page using seperate links
However, I'm trying to use a single link to a landing page and after the user logs in redirect to the relevant page using codebehind. The landingpage requires login but all roles can view this page set in the rules.
landingpage.aspx:
protected void Page_Load(object sender, EventArgs e)
{
string redirectPath;
string pagePath = Request.AppRelativeCurrentExecutionFilePath;
if (Page.User.IsInRole("Administrator"))
{
//Admin
redirectPath = "~/admin/Default.aspx";
if (redirectPath != pagePath)
{
Response.Redirect(redirectPath);
}
}
else if (Page.User.IsInRole("Member"))
{
//Members
redirectPath = "~/members/Default.aspx";
if (redirectPath != pagePath)
{
Response.Redirect(redirectPath);
}
}
else if (Page.User.IsInRole("Trial"))
{
//Trial
redirectPath = "~/trial/Default.aspx";
if (redirectPath != pagePath)
{
Response.Redirect(redirectPath);
}
}
else
{
//Non member
redirectPath = "~/Default.aspx";
if (redirectPath != pagePath)
{
Response.Redirect(redirectPath);
}
}
}
The problem is the Page_Load event fires straight away and then launches login-with-captcha.ascx after the event has fired.
So then I moved the code to the login form login-with-captcha.ascx.cs to redirect after e.Authenticated = true; but it just redirects back to login-with-captcha.ascx in an endless loop
login-with-captcha.ascx.cs:
// Next, determine if the user's username/password are valid
if (Membership.ValidateUser(loginUsername, loginPassword))
{
e.Authenticated = true;
//tried redirecting from here based on role!
}
else
//............
How can I redirect from the landing page after the user is validated? I suspect it may have something to do with postback but need some help
Can you try adding the following as the first line within your Page_Load to see if it helps? This will likely prevent the endless loop issue if it's being caused by something that triggers a postback event, like a button click.
if (IsPostBack) return;