How to create click-to-call phone number links in PhoneGap
When presented with this problem, my first instinct was to look through the PhoneGap API documentation to see if I could find a way to interact with the internal phone system. After reviewing the documentation, I wasn’t able to find the desired solution, so, I started thinking of other ways to solve this problem. After some contemplation, I realized PhoneGap runs using the UIWebView browser, which, is more or less Safari without a back button. This led me to my solution, I realized I could use the same methodology I would use with a mobile website to create the click-to-call buttons inside of my PhoneGap app.
The solution I came up with was to use the tel: URI-scheme that is found in most mobile web browsers including: iOS, Android, WebOS, Symbian, and Internet Explorer. Using this, I was able to create a simple HTML link using the following syntax:
<a href=”="tel:8009229999">(800) 922-9999</a>
This link when clicked will trigger the internal phone system either from a browser or from within PhoneGap to initiate a call to (800) 922-9999. I haven’t yet tested this strategy with PhoneGap on non iOS devices but I anticipate it should work in most if not all cases. I can say it working splendidly on the iOS app I currently have in development.
Solved: Problem Linking to Google Maps Using PhoneGap and Childbrowser Plugin
Today, I had an odd issue which took me a couple minutes to solve. I was trying to make a link from a PhoneGap iOS application to Google Maps. My intent was to have these links show using the Childbrowser plugin, which, I had installed and working for other links but for some reason Google Maps was loading as a blank page. I was using the Google Maps URL:
http://maps.google.com/?q=154 S. Madison Ave Spokane WA 99201
If I visit this URL in my browser it loads as expected, however, when I attempted to load the exact same URL in PhoneGap using Childbrowser it failed with no errors. I played around with the URL for awhile and finally determined that PhoneGap and Childbrowser won’t accept spaces in the URL. I didn’t test if this is a function of the UIWebView that is used to render code in PhoneGap or if this applies to mobile Safari as well but I would guess it probably has something to do with the UIWebView/Childbrowser combination. The problem was easily solved by modifying my URL to:
http://maps.google.com/?=154+S+Madison+Ave+Spokane+WA+99201
This problem is not limited just to Google Maps. Spaces and other non URL friendly characters will cause problems, so, make sure to properly encode your URL before sending it to Childbrowser. I should’ve done this in the first place but I was being lazy!
How to Make a Cross Domain AJAX Request with jQuery
I am currently working on a project that required me to make a cross-domain AJAX request using jQuery. This is a function that is disabled by default because of security implications, however, there is occasionally a need for this type of request. In this case, I need to load content from a remote URL or website similar to how you would load content using jQuery’s .load() function or using PHP’s file_get_contents() function.
/******************************************************************************** FUNCTION FOR CROSS DOMAIN AJAX REQUEST USING JQUERY 1.5+ ********************************************************************************/ function loadContents(url, callback) { //CONFIRM A URL WAS PROVIDED if(url) { //SET URL FOR YAHOO YQL QUERY var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + url + '"') + '&format=xml&callback=?'; //MAKE YAHOO YQL QUERY $.getJSON(yql,function(data) { //BUILD CALLBACK FUNCTION if(typeof callback === 'function') { callback(data.results[0]); } //WRITES ERROR TO LOG }).error(function(jqXHR, textStatus, errorThrown) { console.log(errorThrown); } ); //LOG ERROR IF NO URL WAS PASSED TO THE SCRIPT } else { console.log('No site was passed to the script.'); } } /******************************************************************************** SAMPLE USAGE ********************************************************************************/ loadContents('http://www.ziplineinteractive.com/frame/', function(results) { $('#wrapper').html(results); });
I have tested this function in IE, Firefox, Chrome, and Safari and it should allow you to make cross-domain AJAX requests in jQuery 1.3, 1.4, 1.5, 1.6, 1.7, and from what I been able to find online it should also be supported in 1.8, although, 1.8 is not available at this time.
Let me know how this works in your application.
Redefining or changing a PHP $_SERVER variable for an entire website.
Today, I was faced with the need to redefine a PHP $_SERVER variable for an entire application, made up of hundreds of PHP pages. In this case, I needed to redefine $_SERVER['DOCUMENT_ROOT'] for an entire website. The application was built by another company under the assumption that $_SERVER['DOCUMENT_ROOT'] would always point to the document root, however, on some virtual servers this is not the case. The solution actually proved to be very easy, and could be used to redefine other PHP $_SERVER variables as required.
Solution:
Step 1:
Create a PHP file, in this case we are naming it document_root.php. The PHP file should contain the following code (Make sure to replace our path with your path to your document root):
<?php $_SERVER["DOCUMENT_ROOT"] = "/usr/local/www/htdocs/domainname.com/www"; ?>
Step 2:
Add the following code at the top of your .htaccess file (Make sure to replace the document_root.php with your file. If your file is nested in a directory include the file path as well):
php_value auto_prepend_file "document_root.php"
Reload your website and poof, Apache will parse the document_root.php file and set the $_SERVER['DOCUMENT_ROOT'] value on every page you load.
Note: If you are redefining a different global variable or multiple global variables you can revise the PHP file accordingly.
How to get Fixed Header and Footer Toolbars in jQuery Mobile 1.0
At Zipline Interactive, we have been doing mobile websites for a number of years. When we originally started building them, most customers were satisfied with a very simple website but as the mobile market has grown and more and more users have smartphones, many customers expect their mobile website to function much like a mobile app. In addition, tools like PhoneGap and Appcelerator have provided web developers with the ability to create cross platform mobile applications using HTML5 and Javascript. The key with developing mobile websites or applications using web technologies, is mimicking the devices user interface and animations for a consisten user experiene. There are a number of great Javascript frameworks designed to assist with this task. As I have worked with and tested these platforms my clear favorite is jQuery Mobile. It has a great deal of momentum and support, plus I am already a heavy jQuery user so the learning curve is very low.
One of the the biggest problems facing mobile web developers is the ability to create fixed headers and footers on mobile websites and HTML5 powered mobile applications. The problem is caused by the lack of standard support for the CSS properties position:fixed and overflow. Originally, these were not supported because they interfered with the touch interactions of the phone operating system but as of iOS5 and Android 2.1 there is rudimentary support for position:fixed. If you would like to see the level of support for these properties in the various mobile browsers, there is a handy chart available here: http://e.com/css-fixed.
The good news is that default support is on the way. The bad news is that it is not here yet. Regardless of the mobile platform you are targeting, there will be a large percentage of users that are unable to use your interface properly if you rely on position:fixed or overflow. In jQuery Mobile, there is a default solution. They have built in toolbars that mimic a fixed header and footer by fading out and repositioning as the screen moves. While this is an improvement, it is still not a solution for a developer wanting a native app look and feel.
So what is the solution?
After a great deal of research and testing I found there were two primary solutions for this problem being used by fans of the jQuery Mobile platform. They both use Javascript to modify the elements and mimic the scrolling functionality of a native application.
Solution 1: iScroll jQuery Mobile Plugin
URL: https://github.com/yappo/javascript-jquery.mobile.iscroll
This jQuery Mobile plugin is a wrapper for the iScroll Javascript function. (http://cubiq.org/iscroll-4) This plugin is made up of a single file that drops in to your HTML and then is initiated by adding ‘data-iscroll=”scroller”‘ to the element you want to scroll. This plugin was very easy to setup and worked, however, the animation was slow on android applications and when loading websites on the iPhone I had a persistent space at the bottom of the page that I could not remove. I believe it was caused during loading by the default iPhone toolbars but I am uncertain. I searched online and wasn’t able to find a suitable solution. Many users have reported this solution worked well for them and several indicated they were using it successfully with the PhoneGap platform.
Solution 2: Scrollivew
URL: http://jquerymobile.com/test/experiments/scrollview/
Download URL: https://github.com/jquery/jquery-mobile/tree/master/experiments/scrollview
This jQuery Mobile plugin is actually sponsored by jQuery and is currently listed under their experiments section on the jQuery Mobile website. It was a bit harder to get running. It required 4 files, 3 Javascript files and 1 CSS file, although, I was able to lump them together into existing application files to minimize HTTP requests. This solution worked very well for my application. After installing the scripts I simply added data-scroll=”true” to the element I wanted scrollable and the plugin took care of the rest. One important thing to note about this solution, is that in addition to simple fixed toolbars, this plugin also allows scrolling of on page elements left or right and can also handle scrollable lists with inline headers.
My Conclusion:
After extensively testing both of the primary scrolling options for jQuery Mobile I feel like the jQuery Mobile Scrollview is the best solution. It was very easy to install and configure, offered great support on iPhone and Android devices, and has more options and configurations available to customize your application. In addition, it may at some point be integrated into jQuery mobile as default functionality to serve as a bridge until position:fixed and overflow are full supported by the majority of active smartphones.
Photos from Sun Mountain Lodge in Winthrop Washington
My wife and I recently stayed at Sun Mountain Lodge in Winthrop Washington for a marriage retreat through our church, Life Center Church in Spokane Washington. The trip was very educational and fun. This was the second consecutive year that our church marriage retreat took place at Sun Mountain Lodge. In addition to being at a great lodge, this year we were fortunate enough to get a very nice room. Our room was quite large and came with a great view, a jetted tub, a living room, and a warm gas fireplace. This year, we were also blessed with some nice weather and amazing fall photography conditions. I snapped a quite a few photos of the lodge and surrounding areas and have included them in a gallery below:
Accurate Cross Browser Testing With BrowserStack.com
The worst job for any web developer is testing your creations across browsers. Until now, there has been no good way to test a website in various versions of IE, Firefox, Chrome, and Opera. When installing an updated version of each of these browsers your older version goes away. For many developers, this means you have to run special software packages that allow you to run various browser versions in conjunction or in the case of Mac users like myself you needed to keep an old PC around or run a version of Windows on your Mac. (Blah Yuck) To make matters worse, the addition of IE9 compounded this problem because it wouldn’t run on older versions of Windows often required to run IE6.
Thankfully, after years of waiting there is finally a viable solution to this problem, enter BrowsersStack.com. BrowserStack is a tool that lets you load up a browser complete with debugging tools running natively on a computer somewhere in the cloud. Unlike some of the screenshot services that have been around for awhile, BrowserStack allows you to actually interact with the website through the browser providing full Javascript testing abilities. You can do all of this directly from your Mac or PC development computer through a web-based interface.
I have been waiting for a tool like this for quite some time. I have been using BrowserStack for a couple weeks and have been very satisfied. The service is still currently in beta but you can request to be included in the beta here: http://www.browserstack.com/. The Service costs $19.99 a month and is well worth the money for me.
Cool Photos from West Medical Lake
I snapped a couple of cool photos last Sunday morning at West Medical Lake. West Medical is just a couple miles from my house and a great fishing hole. Enjoy.
Remove Unnecessary Querystring From .htaccess 301 Permanent Redirects
Today I ran into an odd problem while trying to create permanent redirects on a website to help with search engine optimization. The website I was working on used a fairly standard URL rewrite rule that rewrite all portions of the URL to a querystring and then the application handled the querystring internally. This methodology is common in many CMS systems and also in the popular Codeigniter framework. When I attempted to use standard .htaccess 301 permanent redirects they would add an unexpected querystring to the URL containing the previous URL that we were rewriting.
To illustrate the problem. I was attempting to rewrite /old-page to http://www.website.com/new-page and when the redirection occurred I would get something along the address of http://www.website.com/new-page/?url=old-page.
I couldn’t figure out a solution for the problem using standard redirects such as:
Redirect 301 /old-url http://www.website.com/new-url
I tried different variations and position and nothing seemed to work. After some experimentation I decided to approach the problem from another direction. Instead I created a RewriteRule to handle the rewriting and then included two designations [L] indicating this is the final rule and to tell apache to stop looking for additional rules if this condition is met and then I specified [R=301] indicating this is 301 redirect. (CAUTION: Do not just use [R] as this is recorded as 302 redirect which is not a preferred redirect type for SEO)
The final redirect looks like this in .htaccess and seems to work as expected.
RewriteRule ^old-url?/?$ http://www.website.com/new-url [L,R=301]
There are likely other ways to approach this problem but this one is working great for me. Let me know if you have any problems implementing this methodology into your .htaccess file.
How to Detect a User’s Language with PHP
I was recently looking for a simple way to automatically detect a user’s language using PHP. There are a number of ways this could be accomplished but after some thought I realized the easiest is to get that information from the users web browser. Users are most likely to browse the web in a language they are comfortable with and your browser will send your accepted language in the HTTP headers when loading a page. After some quick research we realized this is indeed correct and the data is contained within the $_SERVER object, it just happened to be one of the variables we hadn’t used previously.
I put together a quick snippet below that extracts the two digit language code and stores it as a variable. You could use this to load different content, to redirect to another version of the website using the proper language, or to sculpt the user experience.
<?PHP //EXTRACT THE TWO DIGIT LANGUAGE CODE FROM THE HTTP HEADERS $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); ?>





































