Urban pro

View My Profile
Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Saturday, July 13, 2013

The magic of CSSPIE3 library


Hi friends,

Today i am gonna talk about an interesting tidbit that i came to know very recently.

The Problem :

I was working on installing a gradient for a page. For mozilla, the gradient was written as :

background: linear-gradient(to bottom, #ffffff 18%,#ecedeb 18%,#d1d5d0 100%);

And the pictorial view of that block of code comes up as something like this :

As you can see from above that the effect of the block of code is : the thick continuous red line that borders the element .

Now linear gradient cannot be used for the browser like IE8, as IE8 does not understand what it is. Hence we need to use filter here like :

filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#d1d5d0',GradientType=0 );

The element gradientType = 0 signifies that we here are talking about a linear gradient. That's how IE understands a linear gradient. Now the problem with that is, once such a style is implemented, IE super  imposes that with it's own styles, thus marring the whole effect , like in here :


As you can see from the picture above we get discontinuous red lines even after applying the filter.
So for a long time i was languishing under the knowledge that IE 8 is not letting me bring up the gradient properly.

Reason :

The problem with using filters is that they are old pieces of code of a bygone era. They are not very reliable/good. No one really used them until recently when we got first class gradients/opacity etc. IE's old filter styles are well known for having major bugs and quirks. Hence  i was pondering on the possible solutions when i suddenly came across the CSSPIE3  library.

The way out :

CSS3Pie library is a little Javascript lib that tries to add a few standard CSS features to old IE versions, including CSS gradients. It works internally by using VML graphics, not filter styles, which means that you don't get the bugs thatfilter causes . Hence all i needed to do here was use the linear gradient and couple it to PIE.js. 

I downloaded the PIE.js from : http://css3pie.com/ .

Now to use it , first i described my style in jsp inside a class like :

<Style type="text/css">

   .ieMasterStyle{
     background: linear-gradient(to bottom, #ffffff 18%,#ecedeb 18%,#d1d5d0 100%);
   }

<Style>

In my jsp , i referred to it as :

<td class='ieMasterStyle'>Border</td>

Now calling this one is a bit tricky and it is a two step process :

STEP 1 :

Include the PIE.js script in your page, surrounded by a conditional comment to prevent it from being downloaded in other browsers:

<!--[if IE]>
<script type="text/javascript" src="path/to/PIE.js"></script>

<![endif]-->

or, in case, you don't want to download it , but just want to refer it from a CDN than do this :


<!--[if IE]>
<script type="text/javascript" src="http://cdn.jsdelivr.net/css3pie/1.0.0/PIE.js"></script>
<![endif]-->

NOTE : Remeber to use PIE.js version 1.0 as it's the most stable version around.

STEP 2 :

Invoke the PIE.attach(el) function for each element that needs CSS3 styling. Make sure you do this after the page's DOM has been fully loaded. For example, using jQuery:


$(function() {
    if (window.PIE) {
        $('.ieMasterStyle').each(function() {
            PIE.attach(this);
        });
    }
});

As you can see from above , i have fed the ieMasterStyle that i created directly o PIE.js, where in the PIE.js will do it's magic and apply the linear gradient for us . Hence the finished product in IE 8 looks like this :



And thus i achieved browser consitency and PIE.js saved my bacon.

That's it guys. Bye .

Friday, January 11, 2013

Problems due to Same Origin Policy -- printing contents of a pdf from a url

This is one of the biggest problems .

Let us consider this scenario :

We have a url which hosts a pdf and we want  to print it from our web page on click of a button. It's at that point of time that we must look at Same Origin Policy.

What is Same Origin Policy : 

In computing, the same origin policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site – a combination of scheme, hostname, and port number – to access each other's methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites. Same origin policy also applies to XMLHttpRequest.

Let us consider these two urls :

http://www.example.com/dir/page.html  /  http://www.example.com/dir2/other.html --> Success since Same protocol and host

Since the above two urls have same protocol, host and domain, hence resource sharing is a possibility here .

However, if it would have been something like :

http://www.example.com/dir/page.html  /  http://www.goIbibo.com/dir2/other.html --> Failure

Now the above two links either don't share the same host or domain and hence it violates the same origin policy. So resource sharing here is not possible .

Workarounds :

To enable developers to, in a controlled manner, circumvent the same origin policy, a number of "hacks" such as using the fragment identifier or the window.name property have been used to pass data between documents residing in different domains. With the HTML5 standard, a method was formalized for this: the postMessage interface, which is only available on recent browsers. JSONP can also be used to enable ajax-like calls to other domains.

In other words, it is really difficult when you try to do that .

Consider a classic scenario :

As stated earlier you want to print a pdf hosted in another site from your web page. How can you do this ?

Well , let us say you have fished out a code like this ::

Inside your body tag you have this ::


<input type="submit" class="btn-red" value="Print"
name="Submit" id="printbtn"
onclick="printPDF('http://www.irs.gov/pub/irs-pdf/fw4.pdf')" />

Inside your head tag you have this ::


function printPDF(pdfUrl)
    {

    if ((navigator.appName == 'Microsoft Internet Explorer') )
    window.print(pdfUrl,"_self");
    else
    {
    var w = window.open(pdfUrl,"_self");
    w.print();
    w.close();
    }
    }

So you are trying to print the contents of the URL in  http://www.irs.gov/pub/irs-pdf/fw4.pdf using javascript. However, your web site and the host which hosts the pdf  are different . Hence this does not work.

Further more, window.print() always will print just the content of the current window and hence all you will see is your html mark ups and not the pdf.

So what do you do ?

Probably , now you will think, hang on, i can use this idea :


I can open an iframe and then call window.print() inside of it. I can probably get away with hiding the iframe by giving it position: absolute; left: -9999px.

This is the code that you make up :


function printPDF(pdfUrl) {

var iframe = document.createElement('iframe'),
iframeDocument;

iframe.style.postion = 'absolute';
iframe.style.left = '-9999px';
iframe.src = pdfUrl;
document.body.appendChild(iframe);

if ('contentWindow' in iframe) {
iframeDocument = iframe.contentWindow;
} else {
iframeDocument = iframe.contentDocument;
}

var script = iframeDocument.createElement('script');

script.type = 'text/javascript';

script.innerHTML = 'window.print();';

iframeDocument.getElementsByTagName('head')[0].appendChild(script);

}





But even this idea will not work as the pdf contents will never be available for windows to print, since it's a different host altogether.

Idea No  2 ::

Some people might think , let's have a print.css and let's set the display for every element to none except what i want to print. But whatever you do you are going to try to print using : window.print() only. So this will not work as well.

Idea No 3 ::

Now you will say that, alright man, okay i will use pdf.js and extract the pdf into text . Then i will re construct the pdf from the text on my side and then print it. But that idea will be a flop idea as well. It's because even pdf.js follows the same origin policy .

So is there no way of doing this ?
Hang on, now i did not say that.

The costliest way ::

The same origin policy can be bypassed using : CORS .

What is CORS :

It means Cross-site HTTP requests .

Cross-site HTTP requests are HTTP requests for resources from a different domain than the domain of the resource making the request.  For instance, a resource loaded from Domain A (http://domaina.example) such as an HTML web page, makes a request for a resource on Domain B (http://domainb.foo), such as an image, using the img element (http://domainb.foo/image.jpg).  This occurs very commonly on the web today : pages load a number of resources in a cross-site manner, including CSS stylesheets, images and scripts, and other resources.

How it works :

The Web Applications Working Group within the W3C has proposed the new Cross-Origin Resource Sharing (CORS) recommendation, which provides a way for web servers to support cross-site access controls, which enable secure cross-site data transfers.  Of particular note is that this specification is used within an API container such as XMLHttpRequest as a mitigation mechanism, allowing the crossing of the same-domain restriction in modern browsers.  The information in this article is of interest to web administrators, server developers and web developers.  Another article for server programmers discussing cross-origin sharing from a server perspective (with PHP code snippets) is supplementary reading.  On the client, the browser handles the components of cross-origin sharing, including headers and policy enforcement.  The introduction of this new capability, however, does mean that servers have to handle new headers, and send resources back with new headers.

So all this is fine and dandy but it is extremely difficult

Moral of the story : Don't try to do this. If you have a url , the contents of which you want to print , then host the same thing from your end. Things become much easier then. Otherwise, it will become very difficult a problem to handle .

I recently faced a similar problem, hence i have shared all my knowledge that i gathered while researching this . I sincerely hope it helps other people who are trying similar stuffs .

Good Bye .

Sunday, October 7, 2012

How to create a modal window ?

All right, so i was working with modal , modal overlay and some other stuffs, when it came to my notice that till now no good tutorial is available for beginners to make them understand the whole process sequentially. So, yours truly took the initiative to write about the process to create a basic modal window .

NOTE : This entire effort has been implemented on a JSP but users can use it anywhere else .

Let me first give you some important information. I was configuring my tomcat 7 with my eclipse indigo, when i found  a lot of problems while trying to figure it out. I had not done this since the college days and it seems few things have changed. People who are interested in doing it can follow this link : http://www.coreservlets.com/Apache-Tomcat-Tutorial/tomcat-7-with-eclipse.html  for configuring eclipse with tomcat 7(This is the best tutorial there is for that at present in www).

What is a dialogue ?

A dialog is a  default built-in behavior , but few methods are needed to control it pro-grammatically,  making this an easy to use widget that is also highly configurable and powerful.

What is a modal window ?

When your dialog box prevents the user from interacting  with the layout of the rest of your web page  if they don't close it manually, then it becomes your modal window.

So, how do we go about making it . Let me first give you the screen snaps for the code i had written :






Beware :

Whenever you are importing jquery.js and jquery-ui.js, remember to import jquery.js before jquery-ui.js, other wise you will get these errors :

jquery -- not recognized
('#id').dialog()  is not a function




Now let us understand the code that matters, shall we !

When you write :

$("#id").dialog(); -> you are actually trying to open a dialogue box and not a modal window, as you can still interact with the rest of the lay out of the page .

So how do i make it a modal window ?

Simple, to do this inside the dialog() method you have to provide --> modal : true. This tells the browser that you want the dialogue to be opened within a modal window to prohibit the user from interacting with the rest of the page.

But nobody will believe me if i don't show what it actually does . Okay, so let's see the screen shots below :

screen 1 : Before clicking on the blue date time link :


screen 2 : After clicking on the blue date time link :





Look at how the rest of the web page has become blurred and any attempt at trying to interact with the rest of the page will be a failure .

That's it for today folks.

I will see you all next time. Good bye .

Friday, October 5, 2012

Why using onload() in a body tag is a bad idea ?

                                         Let's go back to our innocent  years :

Keep Javascript unobtrusive :

To keep our Javascript unobtrusive we can keep it in a single file to avoid messing up the markup of the page. To execute the functions in our .js file, we need to call them when the page has loaded. This can be achieved in various ways and each has it's advantages and disadvantages  .

I am feeling a little nostalgic :

Back when we had just started messing around with Javascript  we used to add the onload to the body element, like this :

body onload = "callMyFunction();"

But, this is bad , real bad .

Why ? --> If we call the script(s) in the body element, we really achieve nothing, since we are still mixing markup and event calls.What we need to do is to separate the call out into a .js file.

I am all grown up :

Now the better way is to attach  the call to the onload event of the window object.

When we only use one function, we don't use the parenthesis at the end of the function name, as that would send back the result of the function rather than trigger the function.

If we have more than one function, we have to use an anonymous function that calls the others, this time with parenthesis.

This is achieved as :


window.onload=callMyFunction; //Notice that there is no ()

or

window.onload=function(){  //Here you need to give () as you are calling an anonymous       // function
 callMyFunction1();
 callMyFunction2();
 callMyFunction3();
}

This will prevent us from messing up our mark up of the page rendered .



Thursday, October 4, 2012

javascript - JQuery TypeError : Type Error

            

                                                               TYPE  ERROR

Most people face this error when they use an outdated jquery.js . Sometimes this error also comes up when someone tries to use jquery in jsp.

The most important thing here that a person must do is first use an upto date version of jquery.js . Don't worry u don't even have to download this stuff.

Just have this :



Now what else can be done, if you still get this error. Well, may be you can replace all the '$' symbols with 'jQuery'. Voila, your application will now start making use of all the jquery api s from its library perfectly.
Hence, instead of :
$('#id').click()
you will have :
jQuery('#id').click()
And everything will fall in place .