Forcing to Close Chrome Custom Tab - chrome-custom-tabs

I want to close a chrome Custom Tab with clicking device back button, but it only works when the custom tab has no history for the moment; when there's a remaining history, clicking the device back button only rewinds the custom tab back to a page in its history. Can I force the custom tab to ignore the history at any point and close the custom tab immediately?
I tried different options for the custom tabs such as below, but it appears none helps with my purpose. I would hugely appreciate your idea. Thank you!
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
My current code is
String url = eacharticle.get("url");
String PACKAGE_NAME = "com.android.chrome";
android.support.customtabs.CustomTabsIntent customTabsIntent = new android.support.customtabs.CustomTabsIntent.Builder().setShowTitle(true).build();
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
customTabsIntent.intent.setData(Uri.parse(url));
java.util.List<android.content.pm.ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(customTabsIntent.intent, android.content.pm.PackageManager.MATCH_DEFAULT_ONLY);
for (android.content.pm.ResolveInfo resolveInfo : resolveInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
if(PACKAGE_NAME.equals(packageName))
customTabsIntent.intent.setPackage(PACKAGE_NAME); // force use chrome if installed
}
customTabsIntent.launchUrl(context, Uri.parse(url));

I dont think there is currently an option to do this since we cannot override onBackPressed action on chrome custom tabs. Actually it is better to work this way in many use case.

Related

Print Friendly Page

So I would like to be able to have a print button for entries in our database so users can print an entry via a print friendly "form".
My thought was to create a separate page, add labels and have those labels pull the relevant information.
I know I can add the open widget information via this code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.TestPrint);
But I'm running into a few problems:
I can't get the page to open in a new window. Is this possible?
window.open(app.pages.TestPrint);
Just gives me a blank page. Does the browser lose the widget source once the new window opens?
I can't get the print option (either onClick or onDataLoad) to print JUST the image (or widget). I run
window.print();
And it includes headers + scroll bars. Do I need to be running a client side script instead?
Any help would be appreciated. Thank you!
To get exactly what you'd want you'd have to do a lot of work.
Here is my suggested, simpler answer:
Don't open up a new tab. If you use showPage like you mention, and provide a "back" button on the page to go back to where you were, you'll get pretty much everything you need. If you don't want the back to show up when you print, then you can setVisibility(false) on the button before you print, then print, then setVisibility(true).
I'll give a quick summary of how you could do this with a new tab, but it's pretty involved so I can't go into details without trying it myself. The basic idea, is you want to open the page with a full URL, just like a user was navigating to it.
You can use #TestPrint to indicate which page you want to load. You also need the URL of your application, which as far as I can remember is only available in a server-side script using the Apps Script method: ScriptApp.getService().getUrl(). On top of this, you'll probably need to pass in the key so that your page knows what data to load.
So given this, you need to assemble a url by calling a server script, then appending the key property to it. In the end you want a url something like:
https://www.script.google.com/yourappaddress#TestPage?key=keyOfYourModel.
Then on TestPage you need to read the key, and load data for that key. (You can read the key using google.script.url).
Alternatively, I think there are some tricks you can play by opening a blank window and then writing directly to its DOM, but I've never tried that, and since Apps Script runs inside an iframe I'm not sure if it's possible. If I get a chance I'll play with it and update this answer, but for your own reference you could look here: create html page and print to new tab in javascript
I'm imagining something like that, except that your page an write it's html content. Something like:
var winPrint = window.open('', '_blank', 'left=0,top=0,width=800,height=600,toolbar=0,scrollbars=0,status=0');
winPrint.document.write(app.pages.TestPage.getElement().innerHTML);
winPrint.document.close();
winPrint.focus();
winPrint.print();
winPrint.close();
Hope one of those three options helps :)
So here is what I ended up doing. It isn't elegant, but it works.
I added a Print Button to a Page Fragment that pops up when a user edits a database entry.
Database Edit Button code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showDialog(app.pageFragments.FragmentName);
That Print Button goes to a different (full) Page and closes the Fragment.
Print Button Code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ModelName_Print);
app.closeDialog();
I made sure to make the new Print Page was small enough so that Chrome fits it properly into a 8.5 x 11" page (728x975).
I then created a Panel that fills the page and populated the page with Labels
#datasource.item.FieldName
I then put the following into the onDataLoad for the Panel
window.print();
So now when the user presses the Print Button in the Fragment they are taken to this new page and after the data loads they automatically get a print dialog.
The only downside is that after printing the user has to use a back button I added to return to the database page.
1.
As far as I know, you cannot combine window.open with app.pages.*, because
window.open would require url parameter at least, while app.pages.* is essentially an internal routing mechanism provided by App Maker, and it returns page object back, suitable for for switching between pages, or opening dialogs.
2.
You would probably need to style your page first, so like it includes things you would like to have printed out. To do so please use #media print
ex: We have a button on the page and would like to hide it from print page
#media print {
.app-NewPage-Button1 {
display : none;
}
}
Hope it helps.
1. Here is how it is done, in a pop up window, without messing up the current page (client script):
function print(widget, title){
var content=widget.getElement().innerHTML;
var win = window.open('', 'printWindow', 'height=600,width=800');
win.document.write('<head><title>'+title+'/title></head>');
win.document.write('<body>'+content+'</body>');
win.document.close();
win.focus();
win.print();
win.close();
}
and the onclick handler for the button is:
print(widget.root.descendants.PageFragment1, 'test');
In this example, PageFragment1 is a page fragment on the current page, hidden by adding a style with namehidden with definition .hidden{display:none;} (this is different than visible which in App Maker seems to remove the item from the DOM). Works perfectly...
2. You cannot open pages from the app in another tab. In principle something like this would do it:
var w=window.parent.parent;
w.open(w.location.protocol+'//'+w.location.host+w.location.pathname+'#PrintPage', '_blank');
But since the app is running in frame nested two deep from the launching page, and with a different origin, you will not be able to access the url that you need (the above code results in a cross origin frame access error). So you would have to hard code the URL, which changes at deployment, so it gets ugly very fast. Not that you want to anyway, the load time of an app should discourage you from wanting to do that anyway.

