Oracle ADF: Close popup after downloading file - oracle-adf

So here's the thing. I have a popup that has a button, the button itself has a fileDownloadActionListener, this one is responsible for downloading an excel file. So what I need basically is to hide the popup right after I generate the file.
Here's my .jspx file (Just the popup)
<af:popup childCreation="deferred" autoCancel="enabled"
id="myPopUp"
contentDelivery="lazyUncached"
binding="#{viewScope.mbMyBean.myPopUp}"
partialTriggers="b17">
<af:dialog id="d16" type="cancel"
title="Do you wish to download a file?"
inlineStyle="width:400px;">
<af:panelGroupLayout id="pgl32"
inlineStyle="max-width: 200px;">
<af:outputText value="You're about to download a file. Ready?" id="ot45"
/>
</af:panelGroupLayout>
<f:facet name="buttonBar">
<af:button text="GO" id="b17"
<af:fileDownloadActionListener contentType="excelHTML"
filename="#{viewScope.mbMyBean.FileName}"
method="#{viewScope.mbMyBean.GenerateEmptyExcel}"
/>
</af:button>
</f:facet>
</af:dialog>
</af:popup>
And here's the java method:
public void GenerateEmptyExcel(FacesContext facesContext, OutputStream outputStream) {
try {
HSSFWorkbook wb1 = generateEmptyExcelFile();
wb1.write(outputStream);
outputStream.flush();
outputStream.close();
this.myPopUp.hide();
AdfFacesContext.getCurrentInstance().addPartialTarget(this.myPopUp);
System.gc();
} catch (Exception e) {
e.printStackTrace();
}
}
PROBLEM
The popup won't hide.
NOTES
The popup is properly binded within the bean
I do not own this code and I'm doing a maintainance.
I do not know why the programmer used System.gc() since I consider it as a bad practice. Here's a good reason

I had the same problem after downloading a file, you should try this:
Use a resource type javascript to trigger an event click in commandButton
<af:resource type="javascript">
function customHandler(evt) {
console.log(evt);
var exportCmd = AdfPage.PAGE.findComponentByAbsoluteId("pt1:b17");
console.log(exportCmd);
var actionEvent = new AdfActionEvent(exportCmd);
console.log(actionEvent);
actionEvent.forceFullSubmit();
actionEvent.noResponseExpected();
actionEvent.queue(false);
setTimeout(function(){hidePopup();}, 1000);
}
function hidePopup() {
var popup = AdfPage.PAGE.findComponent("pt1:popupAceptarDescargarPlantilla::content");
popup.hide();
}
</af:resource>
You should have the following buttons:
<af:commandButton text="Aceptar" id="b17" visible="false" clientComponent="true" partialSubmit="true">
<af:fileDownloadActionListener contentType="excelHTML" filename="#{viewScope.mbGestionArchivos.nombre_archivo}" method="#{viewScope.mbGestionArchivos.generateExcelVacio}"/>
</af:commandButton>
<af:button text="Aceptar" id="botonPrueba" actionListener="#{viewScope.mbInformeDetalle.prepareForDownloadAction}" clientComponent="true" partialSubmit="true"></af:button>
This is the java method called by the button :
public void prepareForDownloadAction(ActionEvent act) {
FacesContext context = FacesContext.getCurrentInstance();
ExtendedRenderKitService erks =
Service.getService(context.getRenderKit(),
ExtendedRenderKitService.class);
erks.addScript(context, "customHandler();");
}
The hidden button is triggered using javascript a ADF methods, the magic happen in the setTimeout, When executing this function we avoid for a second to make submit but the request travels to the server, here we can observe how the file is started.

