Tag Archives: HTML5

Launching the Facebook & Twitter Websites From a Web App

25 Mar 2013

Creating a link within your mobile HTML5/web apps is exactly like creating a link that launches in a new window, you simply do the following:

...
<a href="http://somewhere.com" target="_blank"></a>
...

Or via JavaScript:

...
<script language="javascript">
  window.open('http://somewhere.com');
</script>
...

The above does what one would expect in most cases – launching the URL in the device’s mobile browser. However, on iOS if we are trying to go to a Facebook or Twitter site such as in this example:

...
<a href="http://www.facebook.com/pepsi" target="_blank"></a>
...

…and the Facebook App is installed on the iOS device the Facebook App itself will launch instead and present the Facebook login screen – which is not what we want to happen. In this case getting around this iOS quirk is easy – create a proxy page on a server of your choice that will redirect Mobile Safari to the desired location.

For example you might have a link like this one within your web app:

...
<a href="http://myserver.com/redir.html" target="_blank"></a>
...

Given the above your proxy page would contain a single line of JavaScript:

...
document.location.href = 'http://www.facebook.com/pepsi'; // go to the branded pepsi facebook page
...

Pretty simple… but in my specific example I want to have a single proxy page handle multiple Facebook and Twitter cases. Given this information the link within my web app looks similar to this:

...
<a href="http://myserver.com/redir.html?b=abc&sn=fb" target="_blank"></a>
...

The convention that I’ve setup here is that I have a link to a specific brand (“b”) whose branded social network (“sn”) website that I want the user to go to. In my “redir.html” document I have some simple JavaScript to inspect the URL’s name/value pairs and thus branch to the desired brand’s specific social network website based on that information.

...
<script language="javascript">
  var loc = document.location.href.split('?');
  var args = loc[1].split('&');
  var brand = args[0].split('=');
  var sn = args[1].split('=');
  if (brand[1] == 'abc'){
    if (sn[1] == 'fb'){
      // go to the brand's facebook site
      document.location.href = 'http://www.facebook.com/abc';
    } else if (sn[1] == 'tw'){
      // go to the brand's twitter website
      document.location.href = 'http://www.twitter.com/abc';
    }
  } else if (brand[1] == 'xyz'){
    // etc...
  } 
  // etc.....
</script>
...

Intel Buys AppMobi

26 Feb 2013

I just got an email from Intel re its acquisition of AppMobi – Intel has just gotten itself developer tools presumably for its Tizen mobile operating system (of which Samsung is a partner). Here’s the text of the email:

February 25, 2013

Dear HTML5 Developer:

As a valued user of appMobi* HTML5* tools and services, I am pleased to let you know the developer tools and build system business portion of appMobi was acquired by Intel Corporation on February 21, 2013. In addition, Intel hired the tool development team from appMobi. With our combined development teams, we can extend the HTML5 tools capabilities.

While the names and location of the tools have changed, the same capabilities are there for you. You can continue your work, accessing the tools, your work files, and appMobi’s cloud services.

We do need you to sign up with Intel at http://software.intel.com/html5tools . It will take just a minute and you become part of Intel’s developer program, with access to the HTML5 tools and build system at no cost.

At Intel, we are committed to delivering HTML5 tools that inspire you to create and deploy more HTML5 cross platform apps. Our goal is to increase your productivity and expand your customer reach. Working together, Intel and appMobi will continue to serve your development needs.

I hope you will also visit http://software.intel.com/html5 to learn about the latest HTML5 developments from Intel.

We thank you for your continued support.

Sincerely,

Kevin J. Smith

Director, Developer Products Division/Web App

Scrolling in LungoJS HTML5 Framework

12 Jul 2012

I’ve been looking at other frameworks lately, among them LungoJS. After fiddling with the framework I had difficulties creating scrolling views. The docs say that getting a scrolling area is as simple as adding a “scrollable” class to a div – not quite, there are some other requirements.

To get scrolling articles you must have the following structure – notice the DIV that wraps the content:

...
<article id="something" class="scrollable">
   <div> <!-- This DIV is important!! -->
      Your content in here
   </div>
</article>
...

If you attempt to create a scrollable div inside an article tag you **must** also set a height for that div, like so:

