GWT save data in TextBox by clicking a Button - gwt

I have a simple application containing a TextBox and Button by using GWT, the point is that when I write something in the TextBox and click the Button the data in the TextBox would be saved in database, here is what I wrote, but I don't know how to save it by clicking:
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//method to save the data
}
});

You need to implement a remote service to be used by your application.
GWT uses RemoteService to do server tasks. A remote service is an interface defining your remote methods, it must be placed in the shared classpath of your application. The remote service interface is implemented by the servercode to execute the actual action you want it to perform.
The client uses a so called Async interface, that is in the client class path and ususally generated for you by the IDE or a special compiler target. In mvn projects, you will find them in the target/generated-sources folder.
Those async interfaces that are implemented by the compiler and instantiated by your code using GWT.create().
The async interface has the same methods as the remote service interface, but all methods have a changed signature. Instead of a return value, they expose an AsyncCallback<T> handler, that is used to call your code after the remote call on the server returned. <T> is the return type of your method in the RemoteService interface on the server.
The proper way to save your data, is to have a presenter class or activity class that will have an instance of the async service. The activity/presenter will take the value from the view and send it to the remote service for storing into database.
In your click handler, you use the activity to save the data, or the presenter attaches himself as the click handler to the view.
There is plenty of code samples showing the principle in gwtproject.org tutorials section.
The call in the presenter/activity will use an async callback class like so:
backendSvc.saveData( textString, new AsyncCallback<Response>() {
void onSuccess(Response r) {
view.showMessage("Response saved");
}
void onError(Throwable caught) {
view.showError("Ouch", caught);
}
}
The view should not call the backend directly, this will lead to a mess, if your application grows.
I suggest, you check tutorials on the gwtproject website and really try to understand the flow of events. The concept is fundamental to understand the GWT way.

Please elaborate your question..I understood like how to save value in database from text box if it so then ,
Get the Value from Text Box
Send the Value to Server either by using any one of the following approach
RPC
RequestBuilder
Push the Data(value) to database
Example:
services.saveData(textValue, new AsyncCallback<Response>() {
public void onSuccess(Response response) {
showMessage("Saved Successfully");
}
public void onError(Throwable error) {
showError("Failed to Save Data");
}
};

If you are asking how to connect GWT to your server database, this link might be helpful.
XML: The bridge between GWT and PHP
Simply take the input value from textbox and post it to your server

Related

Architecture for stateful MVVM application with self contained client-server code and IoC container

I have an application which has multiple screens and talks to a WCF web service. I am using SimpleInjector for my favourite IoC container, and Caliburn Micro for MMVM with WPF.
I have a separate class implementation of ITransportClient that controls the connection to the web service and sends and receives messages.
The application has the following states:
Start up and initialisation of the application.
Display the login form.
Login form performs connection to chat server with ITransportClient.Login(username, password).
If login successful show a new MainWindow view, if failed prompt user for credentials again.
When logged in, MainWindow controls messages sent and received to the WCF service.
When connection is lost with the server (notified by ITransportClientCallback.OnTransportDisconnected), or when the user clicks logout, the Login form is displayed again.
With the technology I have available and this being my first MVVM project I have the following architectural and design questions:
What design pattern should I use to control showing a separate log in screen, then the main screen when connected, and revert back to the login screen when the connection has been lost?
Who should control the connection state of the chat application and where would this code sit? Would this state sit in the bootstrapper class?
Could I have the ITransportClient registered as a persistence instance scope, and have multiple forms control when required by injecting in to the ViewModel that required it (i.e. both the login form and the main window form)?
The ITransportClient interface is below:
public interface ITransportClientCallback
{
string OnReceivedMessage();
void OnTransportDisconnected();
}
// transport interface that client calls
public interface ITransportClient
{
bool SendLogin(string username, string password);
void SendLogout();
void SendMessage();
void RegisterCallback(ITransportClientCallback applicationHostCallback);
}
Along with the Caliburn.Micro bootstrapper code using SimpleInjector:
public class SimpleInjectorBootstrapper : Caliburn.Micro.Bootstrapper
{
private Container container;
protected override void Configure()
{
this.container = new Container();
this.container.Register<IWindowManager, WindowManager>();
this.container.Register<IEventAggregator, EventAggregator>();
this.container.Register<IAppViewModel, AppViewModel>();
this.container.RegisterSingle<ITransportClient, Transport.WCF.TransportClient>();
}
protected override object GetInstance(Type serviceType, string key)
{
return this.container.GetInstance(serviceType);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
base.OnStartup(sender, e);
var appViewModel = this.container.GetInstance<IAppViewModel>();
var windowManager = this.container.GetInstance<IWindowManager>();
windowManager.ShowWindow(appViewModel);
}
}
What design pattern should I use to control showing a separate log in
screen, then the main screen when connected, and revert back to the
login screen when the connection has been lost?
In alot of cases, MVVM project is accompanied with a "mediator" or "messenger". All View Models can interact between each other through this mechanism by subscribing and publishing messages. All VMs would subscribe to "UserLoggedOutMessage" and do the necessary response (i.e. change its visual state to readonly, or not show anything at all). A separate bootstrapper can also "redirect" the user to the login screen.
Who should control the connection state of the chat application and
where would this code sit? Would this state sit in the bootstrapper
class?
One approach is to have an abstraction for the state of the app - this is equivalent to the HTTPContext.Current variable in asp.net. You could have a Session object which has a CurrentState read-only property with corresponding Login(), Logout(), SendMessage() methods which acts as a state machine. All View Model would then subscribe to the events as soon as the state of the app changes - again through the Mediator. The Session object can be a static variable on the bootstrapper, or a singleton injected to all VMs via the IoC.
Could I have the ITransportClient registered as a persistence instance
scope, and have multiple forms control when required by injecting in
to the ViewModel that required it (i.e. both the login form and the
main window form)?
that's definitely the idea. in most MVVM project, you would want to have a single instance of the dependencies injected to the VMs. This allow for more efficient memory use and also allow a clean object oriented model (as opposed to a procedural immutable transaction scripts).
Having said that, if this was an attempt to check for the "application state" I would change the level of the abstraction to something higher e.g. IApplicationStateMachine or IUserSession. This way if you want to ever support multiple user in one application instance, you could in theory have multiple instances of the IUserSession objects.

Can I do url rewriting for Salesforce public rest services?

I have the following restful service in Salesforce:
#RestResource(urlMapping='/testRest')
global class testRest {
#HttpPost
global static void doPost(){
// do some stuff
}
}
I have this class accessible to a site, so that anyone (unauthenticated) can hit this service at https://mydomain.force.com/sitename/services/apexrest/testRest
I want to make this service accessible to the user in a shorter url, I'd like them to be able to hit the service at https://mydomain.force.com/sitename/rest/testRest
Is there a way to do this? I tried using Site.UrlRewriter with the following code:
if(url.toLowerCase().startsWith('/rest/testrest')){
return new PageReference('/services/apexrest/testRest');
But this redirects me to a FileNotFound page. Am I missing something here?

How to prevent code to execute after firing of history token in gwt?

I am working on gwt2.3 application with gwtp framework.In this application I am have one login (index) page which is bind by the client module.
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.login);
Now after successfull login a new name token name user page is fired.
History.newItem(NameTokens.userconsole,true);
Now I have my history handler like below:
public class NameTokenHandler implements ValueChangeHandler {
#Override
public void onValueChange(final ValueChangeEvent<String> event) {
System.out.println("Nothing to do");
}
}
And I added to History like below in entry point class:
History.addValueChangeHandler(new NameTokenHandler());
Now as I have overridden the onValueChange method & I have left it blank.
So when application loads first or any other name token fires it should invoke onValueChange first
and as there no code in this method nothing should be load.
But in application it is working fine. All the name tokens are firing successfully even after there is no code in onValueChange. I am not getting how to prevent the firing of history token?
Please help me out.
Thanks in advance.
So when application loads first or any other name token fires it should invoke onValueChange first and as there no code in this method nothing should be load.
If you are using gwtp History ValueChangeHandler will not prevent or enable navigation to a particualr part of your application. That is all handled with PlaceManager.
After some googling I came to know about place manager.
I am adding_ a change handler to History. All the change handlers that
have been added already are still there. In particular, the one in GWTP's
PlaceManagerImpl constructor.
If you really want to prevent some history events from being handled by
GWTP, I would suggest that, in your custom PlaceManager, you
override onValueChange(...), intercept the tokens you want to block, and
call the parent's onValueChange for the tokens you want GWTP to handle
normally.

GWT Fragment Identifier works in hosted mode and not in compiled mode (Tomcat)

I have this code below which works when running in hosted/debug mode however it does not work when deployed in Tomcat.
History.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
// call update model, and eventually app will show the appropriate view...
}
});
I code above responsibility is to catch the event when user type something like this in the browser:
http://http://127.0.0.1:8888/index.html?gwt.codesvr=127.0.0.1:9997#user123
Works well in hosted mode, but when deployed in Tomcat and accessed via the browser:
http://127.0.0.1:8888/index.html#user123
it shows blank page.
EDIT: Unless gwt app is first loaded and typing FI works.
Please read this: What is need History.fireCurrentHistoryState() in GWT History?
When you load http://127.0.0.1:8888/index.html#user123 for the first time, you registered your history handler after the history event has already happened. If you reload the page then it will fire.
You need to call History.fireCurrentHistoryState() after you registered the history handler to "re-fire" the event.

GWT. Set url without submit

Can i change url(set parameter) without submit?
I found this method
http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/user/client/Window.Location.html#replace%28java.lang.String%29
but it submit page. All GWT state will be lost.
If you want to change something that is not in the hash, for example you want to change a parameter in the URL, you can do it like this!
private void someMethod() {
String newURL = Window.Location.createUrlBuilder().setParameter("someParam", "someValue").buildString();
updateURLWithoutReloading(newURL);
}
private static native void updateURLWithoutReloading(String newUrl) /*-{
$wnd.history.pushState(newUrl, "", newUrl);
}-*/;
Then you could register a function that handles the user using the back and forward browser buttons as demonstrated here.
Why are you trying to do this? Generally speaking, GWT apps don't change pages - thus they are normally SPAs (single page applications)
When you load a new page from a server, you will lose the state on that page. You can change the hash part of the URL as that won't return to the server, like this:
String newURL = Window.Location.createUrlBuilder().setHash("newhash").buildString();
Window.Location.replace(newURL);
However, if you're going to do this, I would recommend taking a look at GWT's MVP framework, which has built in support for managing locations using hash tokens.
http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html
$wnd.history.pushState(newUrl, "", newUrl);
Works nicely in HTML5-browsers. Not in IE8 or IE9!