Ideally this.myPopUp.hide(); should close the popup but if it is not working for some reason, you can try closing the popup using javascript like:
public static void hidePopup(String popupId){
if (popupId != null)
{
ExtendedRenderKitService service =
Service.getRenderKitService(FacesContext.getCurrentInstance(),
ExtendedRenderKitService.class);
StringBuffer hidePopup = new StringBuffer();
hidePopup.append("var popupObj=AdfPage.PAGE.findComponent('" + popupId +
"'); popupObj.hide();");
service.addScript(FacesContext.getCurrentInstance(), hidePopup.toString());
}
}
You can get the popup clientId that you can pass into hidePopup using: this.myPopUp.getClientId(FacesContext.getCurrentInstance());

Related

Clicking button in Vaadin application has no effect with Selenium WebDriver

I'd like to interact with a Vaadin application (Vaadin 8) using WebDriver. The login form is wrapped using the PageObject pattern.
#Test
public void login() {
driver.get("http://localhost:8080/intern/login");
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUserCredentials("test", "test");
loginPage.submit();
}
The submit() method finds the login button and triggers a .click().
#FindBy(id = "loginButton")
private WebElement loginButton;
public void submit() {
this.loginButton.click();
}
When using the "real" application the click triggers several requests and responses to/from the server until the next page after the login page is loaded.
In the above WebDriver example however nothing happens after the click although I instructed the driver to do an implicit wait.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

CefSharp: Injecting custom CSS File using a custom scheme

I'm using CefSharp (47) to render a webpage from a host that I have no control over, and I want to make some additional CSS tweaks to those provided by the host.
Reading up on various topics across GitHub (https://github.com/cefsharp/CefSharp/blob/cefsharp/47/CefSharp.Example/CefSharpSchemeHandlerFactory.cs), and here (CefSharp custom SchemeHandler), I wrote a custom scheme handler accordingly:
public class CustomSchemeHandlerFactory : ISchemeHandlerFactory
{
public const string SchemeName = "custom";
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
Console.WriteLine(request.Url);
if (schemeName.ToLower() == SchemeName.ToLower())
{
// Do some stuff
}
return null;
}
}
I attempt to bind it in my application in the following manner:
CefSettings settings = new CefSettings();
settings.CachePath = browserCachePath;
settings.RegisterScheme(new CefCustomScheme()
{
SchemeName = CustomSchemeHandlerFactory.SchemeName,
SchemeHandlerFactory = new CustomSchemeHandlerFactory()
});
Cef.Initialize(settings);
The application then browses to the appropriate website, and uses the 'LoadingStateChanged' event to then fire off some JavaScript to inject the CSS file I want to load:
string linkText = "<link rel=\u0022stylesheet\u0022 type=\u0022text/css\u0022 href=\u0022custom://custom.css\u0022>";
var jsFunctionText = string.Format("(function() {{ $('head').append('{0}'); return true;}}) ();", linkText);
var injectionTask = await _myBrowser.GetMainFrame().EvaluateScriptAsync(jsFunctionText, null);
...which succeeds.
But my custom resource handler 'Create' event is never fired.
I can only presume that the handler isn't being registered properly, so I'd appreciate any advice/help in getting this working properly!
Thanks!

Libstreaming: How to navigate from SurfaceView screen(Sending Video+Audio Streams to wowza) to HTML Page in Android Phonegap

