martedì 31 marzo 2015

How to open external links in the Cordova/PhoneGap inAppBrowser or system default browser using jQuery - tutorial for hybrid mobile apps on Android and iOS

While working at a hybrid mobile project with IBM MobileFirst (Worklight 6.3) and jQuery Mobile, I recently had the need to open an external link within a browser (embedded or external, it didn't really matter) in both Android and iOS.
Unfortunately, this task was not that simple. Writing a normal link, such as
<a href="www.mylocation.com" target="_blank">go to my location</a>
didn't work at all in Android. I clicked on the link, but nothing happened, even if it clearly specified target="_blank" (that is "open this link in a separate window"). No good! >:/
In iOS instead I had a more annoying behaviour: the link opened in a new, fullscreen window, and once the window opened there was no way to go back to my app.

After a few hours spent on google and stackoverflow, I finally came across a way to make the link open in the default browser for Android and in the Cordova InAppBrowser for iOS.

This is what you need to know if you're using Cordova 3.6.*, Worklight MobileFirst 6.3 and jQuery Mobile to make your mobile apps.


First of all, in the HTML format your link like this:
<a id="myLink" data-href="http://www.mylocation.com" href="#">your text</a>

Basically, put your target location (http://www.mylocation.com) in a custom attribute (data-href), so you don't lose it. Don't place it inside the href attribute, since this would trigger the default behaviour which is very annoying in iOS and flawed in Android!

Now use jQuery to open the link programmatically with Javascript. Here's the code you need in your javascript file:

$("a#myLink").on("click", function(){
    //Define the behaviour of your code when someone clicks on a link called "myLink"
    openLink($(this).attr("data-href"));

});

As you can see, openLink() is a function I have not yet implemented. To make your app work fine on both Android and iOS platforms, you have to define this function differently.

Function definition for Android apps:
function openLink(myExternalLink){
    window.open(myExternalLink, "_system", "location=no");
}
By writing "_system", you basically tell your app to open the link in the system's default browser.

Here's the function definition for iOS apps specifically:
function openLink(myExternalLink){
    window.open(encodeURI(myExternalLink), '_blank', 'location=no, toolbar=yes');
}

lunedì 9 febbraio 2015

Useful Tips and Tricks for Your jQuery Mobile Project

I've been using jQuery Mobile for quite a bit now, and yet there's always something new to learn about it. Once your mobile project goes beyond the boundaries of the typical jQuery Mobile app made of click-download-changePage, you'll need to remember a long and continuously-growing list of tricks in order to accomplish more complex tasks within your mobile application.
Well, guess what! I'm here to write it down for you (and for myself as well), so grab your popcorn and... thank me later ;)



Disable jQuery automatic styling for certain elements
If you want to stop jQuery from styling specific elements in your code, just apply data-role="none" to those elements. jQuery styling ignores every tag with such attribute.
Here's an example:
<input type="text" class="search" data-role="none">
This will create an input field with absolutely no default style. Simply use your own CSS to style it properly.

Create and call an external popup widget
Recycling your code is always a good practice. So why not create a single, external popup (by external I mean "outside your jquery mobile pages") to call everytime you need it? A good example of a reusable popup widget could be a login window, which comes in very handy if you plan to call it from more than one page.
Here's a nice example of a popup widget, with a unique id, popupLogin. To have an external popup, place this code inside the <body> tag (and, of course, outside the divs marked with data-role="page"):
<div data-role="popup" id="popupLogin" data-theme="a" class="ui-corner-all">
<h3>Login</h3>
<input type="text" id="username" placeholder="username">
<input type="password" id="password" placeholder="password">
<button id="loginButton">Login now!</button></div>
This will however create a popup widget that's not initialized yet. You'll have to instantiate it manually with:
$("#popupLogin").enhanceWithin().popup();
There it is! To open/close your popup, simply call:
$("#popupLogin").popup("open");
$("#popupLogin").popup("close");

Count how many list elements there are in a list
To get the exact number of elements inside a list (ul or ol, it doesn't matter), just call:
$("#yourList li").length
where yourList is the ID of your list. This basically tells jQuery to "select every <li> tag in the list with the id "yourList" and count them".
Let's give an example. Say you have this simple ordered list:
<ol id="yourList">
   <li>Item 1</li>
   <li>Item 2</li>

   <li>Item 3</li>
   <li>Item 4</li>
</ol>
Then the jQuery function:
$("#yourList li").length
will return 4, because there are exactly 4 list items inside your list. Nice and clean.

Display a simple fading popup message using plain Javascript
There are times using plain, vanilla Javascript is far more straightforward than using jQuery widgets.
Say you only want to display a small, informative message to the user, then make it fade out silently.
Here's the only code you'll need:
function myPopup(msg){
   var container = $(document.createElement("div"));
   container.addClass("toast");
   var message = $(document.createElement("div"));
   message.addClass("message");
   message.text(msg);
   message.appendTo(container);
   container.appendTo(document.body);
   container.delay(100).fadeIn("slow", function()
   {
     $(this).delay(1500).fadeOut("slow", function()
     {
        $(this).remove();
     });
   });
}

Here's the CSS to style your fake "popup" properly:
.toast {
    display: none;
    position: fixed;
    z-index: 99999;
    width: 100%;
    text-align: center;
    top: 10%;
    text-shadow: 0pt 0px 0pt rgb(0, 0, 0);
}
.toast .message {
    display: inline-block;
    color: #fff;
    padding: 20px;
    border-radius: 5px;
    font-family: Times, serif;
    font-size: medium;
    background: #333333;
    text-shadow: 0pt 0px 0pt rgb(0, 0, 0);
}
Whenever you need a small message to pop on top of your screen and then fade quickly, just call:
myPopup("Hello there!");
and you're done!

lunedì 3 novembre 2014

Common Problems and Issues When Using Display Tag Library - Whan Can Go Wrong? [java servlet/ jsp/ display tag library]

In this article you'll find a list of common issues I faced when I used Display Tag and how I actually solved them.
I'm pretty sure that this list is going to get expanded very soon :P


"Nothing found to display"
I first saw this message when I tried to test my pagination. The first page worked pretty well, but when I clicked on "next", "prev", "first", "last" or any other page number, I got this mysterious message.

When Display Tag shows "Nothing found to display", it actually means it: it cannot find any data to display. Where did you put it before calling Display Tag?
You probably didn't specify the scope of your list/array/whatever-container-you-used-for-your-data.
Here's how you can tell Display Tag where to get it:

List<MyBean> myData = ..... ; // get your data from somewhere, wrapped into an ArrayList
session.setAttribute("myTable", myTable); //pur your table in the current session
...
<display:table name="sessionScope.myTable" pagesize="25"
sort="list" uid="id" >
   [content of your table ...]
</display:table> 
 
As you can see, <display:table name="sessionScope.myTable" > tells Display Tag to retrieve your data from the current session (sessionScope). You can always specify a different scope, if necessary: just choose among pageScope, requestScope (set by default), sessionScope or applicationScope, based on your application needs.

Another situation where you can get a "Nothing found to display" message is when you retrieve your data by sending parameters to a servlet. If you have to write something like:
http://myHost:port/MyContext/Servlet?operation=getData

to obtain your data, then Display Data needs to be informed that there's a servlet to invoke. Here's how to do it:
<display:table name="sessionScope.myTable" pagesize="25"
sort="list" uid="id" requestURI="/Servlet" >


Just replace "/Servlet" with the name of your servlet and you're done!


Column sorting doesn't work correctly
I faced this problem when I tried to put more than one property in a single column, so Display Tag couldn't figure out which of those properties to sort.
A simple solution for this issue is specifying the exact property to be used for sorting, that's called sortProperty.

<display:column title="Column Title" sortable="true" sortProperty="mySortingProperty" >
[content of the column goes here]
</display:column>