Thursday, May 14, 2015

Deploying dojo in Apache Tomcat

-->
Well this is something that I did not want to reinvent and so I searched for the same in the internet aggressively for hours. Guess I am a little dumb. Though I found pages relating to the same, I did not find what I was looking for and instead I found this advice in multiple pages. Guess I am a little smart to understand this advice and hence I ended up working on it and found something that I can remember for a long time J. Really feels a little happy insideJ
My aim is to deploy dojo somewhere in the root directory of the tomcat server, so it becomes automatically available for all the applications that are deployed in the server. I had previously done such things using IIS servers and lotus domino servers. Lotus domino servers have classy ways and it actually comes with dojo inbuilt. Well trying not to deviate from the topic, actually I did not find a solution and ended up finding a work around.
I understand that the Dojo files needs to be deployed in the eclipseWorspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps directory to be available to the apps in the workspace. I know I can write software to do that and I know it could be the most dumbest thing I would have done in a long time. lol.
 
So I tried creating a separate web project which serves as a content management system for dojo and tried including the same in my other apps. The problem is though they worked, the huge size of dojo and its allied packages like dgrid 40+ MB really messed with my patience when the server had to republish them every time.
 
Necessity is the mother of all inventions, someone said. I know I did not invent this, but atleast reinvented it lol, created a separate workspace, with a separate server serving dojo packages and used them in my other workspaces holding my apps which required dojo.
 
Hurray, that’s my answer. lol. Stop, stop!!! don’t scold me.
 
Create a new workspace and create a new dynamic web application. Now import the dojo folder into the webContent folder of that app as illustrated by the following screen shot
Add your dojo application to the server, by right clicking on the server and click on “add or remove” and run it as illustrated by the following screen shot.
 
 
Now go and include this dojo package in your application as illustrated in the following screen shot
Hope you don’t scold me now. At least it’s what I use :@

Tuesday, May 12, 2015

A simple dojo JSONP example

Well I almost got sick of find out the missing link. The missing link I am talking about is something like “What the hell am I missing for a dojo JSONP request to work?” as I was trying those examples provided in dojotoolkit.org. 
Thanks to the post by Jason Schock  titled “So how does JSONP really work?”. With little tinkering I understood how native plain JSONP requests work.
All that was provided in the dojotookit websites says to use jsonp:’callback’ in the script request and that kept failing miserably even though I was able to see responses in the chrome’s developer tool->network tab->response tab of urls that have been hit from the page.
So the trick is to define a variable whose scope is available for both your dojo’s request – script’s jsonp request and callback function definition.
Following is my html file that creates this Jsonp request to a data.jsonp.js file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Dojo Topic</title>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.6/dojo/dojo.js"
       data-dojo-config="async: true"></script>

<style>
.output {
       border: 2px solid green;
       margin: 10px;
       padding: 10px;
       color: #eeeeee;
       background-color: #000000;
       width: 500px;
       min-height: 200px;
}
</style>
<script>
       var jsonpRespData = null;
       require([ "dojo/request/script", "dojo/dom", "dojo/dom-construct",
                     "dojo/json", "dojo/on", "dojo/domReady!" ], function(script, dom,
                     domConst, JSON, on) {
             
              on(dom.byId("startButton"), "click", function() {
                     domConst.place("<p>Requesting...</p>", "output");
                     script.get("/DojoCracker/data/data.jsonp.js", {
                           //jsonp : "dojo_request_script_callbacks.dojo_request_script0",
                           query: {
                                  "callback" : "mycallback"
                   }
                     }).then(
                                  function(data) {
                                         domConst.place("<p>response data: <code>"
                                                       + JSON.stringify(jsonpRespData) + "</code></p>",
                                                       "output");
                                  },function(error) {
                                         domConst.place("<p>Error: <p>"
                                                       + error.response.text + "</p></p>",
                                                       "output");
                                  });
              });          
       });
      
       function mycallback(data){
              jsonpRespData = data
       }
</script>

</head>
<body>
       <h1>Output:</h1>
       <div id="output" class='output'></div>
       <button type="button" id="startButton">Start</button>
</body></html>
The closure in the my data.jsonp.js file as  follows
//dojo_request_script_callbacks.dojo_request_script0({ - will come to this later
mycallback({
              "identifier" : "abbr",
              "label" : "name",
              "items" : [ {
                     "abbr" : "ec",
                     "name" : "Ecuador",
                     "capital" : "Quito"
              }, {
                     "abbr" : "eg",
                     "name" : "Egypt",
                     "capital" : "Cairo"
              }, {
                     "abbr" : "sv",
                     "name" : "El Salvador",
                     "capital" : "San Salvador"
              }, {
                     "abbr" : "gq",
                     "name" : "Equatorial Guinea",
                     "capital" : "Malabo"
              }, {
                     "abbr" : "er",
                     "name" : "Eritrea",
                     "capital" : "Asmara"
              }, {
                     "abbr" : "ee",
                     "name" : "Estonia",
                     "capital" : "Tallinn"
              }, {
                     "abbr" : "et",
                     "name" : "Ethiopia",
                     "capital" : "Addis Ababa"
              } ]
       });


So here is the explanation.  When you look into the html code you will be able to find the following
<![if !supportLists]>1.       <![endif]>First a variable is simply declared and initialized to null – “var jsonpRespData = null;”
<![if !supportLists]>2.       <![endif]>Then comes the dojo code with jsonp callback definition -
query: {"callback":"mycallback"}
<![if !supportLists]>3.       <![endif]>Then there is this function definition mycallback(data)
<![if !supportLists]>4.       <![endif]>Then back in the jsonp success callback I use - JSON.stringify(jsonpRespData)

And that’s what I see on the screen

