ADF Jdeveloper Refresh Parent Form on Popup close - oracle-adf

I want to refresh(update few fields) on my parent form when OK button is clicked on Poup Dialog. But it does not refresh the fields. I have also set partialTriggers for the fields with Popup Id.
My Jdeveloper version is 11.1.1.7
Thanks
Umer Farooq

All you need is linking the OK button action (or action listener) property with a call through an EL to a method provided on a managed bean. Then, in it you should refresh either each component or just the form/parent component keeping all of them(by registering it's bind into a partial target of the ADF context). The method should be similar to this example:
public String refresh() {
AdfFacesContext.getCurrentInstance().addPartialTarget(formToRefresh);
return null;
}
private RichPanelFormLayout installDisable; //this should be the binding to the JSF form
public void setInstallDisable(RichPanelFormLayout installDisable) {
this.installDisable = installDisable;
}
public RichPanelFormLayout getInstallDisable() {
return installDisable;
}

I would need to see what you implemented in your code in order to provide you the "best" solution overall - as theres multiple ways to implement a dialog in a popup. However, here's a couple options depending on how your Popup Dialog is programmed:
Dialog Listener - use this if you use the built-in buttons of a dialog box. You'll need a managed bean for your jspx/jsf page. Create a Dialog Listener on your managed bean that is on your Dialog box. See below for a example of a dialog listener.
public void myDialogListener(DialogEvent dialogEvent) {
if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.yes)) {
// do something...
} else if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.no) {
//do something...
}
}
Return Listener - if you're running a task flow as a popup dialog, on your button, then add a ReturnListener to your page's managed bean. This fires whenever a your popup/dialog is closing.
public void myReturnListener(ReturnEvent returnEvent) {
//do something...
}
Otherwise, i'd add a an ActionListener to your manual button as Endrik suggests.
Now for refreshing your components, use this method in your managed bean, i use it all the time in my projects:
public void refreshComponent(UIComponent comp) {
RequestContext rContext = RequestContext.getCurrentInstance();
rContext.addPartialTarget(comp);
}
To use it, you need to bind your Form's UI components to a managed bean. Then feed in the UI Component's bean property into the method.
For example, below will refresh a Rich Output Text that i have bound to a managed bean:
private RichOutputText myOutputText;
public void refreshMyStuff() {
refreshComponent(myOutputText);
}
Have a good one.

Related

add pull2refresh to tabs in codenameone

i have added the following codes for pull2refresh but the run method is not called. I have tested for form and its ok for form. How to make it workable for tabs so that I can update all tab at once . and I have pull2refresh of form for whole for refresh.
findTabs1(f).getContentPane().addPullToRefresh(new Runnable() {
#Override
public void run() {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//
}
});
Tab doesn't have contentPane but TabbedPane.
To add pullToRefresh to a tab, you should add it to the container you added to the tab and it must be scrollable-Y.
Instead of findTabs1(f).getContentPane().addPullToRefresh do findMyContainerInsideTab().addPullToRefresh

Wicket - Inter-session communication or Create new Request(Cycle) manually

