Last active
January 4, 2016 15:35
-
-
Save lbrenman/d2f0c618c7670e6435ed to your computer and use it in GitHub Desktop.
Appcelerator Titanium Search Autocomplete
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Appcelerator Autocomplete Search | |
A server side search for customers, accounts, inventory, products, etc… in a mobile application is a very common operation. A typical UI for this operation is to allow the user to enter the search text and press a search button or the enter key on the on screen keyboard, as shown below. Then a search is performed, perhaps via a web service call to a server search API, and the retrieved results are displayed in a list for the user to select from the search results, as shown: | |
This is accomplished in Titanium by adding a event listener on the search TextField and listen for the return event as follows: | |
$.searchTF.addEventListener('return', function(e){ | |
processInput(); | |
}); | |
In the above UI, you would also add an event listener on the search button to the right of the search TextField. | |
One way to make the mobile application more useful and responsive is to enhance this search operation by implementing autocomplete. As the user types, searches are performed using the entered text, instead of waiting for the user to finish entering the entire search text. You experience this every time you use Google or Bing to search the web, as shown below: | |
This is easily accomplished in Titanium by also listening for the change event on the TextField as follows: | |
$.searchTF.addEventListener(‘change’, function(e){ | |
processInput(); | |
}); | |
Now, as the user enters text, search results are fetched on each key entered as shown below: | |
One down side of implementing autocomplete is that you are now making many more calls over the network and taxing your back end more. This must be weighed against the increased adoption of the application due its increased usefulness. | |
One tip to reduce the number of web service calls made while still providing the autocomplete feature is to only make the web service call when the user pauses typing. This prevents extra web service calls from being made if the user backs up or changes the input text. This can be accomplished using a JavaScript timer to implement a delay before making the web service call. If the user continues typing before the delay time is reached, then the timer can be reset as follows: | |
var waitForPause, pauseDelay = 1000; | |
… | |
$.wordTF.addEventListener('change', function(e){ | |
clearTimeout(waitForPause); | |
waitForPause = setTimeout(processInput, pauseDelay); | |
}); | |
Next time you implement a server search feature in your application try the autocomplete and see for yourself how your application will appear more responsive and you will find yourself using this feature more and more. | |
The code from this post can be downloaded here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
".container": { | |
backgroundColor:"white" | |
}, | |
"Label": { | |
width: Ti.UI.SIZE, | |
height: Ti.UI.SIZE, | |
color: "#000" | |
}, | |
"TextField": { | |
left: "10", | |
width: Ti.UI.FILL, | |
color: "black", | |
clearButtonMode:Titanium.UI.INPUT_BUTTONMODE_ONFOCUS, | |
//returnKeyType: Titanium.UI.RETURNKEY_DONE, | |
autocapitalization:Ti.UI.TEXT_AUTOCAPITALIZATION_NONE, | |
autocorrect: false | |
}, | |
"TableViewRow": { | |
height: "40", | |
hasChild: true | |
}, | |
"TableView": { | |
height: Ti.UI.FILL | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var waitForPause, pauseDelay = 1000; | |
$.infoButton.addEventListener('click', function(e) { | |
alert("Autocomplete demo"); | |
}); | |
$.wordTV.addEventListener('click', function(e) { | |
Ti.API.info("index: $.wordTV.addEventListener(click)"); | |
alert("row clicked, word = "+e.row.word); | |
}); | |
function resetTable(table) { | |
Ti.API.info("index: resetTable()"); | |
var rd = []; | |
table.data = rd; | |
} | |
function processInput(){ | |
Ti.API.info("index: processInput()"); | |
if($.wordTF.value=="" || $.wordTF.value==null) { | |
resetTable($.wordTV); | |
} else { | |
getWords($.wordTF.value, { | |
success: function(e) { | |
Ti.API.info('Recieved data = '+e); | |
loadTable(e, $.wordTV); | |
}, | |
error: function(e) { | |
Ti.API.info('Error = '+e); | |
alert("No network or server not available. Please try again."); | |
} | |
}); | |
} | |
} | |
$.wordTF.addEventListener('change', function(e){ | |
Ti.API.info("index: $.wordTF.addEventListener(change)"); | |
//processInput(); | |
clearTimeout(waitForPause); | |
waitForPause = setTimeout(processInput, pauseDelay); | |
}); | |
$.wordTF.addEventListener('return', function(e){ | |
Ti.API.info("index: $.wordTF.addEventListener(change)"); | |
processInput(); | |
}); | |
function loadTable(e, table) { | |
Ti.API.info("index: loadTable()"); | |
var reply = JSON.parse(e); | |
var rows = []; | |
var i = 0; | |
Ti.API.info("index: reply = "+reply); | |
if(reply.searchResults.length>0){ | |
_.each(reply.searchResults, function(item) { | |
rows.push(Alloy.createController('wordRow', { | |
word: item.word, | |
}).getView()); | |
}); | |
} | |
else { | |
alert("No words found."); | |
} | |
//$.wordTV.setData(rows); | |
table.setData(rows); | |
} | |
function getWords(text, o){ | |
Ti.API.info("getWords() - text = "+text); | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.info("markit: ondemand() - No Network"); | |
if (o.error) { o.error("No Network"); }; | |
return; | |
} | |
var xhr = Titanium.Network.createHTTPClient({ | |
onload: function() { | |
if (o.success) { o.success(this.responseText); }; | |
}, | |
onerror: function(e) { | |
if (o.error) { o.error("Error with wordnik API"); }; | |
}, | |
timeout: 10000, | |
}); | |
xhr.open("GET", "http://api.wordnik.com/v4/words.json/search/"+text+"?api_key=3fc30fd2caff363468b3a4c28675145127f8640f06715d94f"); | |
xhr.send(); | |
}; | |
$.index.open(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Alloy> | |
<Window class="container" layout="vertical"> | |
<View height="40" backgroundColor="black"> | |
<Label color="white">Autocomplete Demo</Label> | |
<Button id="infoButton" right="10" color="white">i</Button> | |
</View> | |
<View layout="vertical"> | |
<TextField id="wordTF" hintText="Enter word" top="20" /> | |
<TableView id="wordTV" top="20"/> | |
</View> | |
</Window> | |
</Alloy> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var args = arguments[0] || {}; | |
//Ti.API.info("row created, args.name = "+args.name); | |
$.wordRow.word = args.word; | |
$.wordLbl.text = args.word; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Alloy> | |
<TableViewRow class="wordTVR"> | |
<Label id="wordLbl" width="80%" left="10"/> | |
</TableViewRow> | |
</Alloy> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment