Lab 10: User Interface and User Experience

In this laboratory we will try to see different ways we can interact interact programmatically with the interface from javascript.

In order to do these exercises you will need a new phoengap project and the IoT template. Also, in order to make builds, you will need an adobe account to access phonegap build.

For starters we will need the following pages:

  • news (which will display some news)
  • chat (will allow the IoT app users to chat)
  • images (display a gallery of images uploaded by IoT App users)
  • sensors (interact with your boards)
  • templates (a page that should never be shown to the users which will contain copies of the HTML elements you need to use in the code)

Don't forget to give each page and ID and for testing purposes also write the name of the page inside the page. Eg:

<div id="news" data-role="page">
   news
</div>

Now that you've created the pages start linking them to the menu by creating buttons as shown in the course: Eg:

<li>
  <a href="#news">
    <i class="fa fa-newspaper-o"></i> News
  </a>
</li>

In your template you will find the close button already defined, so start creating your own buttons after that. Also try assigning a relevant icon to each menu item.

You should achieve an end result similar with the one presented in the course.

2) Inputs, buttons and message boxes

Alerts and Timing

The standard way to display a message box on the web is alert() for a notification base message box, confirm() for a yes/no answer message box.

The normal usage for the 2 is

alert("Welcome");
if( confirm('Are you human?') ){
  //code for yes
}else{
  //code for no
}

There is a problem with apple phones where they need a delay of at least 0ms (a delay of 0 might not make sense but it actually waits 1 event loop cycle which can be less than 1ms) in order to show alerts. This problem exist for more elements not just alerts. In javascript there are 2 main timing methods: setTimeout which delays a function and setInterval which run a function at set intervals.

var id_of_timer = setTimeout(callback, time); //  to create a delay
clearTimeout(id_of_timer); // to delete the delay before it actually runs

var id_of_timer = setInterval(callback, time); //  to create an interval
clearInterval(id_of_timer); // to delete the interval

the callback can be the name of a function,method created before or an anonymous function crated in place:

setTimeout(show_alert,0);

or

setTimeout(function(){
  alert("Hello");
},0);

This is true for any callbacks in javascript. You can always either point to a method/function or create a new one on the spot.

CSS selectors,input boxes and values

jQuery (and javascript in general, we use jQuery for simplification) allows us to access elements by providing a css selector towards them. The selection can result 0,1 or more elements.

A css selector can select elements based on tag,id,class,attributes and many other constraints, but we will stick to tag id and class here. An html/xml node in general looks like

<tag_name id="id" class="class1 class2 class3" attr1="attr1 value" attr2="attr2 value">
  html content
</tag_name>

Even if browsers allow you to give the same id to multiple elements, each id needs to be unique for things to work properly. In order to select a certain element the selector can be:

tag_name#id.class
 

but each part can be omitted. In this case for example since the id is already unique there is no need to mention the tag_name and the class so

#id

should suffice.

Also in order to select certain children we can use ”>” or ” ” (black space) where

#id>div /*selects all the divs that are direct children of the tag with id #id*/
#id div /*selects all the divs that are children(including grandchildren) of the tag with id #id*/

For a complete list of CSS selectors check here.

In order to select an element from javascript

$(cssSelector as string); // EG $("#username")

This call returns a jQuery object on which we can use jQuery methods to modify the HTML node.

In order to retrieve or change the contents of a javascript element we can muse the .html() jQuery method.

<div id="example">
  <p>Example</p>
</div>

For the above code:

$("#example").html(); //would return  <p>Example</p>
$("#example").html("hi");
/* would change the node too
   <div id="example">
     hi
   </div>
*/

Now, let's go to the chat page and create some interactive input boxes and buttons. Since this page will represent a chat box we need to divide our space in 2:

  • top part = diplaying the messages
  • bottom part allowing user to send messages

In order to do that just copy the following code into your page

<div id="chat_controls">
</div>
<div id="chat_box">
</div>

Now add to chat controls 2 input text boxes and a button. The code for generating an input box in html is

<input type="text">

give the first input id username and the 2nd one id msg. After the 2 inputs include a button from the ones offered by the template.