I have some wicket panel store in a static Hashmap from different sessions, i want to do some like if some panel notifies the map, then the map notifies all other panel.
for example:
public class PanelMap{
private static Map<Long, List<MyPanel>> map = new HashMap<Long, List<MyPanel>>();
public static void subscribe(Long id, MyPanel panel){
if (!map.containsKey(id)){
map.put(id, new ArrayList<MyPanel>());
}
map.get(id).add(panel);
}
}
public static void notify(Long id, String notification){
if (map.containsKey(id)){
List<MyPanel> panels = map.get(id);
for(MyPanel panel : panels){
panel.newNotification(notification);
}
}
}
}
In Panel, newNotification(String notification) i want to send request to server and refresh my panel in browser.
public void String newNotification(String notification){
// do some business logic depends on notification
onMyRequest();
}
i've made some search among wicket behavior source files and about i found in AbstractDefaultAjaxBehavior i tried to make my own onRequest method inside my wicket panel as follows
private void onMyRequest(){
AjaxRequestTarget target = ((WebApplication)getApplication()).newAjaxRequestTarget(getPage());
target.add( _some_wicket_components_ );
RequestCycle.get().scheduleRequestHandlerAfterCurrent(target);
}
but all i did is some Ajax error in Wicket Ajax Debug about
Wicket.Ajax.Call.processComponent: Component with id _containerdiv_ was not found while trying to perform markup update.
ERROR: Cannot find element with id: _someComponentIdOnPanel_
(those components are exist)
How could i send my own request to server (or how can i get valid AjaxRequestTarget to update my components? )
Update: I need inter-session communication.
To update panels on different user's sessions, you obviously can't use the current AjaxRequestTarget as this in a way represents a single communication between the server and the requesting user of which another user's Browser has no way of knowing. (Very very basically spoken)
You could either use an AjaxSelfUpdatingTimerBehavior to poll for updates. This would generate new AjaxRequestTarget for every user at regular intervals that you can use to attach changed panels to. It's a very basic and simple implementation that will most likely impact your systems performance and generate quite some traffic.
The other way would be to use something like Atmosphere, which is supported by Wicket-Atmosphere (quickstart can be found here) and has some examples over at the wicket-library.com, but that's all I know about this.
Use Wicket event bus system. Have a look to the "Wicket events infrastructure" chapter of the free Wicket guide.
First you need to create one class to encapsulate the notification and the AjaxRequestTarget and pass them using the events infrastructure.
private class Notification {
private String message;
private AjaxRequestTarget target;
... constructor, getters, setters...
}
Then the panels that want to recive the event have to override onEvent method, something like this:
public void onEvent(IEvent<?> event) {
if (event.getPayload() instanceof Notification) {
Notification notification = (Notification) event.getPayload();
... do whatever you want before updating the panel ...
// Update the panel
notification.getTarget().add(this);
}
}
All the components will recive all the events that are send using Wicket events infrastructure. So you can send the event from any other panel using one method like this
protected void sendMessage(String message, AjaxRequestTarget target) {
send(getSession(), Broadcast.BREADTH, new Notification(message, target));
}
Remember that if you want to update the components using AJAX, you need to set setOutputMarkupId(true). And if it's a component that can be hidden and you want to make it visible using AJAX, then you need to set setOutputMarkupPlaceholderTag(true).

close login form after entering correct username and pass

I want to the login form be closed after entering correct use pass and show the main form
if (isValidateUser == true)
{
HomePage homepage = new HomePage();
homepage.Show();
this.Close();
}
but after this code all of application is closed .
can you help me?
Here is my solution:
You start HomePage and on the OnLoad() method override show the login form
public partial class HomePage : Form
{
public HomePage()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var dlg=new LoginForm();
dlg.StartPosition=FormStartPosition.CenterScreen;
if(dlg.ShowDialog()==DialogResult.OK)
{
userStatusLabel.Text=dlg.UserName;
}
else
{
this.Close();
}
}
}
The login form needs to expose the login information
public string UserName { get { return usrText.Text; } }
and the [OK] button have the DialogResult property set to DialogResult.OK and similarly with the [Cancel] button. And make sure the user cannot press ok until the password is valid.
You didn't tell too much, so I'll make some suppositions.
I suppose this is the code from LoginForm. I also suppose that you call Application.Exit() in the handler for the Close event for the form. That's what is closing your application. You should flag someone (like using a bool and setting it to true before calling Close()) that the form should just close and not call Application.Exit().
From MSDN on Form.Close Method
When a form is closed, all resources created within the object are
closed and the form is disposed. You can prevent the closing of a form
at run time by handling the Closing event and setting the Cancel
property of the CancelEventArgs passed as a parameter to your event
handler. If the form you are closing is the startup form of your
application, your application ends.
You can use the Hide() method to hide the current form instead of closing it.

How to share data resources between widgets in GWT