So why bother this much when its not documented in the dojotoolkit website. Well when I use the param jsonp:’callback’ as such as described in the dojotoolkit website, I see the following on the screen
And this error on regarding the closure defined in the data.jsonp.js  file and I don’t get a hold on the response even though I see it in the response and preview tab
Well something tells me that I still miss a link o.0

This e-mail and any files transmitted with it are for the sole use of the intended recipient(s) and may contain confidential and privileged information. If you are not the intended recipient(s), please reply to the sender and destroy all copies of the original message. Any unauthorized review, use, disclosure, dissemination, forwarding, printing or copying of this email, and/or any action taken in reliance on the contents of this e-mail is strictly prohibited and may be unlawful. Where permitted by applicable law, this e-mail and other e-mail communications sent to and from Cognizant e-mail addresses may be monitored.

Ajax in dojo are deep

Really there is so many concepts and ideas in Ajax and I could just get a glimpse of what dojo seekers end up understanding. Awesome man. Just awesome. I have been using Ajax for a long time now and I can see that dojo has a handful of nice utilities which a developer using AJAX would need. This definitely will make life much easier and maaaannnnn…. m amazed

New bees to ajax will end up learning about the following concepts
xmlhttp.open("POST","ajax_test.asp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");
responseText  get the response data as a string
responseXML   get the response data as XML data
onreadystatechange   Stores a function (or the name of a function) to be called automatically each time the readyState property changes
readyState    Holds the status of the XMLHttpRequest. Changes from 0 to 4:
readyState  0: request not initialized
readyState 1: server connection established
readyState 2: request received
readyState 3: processing request
readyState 4: request finished and response is ready
status 200: "OK"
       status 404: Page not found
And I thought I was better than the new bees as I knew something about success responses, timeouts, error responses, promises etc. Thank god, I am wrong. Going through the list of available topics in dojo alone says how much I had never used and never even thought of using.

<![if !supportLists]>·     <![endif]>dojo/request - The whole Dojo Request API
<![if !supportLists]>·     <![endif]>dojo/request/xhr - The default provider for a browser based platform
<![if !supportLists]>·     <![endif]>dojo/request/node - The default provider for the node.js platform
<![if !supportLists]>·     <![endif]>dojo/request/script - A provider that expects the response to be embedded in a <script> tag.
<![if !supportLists]>·     <![endif]>dojo/request/handlers - Handles the data from a response as designated in the handleAs request option. Also provides the ability to register additional types of handlers.
<![if !supportLists]>·     <![endif]>dojo/request/registry - Allows for registration of different providers against different URIs.
<![if !supportLists]>·     <![endif]>dojo/request/notify - Publishes the dojo/request topics for requests.
<![if !supportLists]>·     <![endif]>dojo/request/watch - Allows the watching of inflight requests.
<![if !supportLists]>·     <![endif]>dojo/request/iframe - A provider that uses IFrame for transport
<![if !supportLists]>·     <![endif]>dojo/Deferred - The base class for managing asynchronous processes.
<![if !supportLists]>·     <![endif]>dojo/promise - The package that provides the Dojo Promise API.

-->

Handling security errors due to Cross Domain Ajax (JSONP)

Some basic issues that I face while working with iframes include t not limited to the following,

1.       Unable to access iframe – document object

2.t  when I am unable to access iframe’s document object or vice versa, the issue could be due to browser settings or because the url in the child frame belongs to a differennts in ed from different servers whose urls were similar to the following

http://********.xtss.com:8080/JSONP_Consumer/ParentFrame.html  and

http:// ********.xtss.com:8090/JSONP_Store/iframeContent.html

Observe closely. These two urls belong to two different servers. Running on different ports.

To ensure smooth communication between the two webpages, I had used the following trick

document.domain="xtss.com"; //should be subset of domain name in host name

Don’t worry about the dojo code that you will find on the page. Dojo has nothing to do with the trick. Its just that I had used it to write a logic to find and hide a button in the parent window. One can always use native javascript or other libraries like jquery to do that.

Now put the following in ParentFrame.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

<script>

 

document.domain="xtss.com";

 

</script>

 

 

</head>

<body>

       <button id='trg'> Hide target </button>

       <iframe src='http:// ********.xtss.com:8090/JSONP_Store/iframeContent.html'></iframe>

</body>

</html>

 

And put the following code in the iframeContent.html

<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

 

<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js"

            data-dojo-config="async: true"></script>

           

<script>

 

document.domain="xtss.com";

 

/* function clickme()      {

       console.log('inside click')

       window.parent.document.getElementById('trg').style.display='none';

} */

 

var changeStyles;

require(["dojo/on",

         "dojo/dom",

         "dojo/_base/window",

         "dojo/query",

         "dojo/dom-style",

         'dojo/domReady!'],

              function(on, dom, win, query, domStyle){

                          

                  changeStyles = function(){

                    

                     var targetIDinParentScreen='trg';

                     var pageToRedirectTo='/JSONP_Store/dummyPage.html';

                      var parentDoc = window.parent.document;

                     

                      win.withDoc(parentDoc, function(){

                             var hideTarget = query("#"+targetIdInParentScreen)

                             domStyle.set(hideTarget[0], "display", "none");

                      });

                     

                      window.location.href=pageToRedirectTo;

                  };

              });

             

</script>

 

</head>

<body>

 

 

 

<a id="eventSource" href='javascript:changeStyles()'> click me</a>

 

</body></html>

 

Now when you try to reload a frame with a different url, make sure you donot use sites like “Google.com” as they won’t open inside an iframe. They always check that they are on top and don’t let iframes use them. So for that sake I am creating my own page – a dummyHTML file

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head>

<body>

Dummy Page

</body>

</html>