AIAIO: Our Blog

AIAIO: Our Blog

The pulse and reviews of Alexander Interactive

Archive for October, 2011

Pew Study Highlights Growing Tablet Use

Last week BGR posted a great infographic visualizing the results of a Pew study on how tablet users are consuming their news. The findings of the research confirmed findings by Forrester, specifically that people who own tablets use them – a lot. According to the study 77% of tablet owners use their tablets daily.

The study also showed that tablet owners spend an average of 95 minutes per day on their tablets. With Apple reporting record iPad sales (over 11 million sold last quarter), these findings show that e-retailers can only expect the amount of visits from tablet-wielding consumers will continue to grow exponentially.

Some of the most interesting numbers coming out of the study centered around the use of native apps versus mobile browsers. Almost twice as many responders reported using mobile browsers as their main news source compared to apps (40% for browsers, 21% for apps), which shows the importance for having sites optimized for tablet users.

As shown in Ai’s T-Commerce Report, even the largest internet retailers are still struggling to capture this up-and-coming demographic. This report shows that while a few retail giants have capitalized on the t-commerce market with responsive designs, larger calls to action and gesture friendly interfaces (Nike is a prime example), most e-commerce giants are falling behind the curve when it comes to t-commerce. Even Amazon is showing slow adoption of t-commerce best practices in its new redesign; though their new fashion deal site, MyHabit, is highly optimized for t-commerce.

For more on how you can optimize your site for t-commerce check out Alex’s article “Make Way for T-Commerce” or download the T-Commerce Report.

Ecommerce

Solving the IE 7, IE 9 Magento & Prototype Validation Bug

UPDATE: Read this first please…

After receiving some comments from fellow web devs [see comments between 10/26 and 11/11], I decided to integrate some of their changes. I’ve also included some enhancements via my colleague, Tom Rosario. They include a couple of updated variables (hopefully eliminating any headaches with the original ‘fieldsFilled’ infinite increment issue) and a regEx that validates the the email field, once (or if) the core validation fails.

For the rest of you…read the original post [below] to gain a little background/perspective and see if this suits your current issue. Feel free to challenge me and post fixes/improvements (We’re all fighting the same [grunt, groan, teeth-gnash] IE-quirks-battle after all ;) I will also be in the process of trying to find inconsistencies and will update accordingly if I find them.

[original post below]

Hey there fellow Magento-ers,

Have you been spending countless hours scouring the internet for a solution to this odd problem, in Magento, where you use the built-in Prototype validation to validate your form and it does not? And by ‘does not [validate]‘ I mean that in Internet Explorer 7 AND 9 (of course) it manages to ‘validate’ your empty fields, when attempting to submit an empty form, and then immediately disregards this ‘validation’ and just submits the form anyway….

Annoying, right? Can’t seem to get around it, right?

Well, have no fear! I’ve already ruined my own life, productivity and sanity in order to bring you this very specific and (I think) simple solution. I wrote (with the help of my pal Tom Rosario) a little unobtrusive Class-based function to handle it!

Just to give you some background, and to ensure I’ve been as thorough as possible, I’d like to list the things I’ve already attempted and failed at. This includes both my own solutions and those suggested by experts on the web:

  • Stopping the page from loading via the location and window object: simply doesn’t work
  • Changing the version of prototype: messes up all kinds of things in Magento, namely, checkout…so don’t do it
  • Using jQuery validation: same issue occurs
  • Using the IE 7/IE 8 compatibility meta tag: should work, but I never had success with it

Now that we’ve covered some of my futile attempts, let me tell you what I know worked; putting a good, old-fashioned ‘ onsubmit=”return false” ‘ on the form itself. This, of course, is only half the work. You then need to remove this, once the validation is satisfied and only if all the required fields are filled. In my humble opinion, this is (currently) the best solution because we’re allowing the built-in validation to still do it’s thing, with an extra layer of validation to prevent any unwanted results. The best part of this is that it doesn’t negatively affect functionality in the other browsers (FF, Chrome, Safari), who weren’t experiencing this problem in the first place. [raised eyebrow]

So speaking of that extra layer, the approach is really quite simple; we prevent the form from submitting anything if all the fields with the ‘required’ classes are empty, then remove that constraint once they’re filled/validated. Prototype validation is still able to do it’s thing, and when it’s done, and all other aspects are satisfied, we go ahead and take the ‘return false’ off the form and let it submit. Pretty simple right? I’m surprised myself that it was that easy.

Here’s the Class:

/* FormValidator Fix for IE7 & IE9 */