I am creating one phonegap application using Libstreaming for Video and Audio streaming. I have login and Home screen. On Home screen, there is a button "Start Streaming", on click of this button It launches the camera to start streaming which sends audio and video streams to WOWZA media server. The camera preview has one surface view on which video is getting played.
The camera preview has one Back button over SurfaceView to back on Home screen. My issue is that, On click of back button Camera preview should be destroyed and It should redirect to Home screen (Navigation from Android SurfaceView to HTML page).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/surface_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:background="#android:color/black" >
<!-- Below surface view is used to to send rtsp audio+video stream to wowza server -->
<net.majorkernelpanic.streaming.gl.SurfaceView
android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<!-- button to halt the camera preview and go back on to the main screen -->
<Button
android:id="#+id/btnGoBack"
android:layout_width="60dp"
android:layout_height="40dp"
android:visibility="visible"
android:text="Back"
android:layout_alignTop="#+id/surface_view"
android:layout_alignParentLeft="true"
android:textSize="14dp"
/></RelativeLayout>
I have done it myself. It looks big but quite simple. All you need to do is, define a click method of back button (which is on the SurfaceView) in your activity class (Not MainActivity as follows-
public class LiveStreamingActivity extends Activity implements RtspClient.Callback, Session.Callback, SurfaceHolder.Callback {
private static SurfaceView mSurfaceView;
private Button btnGoBack;
private SurfaceHolder mHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if (!LibsChecker.checkVitamioLibs(this))
return;
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
btnGoBack = (Button) findViewById(R.id.btnGoBack);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
/* click listener of back button */
btnGoBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
MainActivity.isFirstTime = true;
/* on click of back button finish the current activity
* which will destroy the surfaceview and will go back on MainActivity
* by referring the Android Activity lifecycle, OnResume() method of MainActivity
* would be called where you can call javascript function directly.
*/
finish();// callback lifecycle: "onPause", "onStop", and at last "onDestroy"
} catch (Exception e) {
e.printStackTrace();
}
}
});
}}
MainActivity.java:
You have to declare a field ("isFirstTime = false") to put a logic for calling javascript function in OnResume() method. (For better understanding please refer Android activity lifecycle).
public class MainActivity extends CordovaActivity {
public static boolean isFirstTime = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadUrl(launchUrl);
}
#Override public void onResume(){
super.onResume();
System.out.println("onResume main activity");
if(isFirstTime){System.out.println("Inside onResume");
loadUrl("javascript:launchProfile()");
}
}
#Override public void onPause(){
super.onPause();
System.out.println("onPause main activity");
isFirstTime = false;
}}
Javascript Function:
I am using AngularJS. So I have to get the $location object to inject the path of profilePage.
function launchProfile(){
var e = document.getElementById('loginScreen');/*'loginScreen' is login form id */
var $injector = angular.element(e).injector();
var $location = $injector.get('$location');
$location.path("/profilePage");}
app.js (Angularjs routing):
vcApp = angular.module('VCMobApp', ['ngRoute']);vcApp.config(['$routeProvider', function ($routeProvider){
$routeProvider.when('/', {templateUrl: 'screens/login.html', controller: 'loginPageCntrl' });
$routeProvider.when('/profilePage', {templateUrl: 'screens/profilePage.html', controller: 'profilePageCntrl'});
$routeProvider.otherwise({ redirectTo: '/' });}]);
In case you are not using AngularJS, then directly you can call your html page using window.location.href='../profilePage.html' inside launchProfile() function itself (skip angularjs code then).

Facebook crossdomain.xml silverlight error

