How to clear the RootPanel before displaying the next view - java

I am using GWT Java and I am trying to remove the PayPal Donate button (i.e., clear the RootPanel), which is part of an HTML form, when I move from the LoginView to another view. I found that I should use:
RootPanel.get("payPalDonate").clear();
RootPanel.get().clear();
RootPanel.get().getElement().setInnerHTML("");
This does clear the form so it does not appear on the next view; however, when the next view is displayed the buttons, hyperlinks and the browser back button on the view do not work.
The code is in the :
private void checkWithServerIfSessionIdIsStillLegal(String sessionID) {
rpc = (DBConnectionAsync) GWT.create(DBConnection.class);
ServiceDefTarget target = (ServiceDefTarget) rpc;
String moduleRelativeURL = GWT.getModuleBaseURL() + "MySQLConnection";
target.setServiceEntryPoint(moduleRelativeURL);
AsyncCallback<Account> callback = new AuthenticationHandler<Account>();
rpc.loginFromSessionServer(callback);
}
class AuthenticationHandler<T> implements AsyncCallback<Account> {
#Override
public void onFailure(Throwable caught) {
RootPanel.get().add(new LoginView());
}
#Override
public void onSuccess(Account result) {
if (result == null) {
RootPanel.get().add(new LoginView());
} else {
//if (result.getLoggedIn()) {
RootPanel.get().clear();
//RootPanel.get().add(new SelectPersonView());
RootPanel.get().add(new LoginView());
//} else {
//RootPanel.get().add(new LoginView());
//}
}
}
}
public void onValueChange(ValueChangeEvent<String> event) {
RootPanel.get("payPalDonate").clear();
RootPanel.get().clear();
RootPanel.get().getElement().setInnerHTML("");
//Get the historyToken value
String historyToken = event.getValue();
//Check the historyToken
if (historyToken.startsWith("!"))
historyToken = historyToken.substring(1);
if (historyToken.length() == 0) {
//Initial entry
RootPanel.get().clear();
RootPanel.get().add(new LoginView());
} else if (historyToken.equals("login")) {
RootPanel.get().clear();
RootPanel.get().add(new LoginView());
} else if (historyToken.equals("goToVideo")) {
RootPanel.get().clear();
Window.Location.replace("https://www.youtube.com/user/GlyndwrBartlett");
} else if (historyToken.equals("goToMetawerx")) {
RootPanel.get().clear();
Window.Location.replace("https://www.metawerx.net/");
} else if (historyToken.equals("goToPrivacy")) {
RootPanel.get().clear();
RootPanel.get().add(new SecurityAndPrivacyView());
} else if ...
In the LoginView:
initWidget(verticalPanel);
RootPanel.get("payPalDonate");
In the html:
<div style="margin:auto" id="payPalDonate">
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="image" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1">
</form>
</div>

Typically in GWT the RootPanel is never cleared. When you start your app, you pass a container to the RootPanel, and then all the views are added to and removed from that container.
Personally, I use Activities and Places pattern for all of my apps. This link offers an example of how to change views within a main container.

I am reading the link provided by Andrei. In the meantime I found the issues were being cased by:
RootPanel.get().getElement().setInnerHTML("");
I tried:
RootPanel.getBodyElement().removeChild(RootPanel.get("payPalDonate").getElement());
However, this cased the same issue. In the end I found this https://groups.google.com/forum/#!topic/google-web-toolkit/zVvY39blkY4
So I replaced the offending code with:
RootPanel.get("payPalDonate").setVisible(false);
And I placed the code in the LoginView just before I pass control to another view. Not the most elegant; however, it works until I digest the information provided by Andrei.

Related

Function keeps on removing documents from repeat control

I have a xp:repeat control with a list of entries. For each entry I have defined a button to remove the back-end document from the database:
<xp:button value="Delete" id="button2">
<i class="fa fa-trash"> </i>
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<![CDATA[#{javascript:employeeBean.remove(obj.unid)}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
This works fine although I notice an odd behavior: when I refresh the page (F5 in browser) I get a message: Confirm Form Resubmission. In case I select Confirm another entry is removed from the list.
This process continues as long as I press F5 and refresh the page. How can I stop this?
The remove method is not rocket-science:
public void remove(String id) {
try {
Document doc;
openDatabaseAndView();
if (id != null) {
doc = view.getDocumentByKey(id, true);
} else {
doc = null;
}
if (doc != null) {
doc.remove(true);
} else {
//message to user
}
closeDatabaseAndView();
} catch (NotesException e) {
e.printStackTrace();
}
}
I placed the repeat control within a panel and set a partial refresh on this panel from the Delete button...
F5 with form resubmition in fact repeats last request (delete) that executes button click again, and again...
Take a look at "POST/GET" pattern: https://stackoverflow.com/a/18821569/206265

How can my MVC listener distiguish between different buttons

This is my first time trying the MVC design pattern, and I'm trying to figure out how my controller class can tell, when a different button is pressed, and how it can then pass it on to model
public void addController(ActionListener controller){
System.out.println("View : adding controller");
btnGo.addActionListener(controller);
btnBack.addActionListener(controller);
}
That is how I send it to the controller:
public void actionPerformed(java.awt.event.ActionEvent e){
System.out.println("Controller: acting on Model");
model.actionGo();
}
I have only managed to be able to perform one action.
You can use if cases in the listener to differ the buttons etc.
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnGo){
//perform action when btnGo clicked
}
if (e.getSource() == btnBack){
//perform action when btnBack clicked
}
}
can you give us some additional information in terms of context?
for example I use spring and I can do something like this:
#RequestMapping(value = "/updateAcerAccount", method = RequestMethod.POST)
public String updateAcerUser(#ModelAttribute("userModel") UserViewBean bean, #RequestParam(required = false) String submitType, HttpServletRequest request, Model model) {
if (submitType != null && "extend".equals(submitType))
{
// do something on extend
return "targetPage";
}
else {
//dosomething else on submit
return "targetPage2";
}
}
with submittype being associated to these two buttons in an html page..
<button type="submit" class="btn btn-danger" name="submitType" id="saveUser" value="extend">Resend Link</button>
<button type="submit" class="btn btn-success" name="submitType" id="saveUser" value="submit">Submit Decision</button>
hence give us some context, it's a webapp, a "desktop" application? what technology you use? ..
worst case scenario you can go with determining method branch based on the "originator" of the call, but really.. that's not something i'm overly a fan of...

sending a list of checked boxes from view to controller in play framework java

I have a view with the checkboxes
#for((jc)<-jobcategoryList) {
<input type="checkbox" name="jobcategory.id" value="#jc.id">#jc.name<br>
}
I just want to send this list of checked checkboxes to my controller.But on doing this
public class JobAdController extends Controller {
public static Result save() {
Form<Jobads> jobadsFormData = jobadsForm.bindFromRequest();
if (jobadsFormData.hasErrors()) {
System.out.println("Error in form");
return badRequest();
} else {
Jobads jads= jobadsFormData.get();
List<Jobcategories> jadsList= jads.getJobcategory();
System.out.print("\nLength is:"+jadsList.size());// always prints Length is:0
}}
}
where Jobads and Jobcategory are my models.
My Jabads.java model
public class Jobads extends Model {
#ManyToMany
private List<Jobcategories> jobcategories;
}
My problem is that whenever i submit my view form with the checkboxes(given above).My console prints Length is:0
When i tried to change my view to
#for((jc,index)<-jobcategoryList.zipWithIndex) {
<input type="checkbox" name="jobcategory[index]" value="#jc">#jc.name<br>
}
and submit my form the controller an [[NumberFormatException: For input string: "index"]] is generated on the first line of controller.
How can I send this checked boxes to my controller.
Thanks
Use:
#for(jc <- jobcategoryList) {
<input type="checkbox" name="jobcategories[]" value="#jc.id">#jc.name<br>
}
or
#for((jc,index) <- jobcategoryList.zipWithIndex) {
<input type="checkbox" name="jobcategories[#index]" value="#jc.id">#jc.name<br>
}
and in your form class:
public List<Long> jobcategories;