Qt installer framework hide or disable buttons

I want to hide or freeze the back button on a page ( to be more specific, License Agreement Page). I tried editing control.qs with few methods but it doesn't seem to work. Following is one of them
Controller.prototype.LicenseAgreementPageCallback = function()
{
var widget = gui.currentPageWidget();
if (widget != null)
{
widget.BackButton.setVisible(false) ;
}
}
I'm facing a similar problem trying to keep hide the Next button in the Target Directory page under certain conditions.
But your case may be easier:
1) You should use a global boolean variable set to true when you enter the License Agreement page.
2) When you enter the previous page test the value of this global: if true then force a click on the next page (gui.click(buttons.NextButton);).
Yes, it's a dirty workaround ;)
I think you could try what I've proposed here: Qt installer framework: remove radio buttons from uninstaller. Even if it wasn't accepted, that what I used in my installer, so I'm pretty confident it's working!
For the wizard BackButton specifically, it automatically disables itself if there are no pages before the current page a la the Introduction page.
From QtScript this can be accomplished by removing any dynamic pages before the current page with installer.removeWizardPage and disabling all default pages before the current page with installer.setDefaultPageVisible(QInstaller.Introduction, false).

open a page to new window/tab from iframe

I have a page with an iFrame on it.
On the page in the frame I have a button.
What I want is that if the user clicks on the button, another page is opened in it's own new window or tab. This functionality is to show the user a print friendly page.
How can I do this?
This is how I now try it:
Dim sb2 As New StringBuilder
sb2.Append("window.open('")
sb2.Append(sb.ToString)
sb2.Append("','NewPFWindow','menubar=1,toolbar=1,scrollbars=1,resizable=1,sandbox=""allow-same-origin allow-forms""')")
ClientScript.RegisterClientScriptBlock(Me.GetType, "si2", sb2.ToString, True)
sb holds the page like "mypage.aspx"
Another option is to resize the iFrame so the whole page will fit. Is that possible from code-behind?
rg.
Eric
Just provide a target that has not been named on your site yet, most people will use _blank for that
I.e.
link text
or if you want to tie that to another click-event somewhere else:
window.open('desiredLocationUrl....', "_blank");
Btw. it does not matter if that link is inside an iframe ;)
found it.
Apparently Chrome uses an undocumented feature.
The frame that is trying to put the new page in it's own window or tab, needs an extra option in the sandbox property called "Allow-popup'.
This is not documented on the w3schools.com website.
So by adding this to the sandbox property, you allow the browser to create new window/tab.

History.js implementation

I'm having trouble implementing history.js
I have a single page website that uses a jquery slider (royal slider) to slide full page divs that act as pages. The slider is operated using custom links. What I would like to do is have each link manipulate the browser history in order to 1. change the page URL. and 2. push states to the browser that are refreshable and can be navigated to and from via the browser's forward and back buttons.
What I'm not sure about is whether any pushstate will save the sliders current slide?
It's not essential if not, as the change in URL is the main thing.
Each link is controlled via a javascript click function that looks like this...
var workclick = document.getElementById('worklink');
workclick.onclick = function () {
thefooter.style.opacity = "1";
thefooter.style.filter = 'alpha(opacity=100)';
thefootdivide.style.opacity = "1";
thefootdivide.style.filter = 'alpha(opacity=100)';
$(".royalSlider").royalSlider('goTo', 1);
}
Can somebody help me with what I need to add to my page to get history.js to work with what I have here?
Thanks so much for any help
I am not an expert on History.js, but my understanding is that once it's installed, each time a slider value is changed you could call replaceState() with url parameters that reflect their values something like :
History.replaceState( null, 'My Title', '?slider1=' + $('#slider1').value );
And then, when your page loads have it read these request parameter values and (if present) set the sliders accordingly.
Again I'm not sure this is exactly what you need but I'm pretty sure it's on the right track.

ASPnet web Form Navigation

I want to redirect a new tab and to get focus of the new window when a button is clicked.. I can create a new window, but can't get its focus even thourh, I tried the following code
Window.focus(); How to do this?
My Code:
function new_window(url)
{
//Open a Window in New tab
var popupwin = null;
popupwin = window.open(url);
popupwin.focus();
self.focus();
//window.focus();
}
I think it would be better not to do this. These are browser preferences and don't try to override those. It may fail due to user settings.
Remove
self.focus();
You can use focus() method of a form element. This brings mostly the window to front. window.focus() might implemented different by different browsers.
Do you have html input elements on you popup win?
Try calling focus() on one of the html input elements. This will place the cursor into the element to assist the user start typing there.

Resources