gwt file upload code - gwt

I want to upload file in my application and want to set path where the files should be saved after uploading in my local system.I am using the following code but on the submit button getting no response while clicking.Please tell me the code which works fine for the file upload in gwt.
[code]
public class FormPanelExample implements EntryPoint {
public void onModuleLoad() {
// Create a FormPanel and point it at a service.
final FormPanel form = new FormPanel();
form.setAction("/myFormHandler");
// Because we're going to add a FileUpload widget, we'll need to set the
// form to use the POST method, and multipart MIME encoding.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
// Create a panel to hold all of the form widgets.
VerticalPanel panel = new VerticalPanel();
form.setWidget(panel);
// Create a TextBox, giving it a name so that it will be submitted.
final TextBox tb = new TextBox();
tb.setName("textBoxFormElement");
panel.add(tb);
// Create a ListBox, giving it a name and some values to be associated with
// its options.
ListBox lb = new ListBox();
lb.setName("listBoxFormElement");
lb.addItem("foo", "fooValue");
lb.addItem("bar", "barValue");
lb.addItem("baz", "bazValue");
panel.add(lb);
// Create a FileUpload widget.
FileUpload upload = new FileUpload();
upload.setName("uploadFormElement");
panel.add(upload);
// Add a 'submit' button.
panel.add(new Button("Submit", new ClickListener() {
public void onClick(Widget sender) {
form.submit();
}
}));
// Add an event handler to the form.
form.addFormHandler(new FormHandler() {
public void onSubmit(FormSubmitEvent event) {
// This event is fired just before the form is submitted. We can take
// this opportunity to perform validation.
if (tb.getText().length() == 0) {
Window.alert("The text box must not be empty");
event.setCancelled(true);
}
}
public void onSubmitComplete(FormSubmitCompleteEvent event) {
// When the form submission is successfully completed, this event is
// fired. Assuming the service returned a response of type text/html,
// we can get the result text here (see the FormPanel documentation for
// further explanation).
Window.alert(event.getResults());
}
});
RootPanel.get().add(form);
}
}
Thanks
Amandeep

Now, I remember.. There's a bug in the FormPanel code that causes form.submit() not to work, when the type of the form is changed from the default (don't know if it's fixed yet in any release of GWT). If you create a "native" submit button like this:
HTML nativeSubmitButton new HTML("<input class='gwt-Button' type='submit' value='" + buttonText + "' />")
It will submit the form.
The disadvantage is that you cannot use any Button methods on this object, since it's a simple HTML wrapper. So disabling the button on submit (to avoid accidental double submit, and to give feedback that the form is actually submitting) won't work .
I've created a utility class for this purpose myself called DisableableSubmitButton that is essentially a FlowPanel with one HTML button like the above, and one gwt Button that is disabled, and some logic to toggle each of them visible. Since it cannot modify the actual enabled status of the HTML button all submit handlers must ask this class if it's "enabled" or not and cancel the event if it is. If you're interested in this implementation, i could share it with you (I don't want to flood stackoverflow with code unless you are interested).

Related

Change form item editor type dynamically in smartGwt

I have a smartGwt DynamicForm with a FormItem
FormItem item = createTextItem();
form.setFields(item);
After creating the and setting fields, I need to dynamically set an editor type for the item. I have to do it dynamically based on some conditions.
I'm calling item.setEditorType(new PasswordItem());
just after I call form.editRecord(record); so that the new editor type should appear. But it is not working.
Tried calling item.redraw() and is not working.
My goal is to set the editor type dynamically based on the record that is edited.Please help.
Try with Custom Data Binding (see page 23 for more details). What you tried won't work, AFAIK, because the ListGridField has already been created with the initial custom editor, and it can't be changed dynamically with setEditorCustomizer.
Take a look at this sample (based on this showcase demo), which does what you want to do to the password field when it is being edited in the DynamicForm, and after the changes have been saved (please pay attention to the comments, as without some of these settings it won't work as expected):
public void onModuleLoad() {
final DataSource dataSource = ItemSupplyLocalDS.getInstance();
final DynamicForm form = new DynamicForm();
form.setIsGroup(true);
form.setNumCols(4);
form.setDataSource(dataSource);
// very important for not having to set all fields all over again
// when the target field is customized
form.setUseAllDataSourceFields(true);
final ListGrid listGrid = new ListGrid();
listGrid.setWidth100();
listGrid.setHeight(200);
listGrid.setDataSource(dataSource);
listGrid.setAutoFetchData(true);
IButton editButton = new IButton("Edit");
editButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
form.editRecord(listGrid.getSelectedRecord());
// when the button is clicked, the password field is rendered with
// a plain text item editor, for easy verification of values entered
FormItem passwordField = new FormItem("passwordFieldName");
passwordField.setEditorProperties(new TextItem());
form.setFields(passwordField);
form.markForRedraw();
}
});
IButton saveButton = new IButton("Save");
saveButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
form.saveData();
// when the button is clicked, the password field is rendered with
// a password editor, for added privacy/security
FormItem passwordField = new FormItem("passwordFieldName");
passwordField.setEditorProperties(new PasswordItem());
form.setFields(passwordField);
form.markForRedraw();
}
});
VLayout layout = new VLayout(15);
layout.setWidth100();
layout.setHeight100();
layout.addMember(listGrid);
layout.addMember(editButton);
layout.addMember(form);
layout.addMember(saveButton);
layout.draw();
}