Tapestry 5, jQuery UI Dialog and close action

Using tapestry5-jquery and Dialog component, ¿How do I implement a close action for the parent dialog?. I mean a button that executes some code and then close parent dialog without changing of page.
This is the javascript only version of what I'm doing:
<div id="container">
¿Are you sure to delete selected items?
</div>
$('#container').dialog({
modal : true,
buttons:[{
text: "Yes",
click: function() {
//Perform action here, then close dialog.
$(this).dialog("close");
}
},{
text: "No",
click: function() {
//Only close dialog
$(this).dialog("close");
}
}
}]
});
But I need to use Tapestry 5 tags and java class methods:
<t:jquery.dialog t:clientId="delDialog">
¿Are you sure to delete selected items?
<input t:type="submit" t:id="delYes" value="Yes"/>
<input t:type="submit" t:id="delNo" value="No"/>
</t:jquery.dialog>
Java class:
public class UserAdmin {
#OnEvent(component = "delYes", value = EventConstants.SELECTED)
void delYesClicked(){
//Delete selected items
}
#OnEvent(component = "delNo", value = EventConstants.SELECTED)
void delNoClicked(){
//Close dialog
}
}
Thanks.
You could do something like this if the clientId is always the same (i.e. 'delDialog')
#Inject
private AjaxResponseRenderer ajaxResponseRenderer;
protected void addCloseDialogCommand() {
ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
#Override
public void run(JavaScriptSupport javascriptSupport) {
javascriptSupport.addScript("$('#delDialog').dialog('close');");
}
});
}
...and call the method in your event handler:
#OnEvent(component = "delNo", value = EventConstants.SELECTED)
void delNoClicked() {
addCloseDialogCommand();
}
This behavior could be implemented using a mixin that you apply on any element you want.
Suggested mixin:
public class DialogButtonHandler {
#Parameter(value = "dlgId", defaultPrefix = BindingConstants.LITERAL)
private String dlgId;
#Inject
private JavaScriptSupport javaScriptSupport;
#InjectContainer
private ClientElement element;
#AfterRender
public void afterRender() {
javaScriptSupport.addScript(
"$('#%s').click(function(){$('#%s').dialog('close');});",
element.getClientId(), dlgId);
}}
Markup:
<t:jquery.dialog t:clientId="delDialog">
¿Are you sure to delete selected items?
<input t:type="submit" t:id="delYes" value="Yes" />
<input t:type="submit" t:id="delNo" value="No" t:mixins="dialogButtonHandler" t:dlgId="delDialog"/>
</t:jquery.dialog>