var ie7 = $j.browser.msie && $j.browser.version=="7.0";
var ie9 = $j.browser.msie && $j.browser.version=="9.0";
var safari =$j.browser.safari;
/*--------------------------------------------------------------------------*/

var FormValidator = function (form, opts) {
	this.form = $j(form);
	this.required = form.find('.required-entry');
	this.defaults = {
		email: form.find('.validate-email')
	};
	this.options = $j.extend({}, this.defaults, opts);
	this.setup();
};
FormValidator.prototype = {
	setup: function () {
		var self = this;

		this.form.submit(function () {
			self.onSubmit();
		});
	},
	validateEmail: function () {
		var emailCheck = this.options.email.val().match(/^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i);
		if (emailCheck != null) { return true; }
		else { return false; }
	},
	onSubmit: function () {
		var self = this, numFilled = 0;
		this.required.each(function (idx) {
			if ($j(this).val().length > 0) {
				numFilled++;
			}
		});

		var valid = this.validateEmail() && (numFilled == this.required.length);
		if (valid) {
			this.form.removeAttr('onsubmit');
			this.form.submit();
			return true;
		} else {
		/*uncomment the alert below to test your numFilled variable
		if all is going well it shouldn't increment and match the
		number of required inputs you have*/
		//alert(numFilled);

		}
	}
};

Here’s the Call (put this below your form markup):

<script type="text/javascript">// <![CDATA[
	var contactForm = new VarienForm('myform', true);
if (ie7 || ie9 || safari) {
    $j('#myForm').submit(function(e){
        if ($j('#myForm').find('.required-entry:input[value=""]').length <= 0 ) { this.submit(); }
    });
    new FormValidator( $j('#myForm') );
} else {
    // remove the 'onsubmit' and don't run the function, as all non-IE browsers don't seem to have this bug
    $j('#myForm').removeAttr('onsubmit');
}
// ]]></script>

It’s really that simple kids. Please feel free to add a comment and let me know if this didn’t work for you, or if you’d like to add something.

Technology

What do you listen to? (podcast edition)

I tend to listen to a decent number of podcasts. Usually while doing the dishes, running, or something or other in the park.  Some are book/comic related and help me keep up to date with what’s coming out and how some books were that I didn’t have time to read.  Others are tech and help me get other opinions on the new libraries or trends.  I’ve found a number of fun libraries/how-tos from listening. Check them out below, what do you listen to?

Tech

Non Tech

* I listen to every episode, others I cherry-pick

Technology

UX Critic: Highrise and LinkedIn

I am an unabashed fan of 37 Signals’ Highrise contact management tool. For concentrated, straightforward sales and CRM, it’s an ideal web app. Between notes, contact information and useful task reminders, it’s a key part of how Canopy does business, and by and large it’s a delight to use.

Today Highrise rolled out LinkedIn profile integration, a nice idea that they say has been regularly requested. But the implementation is cumbersome and disappointing to the point where I’m probably not going to use it.

Here’s why:

It’s reactive. LinkedIn profiles are only added to Highrise profiles once the user has pasted the appropriate link from LinkedIn into a text field in the contact’s edit screen. There’s no dynamic list generation, no scanning the LinkedIn database, and more importantly, no recognition of post-login URLs. Which means…

It’s cumbersome. For each contact, I have to go to linkedin.com, find the right individual, click through to his or her full profile page, and copy the public link off the web page to add to Highrise. Grabbing URLs out of my status bar won’t work, because Highrise can’t reconcile them. (I suppose one could just find public profiles via Google, but that doesn’t seem practical at all.)

It's David! No, it's Reid!It’s account-reliant. Despite the need to use public profile links, Highrise and LinkedIn require users to log into both systems to coordinate data. But:

It’s not relational. Highrise doesn’t care if you have connected with the people whom you access on LinkedIn-via-Highrise. It also doesn’t care about your accuracy. I had no problem, for example, dropping LinkedIn CEO Reid Hoffman’s LinkedIn profile onto my own Highrise contact page. This doesn’t much matter when it’s being manually updated, assuming the user is careful, but it’d sure be nice to hit the right David Wertheimer by cross-referencing company, title and location data between the two services.

This seems like a great idea missing some key integration points that would make it as practical and useful as the rest of the system.

UX

Creating a Stateless Request in Magento