Wicket form missing data on submit

I have a ModalWindow which has a form, which has a TabbedPanel, which has two AbstractTabs which, on which there is a DataTable on each of them, with input elements.
So: ModalWindow > Form > TabbedPanel --> Tab1 (Panel) > DataTable (there are two tabs)
Within the ModalWindow, I added to the form 3 buttons, like the following:
// save button
final GbAjaxButton save = new GbAjaxButton("save") {
private static final long serialVersionUID = 1L;
#Override
public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
System.out.println("Saving something... ");
}
};
I can see the data being sent via POST to the backend, but I can't seem to be able to access any of the fields in the DataTables.
Some parts for the code are:
tabA = new AbstractTab("Tab Name") {
public Panel getPanel() {
return new SomeNewPanel(panelId,<somedata>); // <-- this has the DataTable with inputs
}
}
Form form = new Form("formNameInHtml");
form.add(new TabbedPanel("htmlName", tabs);
I would really appreciate some insight on this problem.
Thanks.
From ModalWindow javadoc, "If you want to use form in modal window component make sure that you put the modal window itself in another form (nesting forms is legal in Wicket) and that the form on modal window is submitted before the window get closed."
Wicket automatically adds a form outside the modal window, so if you want to use a second form inside you should override org.apache.wicket.markup.html.form.Form#isRootForm() and have it return true.

How to don't validate form with Ajax buttons

I have a problem with validation on form actually sub-form.
In my website I have some kind of table and "Add row" button (BlockingAjaxSubmitLink).
When I try add let say 2 rows, I get validation error (because row in this table has Required=True parameter) and I can't add another row. I tried use simple AjaxLink but it doesn't have reference to form in onClick method and when I complete some rows and click "Add row" this data get lost.
I want to enable validation only after "save" button click.
Any idea how to deal with this problem?
I do something like you want using an AjaxLink.
My AjaxLink:
private AjaxLink addNewRow = new AjaxLink("addNewRow") {
#Override
public void onClick(AjaxRequestTarget target) {
MyEntityObject newTableRowObject = new MyEntityObject(irrelevantParameter);
entityObjectTableService.createNewRowInDB(newTableRowObject );
target.add(listViewContainer);
}
};
In this code the listViewContainer is a WebMarkupContainer which contains a ListView holding the table rows.
When i click this AjaxLink a new object representing a row in my table is added to the database and then the container containing the ListView is being refreshed refreshing the ListView and the new empty object is being fetched from the DB and shown as a new row in my table at the end.
Depending on your structure maybe you are looking after disabling validation using setDefaultFormProcessing(true); - http://ci.apache.org/projects/wicket/apidocs/6.x/org/apache/wicket/markup/html/form/AbstractSubmitLink.html#setDefaultFormProcessing%28boolean%29
For now I write some kind of hack
First I set
addKnowledgeLink.setDefaultFormProcessing(false);
and next
BlockingAjaxSubmitLink<Object> addKnowledgeLink = new BlockingAjaxSubmitLink<Object>(
"link_knowledge_add") {
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
ChangeDataForm.this.process(this);
/* some code */
target.add(form.get(MY_CONTAINER_ID));
}
(...)
and my hack...
//HACK
public void process(IFormSubmitter object){
if (!isEnabledInHierarchy() || !isVisibleInHierarchy())
{
return;
}
// run validation
validate();
/*if (hasError())
{
// mark all children as invalid
markFormComponentsInvalid();
// let subclass handle error
callOnError(object);
}
else
{*/
// mark all children as valid
markFormComponentsValid();
// before updating, call the interception method for clients
beforeUpdateFormComponentModels();
// Update model using form data
updateFormComponentModels();
// validate model objects after input values have been bound
onValidateModelObjects();
if (hasError())
{
callOnError(object);
return;
}
// Form has no error
delegateSubmit(object);
//}
}
and I ovveride one method
#Override
protected void onError(){
super.onError();
this.updateFormComponentModels();
}
I know it is ugly solution but I couldn't figure out anything better..
And I couldn't shutdown feedback messages

GWT FormPanel - avoid redirecting

I have a FormPanel which sends a POST Request to a server with:
form.setAction("http://servlet_address")
The problem is, after firing submit(), the formpanel redirects the page to "http://servlet_address" (where the request was sent), but this action is not desired, as the servlet just receives data. How can I avoid this redirection behaviour?
It is a standard HTML form behavior. When you submit the form you actually send form data to server using HTTP request. "Method" attribute allows you to define where to encode form data (URL or HTTP request body). And result of form submitting (HTTP request) will be displayed in your browser.
As I understand you want to override this behavior. There are several ways to do it. All of them requires you to process form data manually and generate correct request. It means that you can not submit your form. There are 2 common patterns for GWT to communicate with server:
GWT-RPC ( https://developers.google.com/web-toolkit/doc/latest/tutorial/RPC )
Request Factory ( https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory )
Both of them are easy to use if you have Java Server back-end. If you need to submit your data to non-java we-server than Request Factory only can be used and it is complicated task.
See the following code it works fine without redirecting (this code work properly in an onModuleLoad() method):
final FormPanel formPanel = new FormPanel();
formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
formPanel.setMethod(FormPanel.METHOD_POST);
VerticalPanel verticalPanel = new VerticalPanel();
verticalPanel.add(new Label("Username"));
TextBox userid = new TextBox();
userid.setName("username");
verticalPanel.add(userid);
verticalPanel.add(new Label("Password"));
PasswordTextBox passwd = new PasswordTextBox();
passwd.setName("pass");
verticalPanel.add(passwd);
verticalPanel.add(new Button("Submit", new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
formPanel.submit();
}
}));
formPanel.add(verticalPanel);
formPanel.setAction("submit"); // e.g. servlet URL
// Add an event handler to the form.
formPanel.addSubmitHandler(new FormPanel.SubmitHandler() {
public void onSubmit(SubmitEvent event) {
// This event is fired just before the form is submitted. We can
// take
}
});
formPanel.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
public void onSubmitComplete(SubmitCompleteEvent event) {
// When the form submission is successfully completed,
// this event is fired.
Window.alert(event.getResults());
}
});
RootPanel.get().add(formPanel);
Have a nice time.