...
<article id="something">
   <div id="myDiv" class="scrollable" style="height:300px;">
      <div> <!-- This DIV is important!! -->
         Your content in here
      </div>
   </div>
</article>
...

Notice the ID in the scrollable divs – ID is **required**, you will see as much in the console if you forget this.

Note the DIV that is the immediate child of the scrollable div – that is also required. No need to style it or add an ID. Your content must be wrapped by a DIV – P’s, Lists and header elements also work. Spans do not.

If the scrolling area is not an article tag then you **must** include the height for the scrolling div, which is illustrated in the second example above.

I noticed a lot of confusion in the forums and was confused myself – IMO the docs should be amended with the above.

Ext.Picker Slots with A Single Value: showing a Decimal Point

08 Feb 2012

A case has come up where I need a picker with multiple slots that represent a number to two decimal places. A decimal point will be necessary to delineate between whole numbers and the decimals. To achieve this I will need to have a 5 slot Ext.Picker where the middle slot is a decimal point, as shown in the image below:

Sencha Picker with 5 slots, the center having a single value.

At first glance this might seem to be fairly easy. As slots are simple to define we then assume that the center slot just needs to be a single value, right? Actually, that’s not quite true. A few things make this not so clear-cut, among them is that a slot cannot be disabled. There *is* an option to set “draggable” to false but it doesn’t work (Sencha 1.1.1). As a result the slot will always be subject to being dragged by the user. Also an Ext.Picker with a slot consisting of only a single value will actualy throw errors if the slot is dragged up or down – trial and error reveals that a slot must consist of at least two values.

So then, we will create our center slot with two values. Also, I think its pretty tedious to manualy create all of the values for the other slots, so I wrote a function that builds an array of configuration objects that I’ll use to populate the slot data. Here’s what we have at this point:

function returnNumbers(){
	var num = [];
	for (i=0;i<10;i++){
		num[num.length] = {text:i,value:i};
	}
	return num;
}

var taxPicker = new Ext.Picker({
	slots: [
		{
			name : 'whole1',
			title: 'col 1',
			data : returnNumbers()
		},
		{
			name : 'whole2',
			title: 'col 2',
			data : returnNumbers()
		},
		{
			name : 'dot',
			title: 'decimal',
			draggable:false, // doesn't work!!
			data : [{text:'.',value:'.'},{text: '', value: ''}]
		},
		{
			name : 'decimal1',
			title: 'col 3',
			data :  returnNumbers()
		},
		{
			name : 'decimal2',
			title: 'col 4',
			data :  returnNumbers()
		}
	]
});

As you can see the first two slots are a range of numbers, 0 through 9. The center slot is the decimal and an empty string, and then the last two slots like the first pair are also setup to display 0 thru 9.

When the picker is shown via the show() method it appears the way we want - the decimal point is the first selection. Recall though that we have two values for the center slot, and that the user can play with the slot as they wish. If the decimal is dragged down Sencha handily animates it back into position. However if the decimal is dragged up - we get the empty-string as the selection for the slot. Note that we actual don't care what the selection of the center slot is - I don't use it - but visually this looks wrong so it needs to be addressed. If we can't prevent the user from dragging the decimal then we should at least find a way to put it back where we want it.

They key here is that Slots fire "pick" events when they are changed. So that's where we'll start; by adding a listener to the picker. Next, we need to set its value and there is a method that does just that - setSelectedNode(). Lets create the listener:

	...
	listeners:{
		pick:function(pickerO,o,pickerS){
			pickerS.setSelectedNode(0,null);
		}
	}
	...

This is great except for one thing - all of the slots are being animated back to their initial values. We need a way of being more selectful in our approach as this code doesn't discriminate and attacks all of the slots. The answer here is to look at the value of the slot responsible for the event call and do a comparison against it to see if its the slot we're looking for.

The slot object is being passed as "pickerS", so lets grab that and compare the name given to the slot against what we know is the name of the decimal slot (refer to the picker code above - all of the slots have a "name"):

	...
	listeners:{
		pick:function(pickerO,o,pickerS){
			if (pickerS.name == 'dot'){ // send back to the decimal...
				pickerS.setSelectedNode(0,null);
			}
		}
	}
	...