I am using GWT and AppEngine for a project. I would like to know how can I share data (ArrayList objects)between widgets, so I could centralize the logic and reduce the number of RPC calls to the server.
I have thought of two ways, but I don't know which is better:
1) When I instantiate the widget, I pass the ArrayList object as a parameter, although I don't know how to do that because the widget gets instantiated with :
ThisAppShell shell = GWT.create(ThisAppShell.class);
2) By using a mechanism like eventBus
http://www.dev-articles.com/article/Gwt-EventBus-(HandlerManager)-the-easy-way-396001
When the user loads the application,after the login process is complete, I would like to download a list of employees which should be available for all widgets. This should all be done in the onModuleLoad() method. I would like to download them all at startup because I would like to implement some sort of caching mechanism. For example, I want to have 2 ArrayList instances:
- emplListOnStart which is populated when the application is loading
- emplListChanges, an array on which the user will make modifications from inside widgets.
After the user has finished making the changes (he presses the "Save" button), the two arrays will be compared, the differences will be saved in appengine (via RPC) and also updated in emplListOnStart.
This is the code for the EntryPoint class:
public class ThisApp implements EntryPoint {
ThisAppShell shell = GWT.create(ThisAppShell.class);
LoginServiceAsync loginService = GWT.create(LoginService.class);
private ArrayList<Employee> emplListOnStart;
private ArrayList<Employee> emplListChanges;
public void onModuleLoad() {
RootLayoutPanel.get().clear();
RootLayoutPanel.get().add(shell);
loginService.isAuthenticated(new AsyncCallback<UserDto>() {
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
public void onSuccess(UserDto result) {
//Here I should load the emplListOnStart list;
}
});
shell.getLogoutLink().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
loginService.logout(new AsyncCallback() {
public void onFailure(Throwable caught) {
}
public void onSuccess(Object result) {
//Here the user will get logged out
}
});
Window.Location.assign("");
}
});
}
}
And here is the code for the widget:
public class ThisAppShell extends Composite {
private static ThisAppShellUiBinder uiBinder = GWT
.create(ThisAppShellUiBinder.class);
interface ThisAppShellUiBinder extends UiBinder<Widget, ThisAppShell> {
}
#UiField
Anchor logout_link;
#UiField
StackLayoutPanel stackLPanel;
#UiField
TabLayoutPanel tabLPanel;
public ThisAppShell() {
initWidget(uiBinder.createAndBindUi(this));
initializeWidget();
}
public void initializeWidget() {
stackLPanel.add(new HTML("Manage empl."), new HTML("Employees"), 30);
stackLPanel.add(new HTML("Manage Dept."), new HTML("Departments"), 30);
// Add a home tab
HTML homeText = new HTML("This is the home tab");
tabLPanel.add(homeText, "Home");
// Add a tab
HTML moreInfo = new HTML("This is the more info tab");
tabLPanel.add(moreInfo, "More info");
// Return the content
tabLPanel.selectTab(0);
}
public Anchor getLogoutLink() {
return logout_link;
}
}
Is this possible, or how could this be done better?
Thank you.
I think there are two ways to do it:
Create a setter on your widget to set your ArrayList instances (setData()). You can then call this function in the onSuccess method of your loginService.
Inject the singleton instance of a global EventBus into your widget (using i.e. gin/guice) and fire an event containing your data. In the widget you have to attach an EventHandler for the specific event (i.e. LoadEmplListEvent).
I think both solutions are fine to use.
Solution one creates a tighter coupling to your widget but is easier to implement and I think you should take this route if you only have a small number of widgets where you work
with the data.
Solution is a cleaner approach because it de-couples your widgets from the rest. You fire the event the data in your onSuccess method once and you don't care about the widgets.
The widgets that are interested in the data will make sure that they handle the event appropriately (by handling the event). I guess if you have a lot of widgets that have to deal with the data the second approach is the one to go for.

How to invoke on the UI thread of a WinForm Component?

I'm coding a WinForm component where I start a Task to do the actual processing and trap the exception on a continuation. From there I want to show the exception message on a UI element.
Task myTask = Task.Factory.StartNew (() => SomeMethod(someArgs));
myTask.ContinueWith (antecedant => uiTextBox.Text = antecedant.Exception.Message,
TaskContinuationOptions.OnlyOnFaulted);
Now I get a cross-thread exception because the task is trying to update a UI element from a, obviously, non UI thread.
However, there is no Invoke or BeginInvoke defined in the Component class.
How to proceed from here?
UPDATE
Also, please note that Invoke/BeginInvoke/InvokeRequired are not available from my Component-derived class since Component doesn't provide them.
You could just add a property to your component, allows the client to set a form reference that you can use to call its BeginInvoke() method.
That can be done automatically as well, preferable so nobody can forget. It requires a bit of design time magic that's fairly impenetrable. I didn't come up with this by myself, I got it from the ErrorProvider component. Trusted source and all that. Paste this into your component source code:
using System.Windows.Forms;
using System.ComponentModel.Design;
...
[Browsable(false)]
public Form ParentForm { get; set; }
public override ISite Site {
set {
// Runs at design time, ensures designer initializes ParentForm
base.Site = value;
if (value != null) {
IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (service != null) this.ParentForm = service.RootComponent as Form;
}
}
}
The designer automatically sets the ParentForm property when the user drops your component on a form. Use ParentForm.BeginInvoke().
You can use delegates to do this.
delegate void UpdateStatusDelegate (string value);
void UpdateStatus(string value)
{
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new UpdateStatusDelegate(UpdateStatus), new object[]{value});
return;
}
// Must be on the UI thread if we've got this far
statusIndicator.Text = value;
}

Resources