How do you rebuild the GWT History stack?

I have a larger application that I'm working with but the GWT History documentation has a simple example that demonstrates the problem. The example is copied for convenience:
public class HistoryTest implements EntryPoint, ValueChangeHandler
{
private Label lbl = new Label();
public void onModuleLoad()
{
Hyperlink link0 = new Hyperlink("link to foo", "foo");
Hyperlink link1 = new Hyperlink("link to bar", "bar");
Hyperlink link2 = new Hyperlink("link to baz", "baz");
String initToken = History.getToken();
if (initToken.length() == 0)
{
History.newItem("baz");
}
// Add widgets to the root panel.
VerticalPanel panel = new VerticalPanel();
panel.add(lbl);
panel.add(link0);
panel.add(link1);
panel.add(link2);
RootPanel.get().add(panel);
History.addValueChangeHandler(this); // Add history listener
History.fireCurrentHistoryState();
}
#Override
public void onValueChange(ValueChangeEvent event)
{
lbl.setText("The current history token is: " + event.getValue());
}
}
The problem is that if you refresh the application, the history stack gets blown away. How do you preserve the history so that if the user refreshes the page, the back button is still useful?
I have just tested it with Firefox and Chrome for my application and page refresh does not clear the history. Which browser do you use? Do you have the
<iframe src="javascript:''" id='__gwt_historyFrame' style='position:absolute;width:0;height:0;border:0'></iframe>
in your HTML?
GWT has catered for this problem by providing the History object. By making a call to it's static method History.newItem("your token"), you will be able to pass a token into your query string.
However you need to be aware that any time there is a history change in a gwt application, the onValueChange(ValueChangeEvent event){} event is fired, and in the method you can call the appropriate pages. Below is a list of steps which i use to solve this problem.
Add a click listener to the object that needs too call a new page. In handling the event add a token to the history.(History.newItem("new_token").
Implement the ValueChangeHandler in the class that implements your EntryPoint.
Add onValueChangeHandler(this) listener to the class that implements the EntryPoint. Ensure that the line is add in the onModuleLoad() method (it is important it is added in this method) of the class that implements the EntryPoint(pretty obvious ha!)
Finally implement onValueChange(ValueChangeEvent event){ //call a new page } method.
That's it