I have a problem with crossdomain.xml that is located on Facebook photo servers. The first problem arises when Silverlight asks for clientaccesspolicy.xml ā€“ Facebook servers return 403 ā€“ Access Denied which is fine, since they also have crossdomain.xml deployed on their servers. Silverlight then asks for that crossdomain.xml and the response it gets is exactly this:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain- policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" secure="false" to-ports="*" />
<site-control permitted-cross-domain-policies="master-only" />
</cross-domain-policy>
Then I played for a while with this, deployed that crossdomain.xml to my own servers and a got the same results ā€“ a security exception. Then I started moving things out and came to a conclusion that everything will work as desired if I only remove the to-ports="*" attribute? Does anyone has an idea how to overcome this, has anyone had the same problem before or is it something that Iā€™m doing wrong?
I have run into the same issue while trying to programmatically retrieve images from Facebook. The strange part is that if you point a Silverlight image control to the Facebook image url, the image is retrieved and displayed without error. This got me thinking and I have come up with a viable workaround that seems to work consistently for my situation. I hope you find it useful too.
var uri = new Uri("http://graph.facebook.com/mglace/picture/", UriKind.Absolute);
var bmp = new BitmapImage();
bmp.ImageOpened += (sender, e) => { /* Do something here with the sender (which is the BitmapImage) */ };
bmp.CreateOptions = BitmapCreateOptions.None;
bmp.UriSource = uri;
Create a BitmapImage object, set an event handler for the ImageOpened event and set the CreateOptions property to BitmapCreateOptions.None. Finally, set the UriSource to the Facebook image you want to retrieve. The image is downloaded immediately because we set the CreateOptions to None (the default value is DelayedCreation). You can then perform any actions you would like in the ImageOpened event handler.
I wanted to encapsulate this logic in my service layer and beef up the error handling and such so I wrapped it in a Reactive Extensions observable to make it easier to use. Here is my final code snippet:
public IObservable<BitmapImage> GetProfilePhoto(string profileId)
{
return Observable.Create<BitmapImage>(
observer =>
{
// This handler handles a successful fetch
EventHandler<RoutedEventArgs> openedHandler =
(sender, args) =>
{
try
{
observer.OnNext(sender as BitmapImage);
observer.OnCompleted();
}
catch (Exception ex)
{
observer.OnError(ex);
}
};
// This handler handle a failure
EventHandler<ExceptionRoutedEventArgs> failedHandler =
(sender, args) => observer.OnError(args.ErrorException);
var url = string.Format("http://graph.facebook.com/{0}/picture/", profileId);
var uri = new Uri(url, UriKind.Absolute);
BitmapImage bmp = null;
try
{
Deployment.Current.Dispatcher.BeginInvoke(
() =>
{
bmp = new BitmapImage();
bmp.ImageOpened += openedHandler;
bmp.ImageFailed += failedHandler;
bmp.CreateOptions = BitmapCreateOptions.None;
bmp.UriSource = uri;
});
}
catch (Exception ex)
{
observer.OnError(ex);
}
return () =>
{
// Cleanup the event handlers
if (bmp != null)
{
bmp.ImageOpened -= openedHandler;
bmp.ImageFailed -= failedHandler;
}
};
});
}
And usage:
GetProfilePhoto("mglace")
.Subscribe(image => { /* Do something with the image in here*/ },
error => { /* Handle any errors in here */ },
() => { /* Finalization code goes here */ });
I hope someone out there finds this useful.
This is still not resolved in Silverlight 5. Facebook doesn't seem concerned too.

Browser Pop-up WIndows and Silverlight OOB

Within the browser I can use this to open a pop-up window:
System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(uri), "_blank");
How do I do this when running outside of the browser?
In an OOB app, you can use the following work around:
Create a derived hyperlink button like this:
public class MyHyperlinkButton : HyperlinkButton
{
public void ClickMe()
{
base.OnClick();
}
}
Use that for navigation:
private void NavigateToUri(Uri url)
{
if (App.Current.IsRunningOutOfBrowser)
{
MyHyperlinkButton button = new MyHyperlinkButton();
button.NavigateUri = url;
button.TargetName = "_blank";
button.ClickMe();
}
else
{
System.Windows.Browser.HtmlPage.Window.Navigate(url, "_blank");
}
}
see forums.silverlight.net
You don't. System.Windows.Browser.HtmlPage is a call to the HtmlPage that is hosting the silverlight application. In out of Browser, you are not hosted by a web page. Trying to do that just hangs the application.
If you have elevated privileges, than you could make an OS call to open a new browser, or I'm sure there are 3rd party controls that act as a hosted browser.
Another way to do this is through ShellExecute:
if (App.Current.IsRunningOutOfBrowser)
{
dynamic shell = AutomationFactory.CreateObject("Shell.Application");
shell.ShellExecute("someURL", "", "", "open", 1);
}
Documentation for ShellExecute is here: http://msdn.microsoft.com/en-us/library/bb774148(VS.85).aspx

Resources