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
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
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...
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;
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>
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" : "";
}
// ...
}