Have you ever wanted to create a stateless request in Magento? Something that doesn’t touch any of Magento’s sessions?  We were having issues with some of the ajax calls on our cart and checkout pages mucking with the user’s cart and had get stateless on these calls.  The issue we were having was our checkout page was loading, then a javascript include was going out and bringing code from a 3rd party relevance engine into our dom, which was in turn calling back an ajax request to our servers.  This issue with this being that at the start of the page load, the checkout session was being set to a certain state.  This state was then being sent through the rest of the page load, and the ajax calls. Unfortunately, by the time the ajax call got back to our server, the session was different in both locations, creating a race condition.  The ajax request usually won, removing the work the full page load had done with trying to process checkout.  The good news was there was nothing in the ajax call that needed to touch the session, it was just some data lookup. So, nix the session part of that call, and our troubles should be over… Magento’s api controller is the only place that implements a stateless request this but its fairly easy to do (after a bit of digging).

As long as Mage_Core_Controller_Varien_Action is a parent in your controller’s hierchy, you are good to go (it probably is).  This class has a const FLAG_NO_START_SESSION which looks promising. Digging into the code a little we see that it controls whether cookies are processed or the session is started:

<?php
...
        if (!$this->getFlag('', self::FLAG_NO_START_SESSION)) {
            $checkCookie = in_array($this->getRequest()->getActionName(), $this->_cookieCheckActions);
            $checkCookie = $checkCookie && !$this->getRequest()->getParam('nocookie', false);
            $cookies = Mage::getSingleton('core/cookie')->get();
            if ($checkCookie && empty($cookies)) {
                $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, true);
            }
            Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace))->start();
        }
view raw gistfile1.aw This Gist brought to you by GitHub.

By adding to the preDispatch() method of our Action or Controller we can toggle this:

<?php
class Ai_AjaxCatalog_Controller_Action extends Mage_Core_Controller_Front_Action
{
public function preDispatch()
{
$this->setFlag('', self::FLAG_NO_START_SESSION, 1); // Do not start standard session
parent::preDispatch();
return $this;
}
}
view raw gistfile1.aw This Gist brought to you by GitHub.

Now, any action in this controller will be stateless and not effect any sessions.

Technology

Ai Does Some (More!) Good

As I prepare for an upcoming charity weekend, I thought it an apt time to reflect on and share some of the remarkable events we’ve been involved with recently.

In May, Chief Experience Officer and cofounder Josh Levine, his wife Paulina, and 20 fellow ai’ers strutted the streets of New York City with March of Dimes’ March for Babies. Team Levine raised over $40,000 this year, bringing its all-time total to an inspiring $125,000 towards preventing premature births and finding solutions to the problems that threaten our babies. It was a memorable experience for those who were able to join on walk day, and we are already looking forward to next year’s event.

Jess Levy, Senior Project Manager, had a busy summer with a mud run raising money for the National MS Society and Fight Gone Bad, a charity workout benefitting the U.S. Armed Forces Special Operations community. She also participated in Long Island’s Ovarian Cancer Walk.

As a committee chair of the Young Professionals Board of Urban Pathways, I assist homeless New Yorkers increase their likelihood of living independently. I co-hosted a breakfast at Ivan Shapiro House, a residence for formerly homeless, mentally ill New Yorkers, to kick off our series of social events and am back at it this week with a card game night (I’ve been honing my strategy at War).

But this month, whether you’re shopping, watching football or just walking down the street, you’re bound to notice a little more pink around town. October is National Breast Cancer Awareness Month (NBCAM).

Every three minutes a new case of invasive breast cancer is diagnosed. Although survival rates are on the rise, every 13 minutes a life is taken by this terrible disease.

Throughout this month, Ai is doing its part to help decrease those figures.

This weekend I will be staffing the two-day, 39.3-mile Avon Walk for Breast Cancer as thousands of dedicated walkers trek from Pier 84 to Randall’s Island and back again.  The money raised provides access to care and funds research leading to a cure for breast cancer.

Later in the month, Jess will also join the cause at Barbells for Boobs benefiting Mammograms in Action (MIA). MIA is a non-profit organization that provides screening and early detection tools for low-income and uninsured women and men.

Whether raising funds, awareness, or simply remembering the importance of self and annual exams, Ai invites you to join us in the fight against breast cancer. For more information check out the NCBAM’s website or the American Cancer Society.

Ai

Ai Releases its T-Commerce Report

Ai T-Commerce Report

This morning Ai released its T-Commerce Report, a best practices guide for tablet-based UX design and t-commerce review of the ten largest retailers on the web.

We’ve written about the importance of t-commerce UX optimization before on the blog (and E-Commerce Times) and reviewed Amazon’s redesign from a t-commerce perspective. The T-Commerce Report goes into more depth on how the top-selling sites on the internet are adapting to a tablet based future and how you can do the same. Check it out here.

Gadgets