h:commandLink conditional target

I have a h:commandLink :
<h:commandLink value=""
actionListener="#{controller.authenticateAccount}"
style="text-decoration: none;"
target="#{controller.userNameGiven ? '_parent' : '' }">
<img src="../images/Profile/authenticateCPButton.gif" border="0" style="padding-left: 2px;"/>
</h:commandLink>
Now controller.userNameGiven is a boolean field and is set to true if username given and otherwise set to false. The h:commandLink is present in a iframe and prior to this the target was set to _parent and then if the username is present then it was redirecting to a page in the same parent window but in other case the iframe was rendered in the parent page which is clearly a bug. Now after the target validation the redirected page is opening in that iframe, which is undesirable. What I am doing wrong?
Thanks and regards.
Edit 1:
I have changed the target to:
target="#{controller.target}"
where:
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
and
if(this.userName != null && this.userName.trim().length()>0) {
target = "_parent";
FacesContext.getCurrentInstance().getExternalContext().redirect("./somepage");
} else {
target = "";
}
But its still not working and the url somepage is opening in the iframe.
Move the logic into a bean method:
public class Controller
{
// ...
public boolean isUserNameGiven () { /* snip */ }
public String getFooTarget()
{
return this.isUserNameGiven() ? "_parent" : "";
}
// ...
}

Categories

Resources