onbeforeprint() and onafterprint() equivalent for non IE browsers - php

I want to send some info back to my database when a user prints a certain web page. I can do this in IE with onbeforeprint() and onafterprint() but I would like to browser agnostic way of doing the same thing. Don't care which combination of technologies I have to use (PHP, MySQL, JavaScript, HTML) so long as it gets done. Any ideas?
EDIT:
Still having some problems with this. I tried the putting my function in my Print.css as an image, but I am messing it up some how. Then I tried just adding a event listener, but I cannot get that to work quite right either. If anyone can provide some more details on how I might call a function right before print in ANY browser I would appreciate it.
EDIT:
I am giving up on this for now, I have settled with another way of doing what I want. I look forward to the day when FireFox supports onbeforeprint() and onafterprint().

Many browsers now support window.matchMedia. This API allows you to detect when CSS media queries go into effect (e.g., rotating the screen or printing the document). For a cross-browser approach, combine window.matchMedia with window.onbeforeprint/window.onafterprint.
The following may result in multiple calls to beforePrint() and afterPrint() (for example, Chrome fires the listener every time the print preview is regenerated). This may or may not be desirable depending on the particular processing you're doing in response to the print.
if ('matchMedia' in window) {
// Chrome, Firefox, and IE 10 support mediaMatch listeners
window.matchMedia('print').addListener(function(media) {
if (media.matches) {
beforePrint();
} else {
// Fires immediately, so wait for the first mouse movement
$(document).one('mouseover', afterPrint);
}
});
} else {
// IE and Firefox fire before/after events
$(window).on('beforeprint', beforePrint);
$(window).on('afterprint', afterPrint);
}
More: http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/

I m not sure other browsers will allow you to. You could of course specify an image somewhere in a print stylesheet, which probably only will be called on a print, for the onbeforeprint

Try masking the native window.print() with your own...
// hide our vars from the global scope
(function(){
// make a copy of the native window.print
var _print = this.print;
// create a new window.print
this.print = function () {
// if `onbeforeprint` exists, call it.
if (this.onbeforeprint) onbeforeprint(this);
// call the original `window.print`.
_print();
// if `onafterprint` exists, call it.
if (this.onafterprint) onafterprint(this);
}
}())
Updated: comments.

I think that it's simply not possible to this properly. Or at least - not with any technology I know nor with any of the answers given previously.
Both using onafterprint and using serverside dynamic-image-generating script would tell you that the page was printed even when the visitor merely went to print preview mode and then canceled out.
However, I would like to learn how to get the proper information, so that I can be sure that page was actually printed.

Related

dynamically include PHP based on browser features