The javasript will be written in teh index.js file (it can be written anywhere but in general event handling should be broken apart from design). The general structure of an phoengap app is an app object containing properties and methods. The properties are used to store data and states of the apps while the methods are usuall used for events. Your send button should be accessible by the

$("chat_controls>button") //cause there should be only one button

So in order to keep with the phonegap app structure instead of writing the whole code in bindEvents we should link a chatSend event.

app={
  bindEvents: function(){
    
    ...other event binding code here ...
    
    $("chat_controls>button").click(app.chatSend); //this jQuery method links 
    // the given function/method to the click event
    // click events can be linked to any html elemtns and not just buttons
  },
  chatSend:function(){
    //code for chatSend here
  }
  
}

In order to get values from input boxes the .val() jQuery method should be used:

$(selector).val();

Now what we want is to display the message from the input box into the chat_box on click. We will do the following changes in the chatSend method:

var user = $("#username").val(); //get username
var msg = $("#msg").val(); // get msg
var new_div = $("<div>"+user+":"+msg+"</div>"); // create a new div
// the div will look like <div>user:msg</div>
$("#chat_box").append(new_div);
//append new div to chat_box
//the append jQuery method adds new children to an HTML element.

Your own messages should now appear in the chatbox.

3) Displaying the news

For starters, since we do not learn how to fetch info from the server in this laboratory, we will need to use some test data. so copy the following declaration at the start of your index.js.

var test_news=[
	{
		pk:"1",
		title:"Title 1",
		content:"Description 1",
		image:"http://ocw.cs.pub.ro/courses/res/sigla_iot.png"
	},
	{
		pk:"2",
		title:"Title 2",
		content:"Description 2",
		image:"http://ocw.cs.pub.ro/courses/res/sigla_iot.png"
	},
	{
		pk:"3",
		title:"Title 3",
		content:"Description 3",
		image:"http://ocw.cs.pub.ro/courses/res/sigla_iot.png"
	},
	{
		pk:"4",
		title:"Title 4",
		content:"Description 4",
		image:"http://ocw.cs.pub.ro/courses/res/sigla_iot.png"
	},
	{
		pk:"5",
		title:"Title 5",
		content:"Description 5",
		image:"http://ocw.cs.pub.ro/courses/res/sigla_iot.png"
	}
];

We will need a method which should be called at certain intervals to update the news page. For this create a new method/event in the app called udpateNews and inside bindEvents set an interval for it to run every 5 seconds.

setInterval(app.updateNews, 5000);
app.udpateNews();//call once the update method in order to initialize
// the page (this line should be in initialization phase and not in bind events)

Now in updateNews initialize a variable with the value from test_news (we wil later initialize it with data from server) and then parse it and create the proper card elements for it. Don't forget to have a card element in the template page, we will clone this element in order to create our news elements. In jQuery we can run a CSS selector on an already selected element EG:

$("#id").find("li");

will select all the li items from the result of the first query. But remember that when we can write the selector as a single selector it's better to write it as

$("#id li");

the find method is useful in situation where we can't write it in a single query, like when we want to run a query on a cloned element.

updateNews: function(){
  var news = test_news;
  $("#news").html(""); // we empty the contents of the page
  for(var i=0; i<news.length; i++){
    var card = $("#templates>.card").clone();
    card.find(".title").html(news[i].title); //set .title element of the card
    card.find(".content").html(news[i].content); //set .content element of the card
    card.find(".img").attr("src",news[i].image); //set src attribute of the image
    card.attr("data-pk",news[i].pk); //set a custom pk attribute to store the pk
    card.find(/*selector of the read more button*/).click(function(){
      //on click display in console the pk of the clicked card
      console.log($(this).parent().parent().attr("data-pk"));
    });
    $("#news").append(card); //add card to page
   }
}

The above code will redraw the page every 5 seconds and when a “read more” button is pressed it will print in the javscript console the pk of the read more that was pressed. This is helpful for when we want to show the whole article in order to know which article we need to request from the server.

iot2015/labs/10.txt · Last modified: 2016/06/17 15:45 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0