If a user is watching a video, or streaming audio on a page in my Meteor app, is there something I can use to prevent that particular player element from refreshing/stopping/closing during a Hot Code Reload when new code is pushed?
Currently, if I make a change to the code base and a user is watching/listening to something, they will be interrupted and the player will stop.
You could use the onMigrate api (undocumented) to disable a hot code push if someone is watching a video:
function onMigrate (retry) {
//Return [true, data] to allow it to hot code reload, data being anything you want to be available when the page reloads
return false;
}
Meteor._reload.onMigrate("someName", onMigrate);
// or Meteor._reload.onMigrate(onMigrate);
There's also a videocast covering this on eventedmind and a bit of a comment about it on github: https://github.com/meteor/meteor/blob/devel/packages/reload/reload.js#L81-L94
Related
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.
I'm using FirebaseUI for Web — Auth widget to simplify the auth workflow, and I'm stuck with a problem. Everything works OK the first time. But, after I sign in, the widget contents clears away, and the 'Sign in with ...' buttons never come back. Trying to recreate the widget brings up the error "UI Widget is already initialized on the page. Only one widget instance can be initialized per page."
This means that users need to refresh the page to get the sign-in buttons back. Is there a more elegant way?
Are you rendering the widget in a single page application? If so, this currently won't work. You will have to render the sign in widget in a popup whenever you want the user to sign in.
As bojeil stated in the first answer (May 2016), there was really a problem using it in single page applications workflows. But in more recent versions of firebase-ui you can actually reset the widget so you won't need to initialize it again.
All you need to do is to keep the widgets instance reference in a variable. Then, when you want to render it again you use the same reference, reset it and then restart it.
var ui;
if (ui) {
ui.reset();
} else {
ui = new firebaseui.auth.AuthUI(firebase.auth());
}
ui.start('#firebaseui-auth-container', uiConfig);
We're currently using QtWebKit to build an application, part of which displays the product catalogue page of our website. On that webpage we're using the jQuery.history plugin to keep track of sorting and filtering options without users needing to reloading the page.
When jQuery.history's pushState() function is called the URL provided is pushed to the history properly, but QWebView's urlChanged() signal (which we're listening for to update back/forward buttons and the address bar) isn't fired even though the current URL has changed. I can only assume this is because no link was clicked, nor was there a page reload so Qt doesn't think it needs to do anything URL-related.
Is there any way to detect a URL change made via the HTML5 history API in QtWebKit, or am I missing something obvious?
There is QWebPage::saveFrameStateRequested signal:
This signal is emitted shortly before the history of navigated pages in frame is changed, for example when navigating back in the history.
You can use it to track history changes:
void MainWindow::saveFrameStateRequested(QWebFrame *frame, QWebHistoryItem *item) {
// this slot is executed before the history is changed,
// so we need to wait a bit:
QTimer::singleShot(100, this, SLOT(listHistoryItems()));
}
void MainWindow::listHistoryItems() {
for (QWebHistoryItem historyItem: view->page()->history()->items()) {
qDebug() << "item" << historyItem.url() << historyItem.title();
}
}
void MainWindow::finishLoading(bool) {
// (re)connect the signal to track history change,
// maybe there is a better place to connect this signal
// where disconnect won't be needed
disconnect(view->page(), SIGNAL(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)),
this, SLOT(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)));
connect(view->page(), SIGNAL(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)),
this, SLOT(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)));
}
The modified Fancy Browser example screenshot.
i am using custom url scheme in my flex iOS app and it’s working fine when i start my app from a web link..but the issue is when i start my app from start menu in iPad and move to webpage in safari.In page i click a button that redirects it to my app, at that time app call “preinitialize” method more than once..it wary every time, some time it’s 2,3,4 and different one each time..i don't know why it’s behaving like this..can i know the reason please its urgent..
thanks…any help will be appreciated.
Create a flag initialized and set it to true when preinitialize is called. All other calls to this method can be filtered out. Simple example:
private var initialized:Boolean = false;
public function preinitialize():void
{
if (initialized) return;
initialized = true;
}
Next step would be finding the real cause of the multiple calls, but for that we would need to see some code of your app.
I am using asp.net and I need to display a prompt to the user if they have made changes to the web page, and they accidentally close down the browser.
The page could be anything from "Edit Profile" to a "Submit a Claim" etc.
How can I can display the messagebox, ensuring that it is displayed only if changes have been made (as opposed to, the user making changes, then undo-ing the changes, and shutting down the browser)
What I have done in the past is use some client side scripting which does this check during the onbeforeunload event....
var showPrompt=true;
var isDirty=false;
var hidePopup=false;
function onBeforeUnload() {
if (showPrompt) {
if (isDirty) {
if (hidePopup || confirm("Click ok to save your changes or click cancel to discard your changes.")) {
doSave();
}
}
}
showPrompt = true;
hidePopup = false;
}
ShowPrompt can be set to false when your clicking on an anchor tag which won't navigate you away from the page. For example <a onclick='showPrompt=false' href='javascript:doX()'/>
isDirty can be used to track when you need to save something. You could for example do something like $("input").onchange(function(){isDirty=true;}); To track undo's you might want to replace isDirty with a function which checks the current state from the last saved state.
HidePopup lets us force a save without confirming to the user.
That's very difficult to even touch without understanding what's on the page. If it's a few controls you capture value at page load and store them so you can later compare. If it's a complex page you'd need to do an exact comparison to the entire viewstate.
Typically you'd handle this type of situation by setting a boolean to TRUE the first time any change is made and disregard the user changing it back. If you're just trying to avoid accidential non-save of data the user should be smart enough to know they've "undone" their changes.
You can do this with javascript. See this question and either of the first two answers.