REWRITE
I have a website written in HTML5, and the same website written in XHTML. I would like to render one or the other based on whether or not someone is using a browser that supports some of the most basic features of HTML5.
NOTE
The site does not use the canvas, audio, or video features of HTML5. It is simply tagged with aside, section, nav, etc, and uses some of CSS3's fun features for styling embellishments. The difference between the HTML5 site and the XHTML site is minimal, and probably will be barely noticeable to anyone if I can make this work. The content is the same, it is just presented slightly differently.
THE REASON I DID IT THIS WAY
Once the dinosaur browsers are gone, I am hoping I can simply post the HTML5 site, and do away with the old XHTML.
I am running into some logistical snags and have not fully formulated how I want to go about this. I initially had the idea to use Javascript conditional statements to determine which PHP include to render. Yes, go ahead and laugh, I probably will some day too. While investigating that, a person commented that XML might make that possible. I am fairly capable with Javascript, PHP and XML. This is the first time I have tried to integrate Javascript with PHP, so now I understand why my original plan needed some more work.
Ultimately, I feel pretty strongly that this is how I want to move forward. I read about progressive enhancement versus graceful degradation, but I have decided that I want to give my client a beautiful website using all of the new semantic tags and simple style selectors to increase SEO and guarantee that when HTML4 goes away, this new site will stand the test of time...at least for a little while.
If you strongly object to this method, I am willing to listen to what you have to say. Please share your thoughts either way.
What you ask for is impossible; as I already explained, PHP is server-side, and JS is client-side; anything done php side is finished by the time the page is delivered to the user, so it is impossible for js to influence the php side unless your site, or content delivery, is done completely in ajax, which is a method of using js and php to retrieve information; in short, js sends a request to another php page on your server and returns the result.
That however is much more complicated, and I do not recommend it until you are more familiar with both JS and PHP.
That aside, however, there is a solution in php, although I do not have the complete code right now.
The solution is the php 4 and 5 function of get_browser():
$arr = get_browser(null, true);
$var = "some browser";
if ($arr['parent'] == $var) {
require('/php/file.php');
}
else {
//etc
}
The above is before your answer update; I have nothing else to say in regards to said update.
Update: In regards one of the comments below in regards to ajax, I will attempt.. an example. I won't attempt to call it 'simple', because ajax is anything but.. though back to the point...
HTML:
<html>
<body>
<div id="main_body">
</div>
</body>
</html>
JS:
//some code to determine user-agent/browser, set variable 'agent' with result
var use_html5;
if (agent == browser) {
use_html5 = 'yes'
}
else {
use_html5 = 'no'
}
function retrv_body() {
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {//readState 4 is when the request has finished;
//0: request not initialized
//1: server connection established
//2: request received
//3: processing request
//4: request finished and response is ready
document.getElementById('main_body').innerHTML = xmlhttp.responseText;
//set html of div with id 'main_body' to rendering retrieved from php_file_in_same_dir.php
}
}
xmlhttp.open("POST","php_file_in_same_dir.php",true);
//set type of form, boolean is in regards to whether the request is asynchronus or synchronous
//most ajax requests are async, which means they themselves finish executing usually after the function itself has run. I'm not truly knowledgeable regarding this specific thing since I've only ever used async requests, though I would assume being a sync request would mean the function actually waits until it returns a value before it finishes executing.
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//set the headers of the content.
xmlhttp.send("html5=" + use_html5);
//finally, send the data. Depending on the data, the data may need to be url-encoded.
}
retrv_body();
PHP:
<?php
if ($_POST['html5'] == 'yes') {
include('body5.php');
}
else {
include('body_other.php');
}
//body generating code, render page.
?>
The above is just an example, and I would not recommend actually using it, save the retrv_body() function, and changing it into something you can really use.
Hopefully the comments I've put in the code will help in understanding; if anything is left to question, feel free to ask that I explain more thoroughly.
No.No.No.No.No!
Two points:
Use HTML5 shiv - Gives older IE browsers HTML5 capabilities)
Progressive enhancement - You shouldn't code for different browsers. Your code should work in all browsers. Then add features that enhance, but are not required for the site to function, the user experience.

does a PHP page with includes get compiled and sent as one page?