On line 4 above you can see that I have an if statement comparing the passed slot's name to "dot" which is the name I gave to the decimal-having slot. This ensures that we're working with the correct slot when the pick event is fired.

Sweet, that should do it - however, of course there is one last detail... there always is! The above behaves unpredictably. Sometimes the decimal slides back to being selected, sometimes not. In these cases I always wonder if too much is happening at the same time. A simple setTimeout should make all the difference and it does.

        setTimeout(function(){pickerS.setSelectedNode(0,null);},20);

As you can see I've delayed the setSelectedNode() call by 20 milliseconds. Thats all that was needed - if the user drags the center slot to the second "empty" slot we return it to the desired decimal-having slot 20 ms later. Its the best that we can do. Here's the complete source:

function returnNumbers(){
	var num = [];
	for (i=0;i<10;i++){
		num[num.length] = {text:i,value:i};
	}
	return num;
}

var taxPicker = new Ext.Picker({
	slots: [
		{
			name : 'whole1',
			title: 'col 1',
			data : returnNumbers()
		},
		{
			name : 'whole2',
			title: 'col 2',
			data : returnNumbers()
		},
		{
			name : 'dot',
			title: 'decimal',
			draggable:false, // doesn't work!!
			data : [{text:'.',value:'.'},{text: '', value: ''}]
		},
		{
			name : 'decimal1',
			title: 'col 3',
			data :  returnNumbers()
		},
		{
			name : 'decimal2',
			title: 'col 4',
			data :  returnNumbers()
		}
	],
	listeners:{
		pick:function(pickerO,o,pickerS){
			if (pickerS.name == 'dot'){ // send back to the decimal...
				setTimeout(function(){pickerS.setSelectedNode(0,null);},20);
			}
		}
	}
});

Reset Ext.Panel Y Coord to 0

08 Feb 2012

Doubtless there is a way to do this with Ext, but this is my own method of returning a scrolling panel within Sencha Touch to the “top” of the view. I did spend some time reviewing the Sencha Touch docs but the only thing that came close to the desired result was the setPosition() method which only works on floating panels. I did spend some time playing with setting the floating property of the panel and then applying setPosition() but quickly ran into undesired results.

So, as always, time is short and a solution needs to be had quickly. A few minutes later I came up with this:

// setPositionToTop(cmp):void
// This function takes the scrolling area of a panel and sets its y position to 0;
// arguments: cmp:Object, an Ext.Panel
// returns: nothing
function setPositionToTop(cmp){
	var cmpId = cmp.getId();
	var sStr = document.getElementById(cmpId).firstChild.firstChild.getAttribute('style');
	if (sStr && sStr.indexOf('translate3d') != -1){
		var temp = sStr.split(',');
		temp[1] = ' 0px';
		var newStr = temp.join(',');
		//console.log('before: ' + sStr + ', after: ' + newStr);
	document.getElementById(cmpId).firstChild.firstChild.setAttribute('style',newStr)
	cmp.doComponentLayout();
	}
}

The above is based on the following source that Sencha Touch generates:

...

It should be plain that the top-most div is the component, and that I’m traversing the DOM to the third DIV and manipulating the style attribute. In this example the webkit-transform is responsible for the position of the content div and so I’m setting the y value back to 0px thus placing it where I want – back to the top.

The interesting thing here is that without calling doComponentLayout() on the component the space that the scrolling content area occupied before changing its position is still present resulting in a scrolling area larger than desired. In a worse-case scenario you can actually scroll the content area right off the screen – never to get it back. doComponentLayout() fixes this. Simply comment that line out to see this for yourself – scroll your panel to its most extreme y position, nav away, nav back, scroll your panel up as far as you can go…. gone.

To use this function I add it to a beforecardswitch listener for the desired panel and I add an if statement to check if the panel has been rendered yet, which it won’t unless you’ve visited it previously:

beforecardswitch:function(e,o){
	if (transactionsCardDeck.getActiveItem()){
		setPositionToTop(transactionsCardDeck.getActiveItem());
        }
}

The result is that the panel’s y coordinate is reset before you return to it.

Logo

All content © 2012-2017.