651.288.7000 info@intertech.com

In my last post I went over a common solution to fixing the viewport on the Windows Phone so that fixed headers and footers aren’t cut off. This post is going to address a problem you’ll likely come across if you use the <select> element in your Cordova/Iconic project.

The Select Element Double Open Issue

The select element is a common form control that allows users to choose an option from a list of options. This example settings tab contains two select boxes:

Ionic Settings Tab on Windows Phone

Here’s the markup for your reference:

<ion-tab title="Settings" icon="ion-gear-b">
	<ion-content padding="true" class="has-header">
		<form>
			<label class="item item-select">
				<span class="input-label">Status</span>
				<select>
					<option>Away</option>
					<option>Online</option>
					<option>Do Not Disturb</option>
				</select>
			</label>
			<label class="item item-select">
				<span class="input-label">Photo Resolution</span>
				<select ng-model="selectedResolution" ng-options="r.name for r in resolutions"></select>
			</label>
		</form>
	</ion-content>
</ion-tab>

The Status select is hard coded and the Resolution select is bound to a resolutions array that belongs to the scope. When we tap on one of the select controls we expect the native select menu to take over, and it does:

Windows select menu that pops up twice.

Unfortunately, as you may have already discovered, the native Windows option picker appears twice. This is obviously unwanted behavior… We don’t want the user to have to make the choice two times. It’s confusing and clunky.

There is an easy fix, however. Just toss the data-tap-disabled=”true” attribute on your select elements and that unwanted behavior stops.  According to Ionic, the data-tap-disabled attribute may be necessary when certain third-party libraries interfere with the Ionic tap system. When this attribute is set to true, Ionic will no longer attempt to remove the 300ms tap delay introduced by many browsers. Thankfully, setting this attribute to true doesn’t seem to cause any delays on my Windows Phone (Nokia Lumia 520). Here’s the updated markup that includes the new attribute:

<ion-tab title="Settings" icon="ion-gear-b">
	<ion-content padding="true" class="has-header">
		<form>
			<label class="item item-select">
				<span class="input-label">Status</span>
				<select data-tap-disabled="true">
					<option>Away</option>
					<option>Online</option>
					<option>Do Not Disturb</option>
				</select>
			</label>
			<label class="item item-select">
				<span class="input-label">Photo Resolution</span>
				<select data-tap-disabled="true" ng-model="selectedResolution" ng-options="r.name for r in resolutions"></select>
			</label>
		</form>
	</ion-content>
</ion-tab>

This solution works, but has its flaws. It can be inconvenient and error prone to add this data-tap-disabled attribute to every single select element. Also, assuming you’re planning on targeting more than just the Windows Phone, you probably don’t want to introduce a 300ms tap delay on various other devices. A more global, conditional solution would be best.

Luckily was able to Google my way to rhespy’s genius idea to create a custom directive for the select element.  Below is that same directive, but it attempts to conform to John Papa’s Angular style guide:

(function () {
    "use strict";

    angular
        .module('common')
        .directive('select', selectDirective);

    selectDirective.$inject = [];

    function selectDirective() {
        return {
            restrict: 'E',
            replace: false,
            link: function (scope, element) {
                if (ionic.Platform && ionic.Platform.isWindowsPhone()) {
                    element.attr('data-tap-disabled', 'true');
                }
            }
        };
    }
})();

In the link function for this directive, we check to see if the device is a Windows Phone, and if it is we add the data-tap-disabled=”true” attribute to the select element.  By including this directive in your app, you’ll no longer need to manually apply that attribute to each select element.  You’ll also only be applying the attribute on Windows Phones instead of every single device you target. It’s a great fix!

Thanks for reading. The next post in the series will cover troubles with web fonts and icon sets on the Windows Phone. It should be published shortly. Happy coding!