I have a PHP page where the header and footer are PHP includes.
I want to know if there is any possibility of the includes loading asynchronously - or does PHP gather all the files required, compile them and send them as one file?
The reason I ask is that I've seen an interesting PHP app that seemed to keep the connection open and do things in sequence before closing the connection - I wondered if that's what happens with includes.
PHP version is 5.3.6
EDIT:
What I actually want is for the page to load all at once, to prevent my layout mashing as each bit loads. Sorry to any who misunderstood this
PHP does gather and compile them; everything goes to the browser as a single document. If you don't want this, you'll have to do something with XMLHTTPRequest on the frontend
Generally any output will be output as it is generated.
echo 'A';
sleep(1000);
echo 'B';
sleep(1000);
echo 'C';
This slowly outputs "ABC". Includes are included when they are encountered, the same way echo outputs anything at that specific point. It's all in order, never asynchronously.
A web server may buffer all output before sending any of it to the client. In the above example, you'd receive "ABC" all together after 2 seconds of nothing.
If your objective is to receive all the page at once you need to use ob_start() and ob_end_flush(). Do something like:
ob_start();
...
write all your outputs
...
ob_end_flush();
This will force the server to buffer the output until the whole page is prepared.
Good luck!
I use the following architecture when loading a page on my application:
index.php
<script src="path/to/js/lib/jslib.js" type="text/javascript"></script>
window.addEvent('load', function()
{
BuildPg(PgStatus); //PgStatus is a variable I use in a state machine to build different pages
});
<form>
<div id="DivPgTop"></div>
<div id="DivPgMiddle"></div>
<div id="DivPgBottom"></div>
</form>
This is the entire index.php
In my jslib.js I have functions like:
function BuildPg(Pg) {
BuildPgTop(Pg);
BuildPgMiddle(Pg);
BuildPgBottom(Pg);
}
function BuildPgTop(Pg) {
var Content="";
if (Pg == 1) {
Content = function_a(); // function_a builds the top of the page
else if (Pg == 2) {
Content = function_b();
etc...
}
document.getElementById("DivPgTop").innerHTML = Content; //here is where I load the top of the page
}
And I do the same for the other parts of the page Middle and Bottom.
Using this framework, if you changed my BuildPg() function to something like:
function BuildPg(Pg) {
BuildPgTop(Pg);
sleep(foo);
BuildPgMiddle(Pg);
sleep(bar);
BuildPgBottom(Pg);
}
Your user would experience the top of the page loading first, a delay, the middle of the page, another delay, and the bottom.
And if you change the order of the function calls you could even have the bottom of the page load first, then the middle and the top.
I hope this makes sense. Good luck!
PHP sends a single document. What you want to do is achieved with something called AJAX (http://en.wikipedia.org/wiki/Ajax_%28programming%29)
Basically you write some JavaScript code that uses XMLHTTPRequest object to connect to the server and download some extra info.

Output buffer based progress bar

I have been trying to get the following code working.
It's a progress bar trick which uses ob_get_clean() function.
Don't know why but this script just don't work!
Only the initial percent - 1% comes up and nothing after that.
<?php
error_reporting(8191);
function flush_buffers(){
#ob_end_flush();
#ob_flush();
#flush();
#ob_start();
}
$ini = 2;
echo '<script>document.getElementById(\'lpt\').style.width=\'1%\';</script><br>';
for($i=1;$i<=100;$i++) {
$k=$ini-1;
$str=str_replace("width=\'$k%\'","width=\'$i%\'",ob_get_clean());
$ini++;
echo $str;
flush_buffers();
}
?>
You can't 'retract' output text after you've sent it to the client. It merely gets appended.
It would not work as you are trying to mix server and client side code. PHP Code on the client side would not work. You will need to build the whole progress bar using javascript itself.
What #Delan says: You can't "take back" and edit output that has already been sent to the client. You would have to output a completely new <script> snippet for every movement of the percentage bar.
You can't do progress bar in PHP, you must write in eg. JavaScript, and only echo with PHP.
You can't do that because PHP is server-side language and any loading is performing on client-side because server don't loads anything then loading script you must have in client-side language.
i don't think any of these answers are complete or correct that are up-voted.
it's true that you can't retract output, but you CAN do what KPL wants to do using a simplistic non-ajax approach that doesn't even require javascript... i do this all the time. tested on ie 9, firefox, chrome and safari. perhaps it could be true that in 2010 when this was asked this technique didn't work, but i don't see why now. it's not html5 or anything fancy...
you do so using ob_flush like KPL guesses and you re-output the current bar html (however you like it to look, fancy/animated/etc) with position:absolute and an incrementing z-index:$counter. that way on each loop the output gets flushed as the php is running on the server and the new output is neatly placed over top of the previous output. sounds messy, but this technique looks perfect and works really really well on every browser i've tried.

How can I reliably capture screen resolution using Actionscript?

I have several components who's screen position depends on the resolution of the monitor on which the browser lives.
loginBox.x = (flash.system.Capabilities.screenResolutionX - loginBox.width) / 2;
loginBox.y = (flash.system.Capabilities.screenResolutionY - loginBox.height) / 2;
The problem I'm encountering is that the flash.system.Capabilities method pulls the resolution of the primary monitor attached to the computer. In most situations this isn't a problem but on one of my computers, I have a 1680x1050 and a 1440x900. At work, I have a 1920x1200 and a 1680x1050, so if I open the page in a browser on the smaller monitor, things are not centered and my tools panel is completely off to the right of the screen.
I have a block of javascript that I've tried, both in html and through php but the problem is that if I use either httpRequest or urlLoader to grab the html file, I get the source of html and if I try the php script, I get a script block that is attempting to write a cookie. If that page has not been visited prior to loading the flash site, or if cookies are disabled, it never gets written and I'm nowhere.
Is there a method that I can use, that doesn't rely on cookies, to detect the resolution of the monitor that the browser is actually on, and not just the resolution of the first monitor?
Why don't you use stage.stageWidth and stage.stageHeight for positioning purposes?
EDIT:
Ok, here's an example.
I'm considering that you'll place this code inside the container where loginBox also resides.
The stage property is undefined unless your object is added to the DisplayList, so you need to listen for when it's added and then position the loginBox.
// in the constructor
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
and then
private function onAddedToStage(evt:Event) {
loginBox.x = (stage.stageWidth - loginBox.width)/2;
loginBox.y = (stage.stageHeight - loginBox.height)/2;
}
Also, if you have stage scaleMode set to noScale (which maybe is the case), if you need to constantly reposition the loginBox based on browser resizing, you need to listen to an Event.RESIZE event
stage.addEventListener(Event.RESIZE, onResize);
If you're trying to communicate between flash and javascript, ExternalInterface is the way to go. Rather that writing a cookie, just grab the information from javascript, and send it to flash via a callback.

dojo crashes ie6 when using Zend Framework

I'm having issues with a application that I am writing that uses Dojo and Zend Framework. The issue only effects Internet Explorer 6, other versions of IE, ff, chrome and safari work fine with no issues.
When IE6 lands on the login page it crashes with the send details to microsoft dialog box. The login script uses dojo to provide some validation for the users to ensure that their passwords are formatted correctly etc.
I've seen on some forums that addOnLoad() function call in dojo could be the cause and a window.setTimeout() would help. http://www.dojotoolkit.org/forum/dojo-core-dojo-0-9/dojo-core-support/dom-manipulation-addonload-crashes-ie6
The problem I have is how to manipulate the dojo header that we have in the layout.phtml in the application. We currently have in the file this code in the header.
<?php
$this->dojo()->setLocalPath($this->baseUrl().'/javascript/dojo/dojo.js');
$this->dojo()->addStylesheetModule('dijit.themes.tundra');
echo $this->dojo();
?>
This produces the following in the html.
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
dojo.require("dojo.parser");
dojo.addOnLoad(function() {
dojo.forEach(zendDijits, function(info) {
var n = dojo.byId(info.id);
if (null != n) {
dojo.attr(n, dojo.mixin({ id: info.id }, info.params));
}
});
dojo.parser.parse();
});
var zendDijits = [{"id":"username","params":{"regExp":"[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*#[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$","invalidMessage":"Please enter a valid email address","trim":"true","required":"true","dojoType":"dijit.form.ValidationTextBox"}},{"id":"password1","params":{"trim":"true","lowercase":"true","regExp":"^.*(?=.{6,})(?=.*\\d)(?=.*[a-zA-Z]).*$","invalidMessage":"Invalid Password. Password must be at least 6 alphanumeric characters","required":"true","dojoType":"dijit.form.ValidationTextBox"}},{"id":"submit","params":{"label":"Login","dojoType":"dijit.form.Button"}}];
How can I change this to try and add the fixes mentioned in the link, or is there another way to write this without IE6 crashing all the time?? I would prefer to fix this than remove all the client validation, just in case the client is using IE6.
thanks...
Can you reduce it down until you find what is crashing IE6? Save off your output as static html, confirm it still crashes IE and start removing code. Take that addOnLoad out altogether - does it still crash? if not, take out the forEach, and so on. Start removing elements from zendDijits array - is there one in particular that causes the trouble?
Is this a stock IE6? Any plugins/addons?
Your php there should be producing a script element to pull dojo.js. You've got soemthing wierd going on - that Zend code is known to work so we need all the information if you want to solve this.

Categories