A brief history of YUI
AutoComplete
Photo: http://www.flickr.com/photos/margolove/1204358675/
AutoComplete appeared in YUI 0.10.0,
the first public release ofYUI.
It was one of the first open source
JavaScript autocomplete widgets.
Since then, it has been one of the
most popularYUI widgets.
There are lots of different
autocomplete patterns in use on
the web today.
In the YUI 2 world, this meant
AutoComplete had to provide many
options within a single module.
Patterns that weren’t similar to a
traditional list-based autocomplete
weren’t well-served by this model.
This isn’t a problem in the more
granular YUI 3 world.
Say hello to YUI 3
AutoComplete
Photo: http://www.flickr.com/photos/christianschuit/4201189548/
Download video: http://j.mp/yui3ac1
New modular API provides more
flexibility and easier extension to
allow for countless autocomplete
patterns.
Photo: http://...
autocomplete-base
event-valuechange
autocomplete-
filters
autocomplete-
highlighters
autocomplete-list
AutoComplete modules
Synthetic event; fires when an
input field’s value changes.
AutoComplete modules
autocomplete-base
event-valuechange
autocom...
1KB
2KB
3KB
4KB
5KB
6KB
7KB
8KB
2.8.2 3.3.0
AutoComplete module size
(min + gzip)
Filters
Highlighters
List
Base
90% feature parity withYUI 2
AutoComplete.
*
* This is a highly scientific number. I swear.
autocomplete-base autocomplete-list
allowBrowserAutocomplete activateFirstItem
inputNode align
maxResults alwaysShowList
m...
autocomplete-base autocomplete-list
allowBrowserAutocomplete activateFirstItem
inputNode align
maxResults alwaysShowList
m...
Results can come from a
DataSource, Array, or Object.
Results can also come from a
JSONP URL or a YQL query.
This is awesome.
Use the prepackaged result filters and
highlighters, or provide your own.
Built-in filters and highlighters support
word breaking and accent folding.
Provide a custom result formatter
to free yourself from boring text-only
results.
Fully accessible out of the box.
Mobile-ready out of the box.
Photo: http://www.flickr.com/photos/tonymadrid/4696501004/
Photo: http://www.flickr.com/photos/tonymadrid/4696501004/
No keyboard? No point loading
keyboard code.
Speaking of code...
SHOW ME IT.
Photo: http://www.flickr.com/photos/tambako/3535904860/
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
// Plugin-style.
YUI().use('autocomplete', function (Y) {
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'select...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'http://example.com/search?q={query}&callback={callback}'
});
JSO...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'http://example.com/search?q={query}&callback={callback}'
});
JSO...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'http://example.com/search?q={query}&callback={callback}'
});
JSO...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie']
});
Array ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie']
});
Array ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie']
});
Array ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie']
});
Array ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie']
});
Array ...
var ds = new Y.DataSource.IO({
source: 'http://example.com/search'
});
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
re...
var ds = new Y.DataSource.IO({
source: 'http://example.com/search'
});
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
re...
Deep Dive
Photo: http://www.flickr.com/photos/steelcityhobbies/1084984228/
Locating Results
Photo: http://www.flickr.com/photos/st3f4n/3951143570/
[
"apple pie",
"peach pie",
"pecan pie",
"pumpkin pie"
]
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
source: 'http://...
{
"status": "success",
"search": {
"results": [
"apple pie",
"peach pie",
"pecan pie",
"pumpkin pie"
]
}
}
Y.one('#my-inpu...
{
"status": "success",
"search": {
"results": [
"apple pie",
"peach pie",
"pecan pie",
"pumpkin pie"
]
}
}
Y.one('#my-inpu...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultListLocator: function (response) {
return response && response.sear...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultListLocator: 'results',
source: 'http://search.twitter.com/search.j...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultListLocator: 'results',
source: 'http://search.twitter.com/search.j...
{
"results": [
{
"created_at": "Fri, 29 Oct 2010 07:00:58 +0000",
"from_user": "EricF",
"to_user_id": null,
"text": "YUICo...
{
"results": [
{
"created_at": "Fri, 29 Oct 2010 07:00:58 +0000",
"from_user": "EricF",
"to_user_id": null,
"text": "YUICo...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultListLocator: 'results',
resultTextLocator: function (result) {
retu...
Filtering & Highlighting
Results
Photo: http://www.flickr.com/photos/27953349@N06/4465442322/
Prepackaged Filters &
Highlighters
• All are case-insensitive by default, but case-
sensitive versions are available (char...
YUIConf	
  is	
  super	
  awesome,	
  and	
  so	
  is	
  YUI.
charMatch: 'yui'
YUIConf	
  is	
  super	
  awesome,	
  and	
  so	
  is	
  YUI.
phraseMatch: 'yui'
YUIConf	
  is	
  super	
  awesome,	
  and	
  so	
  is	
  YUI.
startsWith: 'yui'
YUIConf	
  is	
  super	
  awesome,	
  and	
  so	
  is	
  YUI.
wordMatch: 'yui'
function customFilter(query, results) {
return Y.Array.filter(results, function (result) {
result = result.toLowerCase();
...
function customFilter(query, results) {
return Y.Array.filter(results, function (result) {
result = result.toLowerCase();
...
function customFilter(query, results) {
return Y.Array.filter(results, function (result) {
result = result.toLowerCase();
...
function customFilter(query, results) {
return Y.Array.filter(results, function (result) {
result = result.toLowerCase();
...
function customFilter(query, results) {
return Y.Array.filter(results, function (result) {
result = result.toLowerCase();
...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultFilters: customFilter,
source: 'select * from search.suggest where ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultFilters: customFilter,
source: 'select * from search.suggest where ...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultFilters: [customFilter, 'wordMatch', otherFilter, ...],
source: 'se...
function customHighlighter(query, results) {
return Y.Array.map(results, function (result) {
return Y.Highlight.all(result...
function customHighlighter(query, results) {
return Y.Array.map(results, function (result) {
return Y.Highlight.all(result...
function customHighlighter(query, results) {
return Y.Array.map(results, function (result) {
return Y.Highlight.all(result...
function customHighlighter(query, results) {
return Y.Array.map(results, function (result) {
return Y.Highlight.all(result...
function customHighlighter(query, results) {
return Y.Array.map(results, function (result) {
return Y.Highlight.all(result...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultHighlighter: customHighlighter,
source: 'select * from search.sugge...
Y.one('#my-input').plug(Y.Plugin.AutoComplete, {
resultHighlighter: customHighlighter,
source: 'select * from search.sugge...
Formatting Results
Photo: http://www.flickr.com/photos/doug88888/4544745031/
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
{
"results": [
{
"created_at": "Fri, 29 Oct 2010 07:00:58 +0000",
"from_user": "EricF",
"to_user_id": null,
"text": "YUICo...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
[
"<b class="yui3-highlight">YUIConf</b> is looking like it's
gonna be crazy good!",
...
]
user: result.from_user
}
);
});...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
function twitterFormatter(query, raw, highlighted) {
return Y.Array.map(raw, function (result, i) {
return Y.Lang.sub(
'<d...
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFormatter: twitterFormatter,
resultHighlighter: 'phraseMatch',
resu...
Y.one('#ac-input').plug(Y.Plugin.AutoComplete, {
resultFormatter: twitterFormatter,
resultHighlighter: 'phraseMatch',
resu...
.tweet {
clear: both;
margin: 6px 0;
padding: 2px 0;
}
.tweet .hd { float: left; }
.tweet .bd,
.tweet .ft { margin-left: 5...
Download video: http://j.mp/yui3ac2
Other new modules
Photo: http://www.flickr.com/photos/thomashawk/55519741/
• Synthetic event. Fires when an input node’s value
changes due to user input.
• Handles keystrokes, pastes, and IME input...
Y.one('#my-input').on('valueChange', function (e) {
Y.log('Old value: ' + e.prevVal);
Y.log('New value: ' + e.newVal);
});...
Y.one('#my-input').on('valueChange', function (e) {
Y.log('Old value: ' + e.prevVal);
Y.log('New value: ' + e.newVal);
});...
Y.one('#my-input').on('valueChange', function (e) {
Y.log('Old value: ' + e.prevVal);
Y.log('New value: ' + e.newVal);
});...
escape
• Static utility methods for escaping strings.
• Currently has methods for escaping HTML and
regex strings. More to...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
Y.Escape.html('<script>alert("pwned!")</script>');
// => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;'
Y.Escape...
And now, a brief interlude wherein I
whine about having discovered, yesterday
afternoon, that “Unicode” is a
registered tr...
®?
®?
As a result, the word “Unicode” has been
replaced with ☃ in the following slides.
I apologize for the inconvenience.
☃-accentfold
• Helpers for creating and working with accent-
folded strings.
• Accent folding converts “résumé” to
“resume...
Y.☃.AccentFold.fold('résumé');
// => 'resume'
Y.☃.AccentFold.compare('résumé', 'resume');
// => true
Y.☃.AccentFold.filter...
Y.☃.AccentFold.fold('résumé');
// => 'resume'
Y.☃.AccentFold.compare('résumé', 'resume');
// => true
Y.☃.AccentFold.filter...
Y.☃.AccentFold.fold('résumé');
// => 'resume'
Y.☃.AccentFold.compare('résumé', 'resume');
// => true
Y.☃.AccentFold.filter...
Y.☃.AccentFold.fold('résumé');
// => 'resume'
Y.☃.AccentFold.compare('résumé', 'resume');
// => true
Y.☃.AccentFold.filter...
☃-wordbreak
• Implements ☃ text segmentation guidelines for
word breaking.
• Handles edge cases like contractions, decimal...
Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes.");
// => ["A", "kilobyte's", "just", "1,024", "bytes"]
Y.☃.WordBrea...
Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes.");
// => ["A", "kilobyte's", "just", "1,024", "bytes"]
Y.☃.WordBrea...
Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes.");
// => ["A", "kilobyte's", "just", "1,024", "bytes"]
Y.☃.WordBrea...
highlight
• Static utility methods for highlighting strings using
HTML.
• Supports phrase highlighting, start-of-string
hi...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui');
// => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3-
hig...
Why <b>?
• HTML5 defines a new <mark> element for
denoting the relevance (as opposed to the
importance) of a span of text.
...
Photo: http://www.flickr.com/photos/tim_norris/2789759648/
What I just said
but with bullets
• Modular architecture makes it easy to
implement a range of autocomplete patterns.
• De...
One more thing...
Photo: http://www.flickr.com/photos/jabb/3502160522/
Download video: http://j.mp/yui3ac3
YUI().use('gallery-node-tokeninput', function (Y) {
Y.one('#my-input').plug(Y.Plugin.TokenInput);
});
node-tokeninput
YUI().use('gallery-node-tokeninput', function (Y) {
Y.one('#my-input').plug(Y.Plugin.TokenInput);
});
node-tokeninput
YUI().use('gallery-node-tokeninput', function (Y) {
Y.one('#my-input').plug(Y.Plugin.TokenInput);
});
node-tokeninput
YUI().use('gallery-node-tokeninput', function (Y) {
Y.one('#my-input').plug(Y.Plugin.TokenInput);
});
node-tokeninput
...but beware, there are some rough
edges at the moment.
Photo: http://www.flickr.com/photos/damaradeaella/2822846819/
Ryan Grove,YUI Team
@yaypie on Twitter
https://github.com/rgrove/
Slides: http://lanyrd.com/smym
Photo: http://www.flickr.c...
Introducing YUI 3 AutoComplete
Upcoming SlideShare
Loading in …5
×

Introducing YUI 3 AutoComplete

16,385 views

Published on

An all-new AutoComplete widget is landing in YUI 3.3.0. In this talk from YUIConf 2010, AutoComplete author Ryan Grove will take you on a whirlwind tour of some of the many autocomplete patterns it makes possible, as well as a deep dive into its powerful new YQL integration, filtering, and highlighting capabilities.

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
16,385
On SlideShare
0
From Embeds
0
Number of Embeds
146
Actions
Shares
0
Downloads
99
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Introducing YUI 3 AutoComplete

  1. A brief history of YUI AutoComplete Photo: http://www.flickr.com/photos/margolove/1204358675/
  2. AutoComplete appeared in YUI 0.10.0, the first public release ofYUI.
  3. It was one of the first open source JavaScript autocomplete widgets.
  4. Since then, it has been one of the most popularYUI widgets.
  5. There are lots of different autocomplete patterns in use on the web today.
  6. In the YUI 2 world, this meant AutoComplete had to provide many options within a single module.
  7. Patterns that weren’t similar to a traditional list-based autocomplete weren’t well-served by this model.
  8. This isn’t a problem in the more granular YUI 3 world.
  9. Say hello to YUI 3 AutoComplete Photo: http://www.flickr.com/photos/christianschuit/4201189548/
  10. Download video: http://j.mp/yui3ac1
  11. New modular API provides more flexibility and easier extension to allow for countless autocomplete patterns. Photo: http://www.flickr.com/photos/grdloizaga/817443503/
  12. autocomplete-base event-valuechange autocomplete- filters autocomplete- highlighters autocomplete-list AutoComplete modules
  13. Synthetic event; fires when an input field’s value changes. AutoComplete modules autocomplete-base event-valuechange autocomplete- filters autocomplete- highlighters autocomplete-list Core logic and API. No UI, minimal dependencies. Optional prepackaged result filters and highlighters. Traditional list widget, just like Mom used to make.
  14. 1KB 2KB 3KB 4KB 5KB 6KB 7KB 8KB 2.8.2 3.3.0 AutoComplete module size (min + gzip) Filters Highlighters List Base
  15. 90% feature parity withYUI 2 AutoComplete. * * This is a highly scientific number. I swear.
  16. autocomplete-base autocomplete-list allowBrowserAutocomplete activateFirstItem inputNode align maxResults alwaysShowList minQueryLength circular queryDelay visible queryDelimiter tabSelect requestTemplate zIndex resultFilters resultFormatter resultHighlighter resultListLocator resultTextLocator source yqlProtocol
  17. autocomplete-base autocomplete-list allowBrowserAutocomplete activateFirstItem inputNode align maxResults alwaysShowList minQueryLength circular queryDelay visible queryDelimiter tabSelect requestTemplate zIndex resultFilters resultFormatter resultHighlighter resultListLocator resultTextLocator source yqlProtocol
  18. Results can come from a DataSource, Array, or Object.
  19. Results can also come from a JSONP URL or a YQL query. This is awesome.
  20. Use the prepackaged result filters and highlighters, or provide your own.
  21. Built-in filters and highlighters support word breaking and accent folding.
  22. Provide a custom result formatter to free yourself from boring text-only results.
  23. Fully accessible out of the box.
  24. Mobile-ready out of the box.
  25. Photo: http://www.flickr.com/photos/tonymadrid/4696501004/
  26. Photo: http://www.flickr.com/photos/tonymadrid/4696501004/ No keyboard? No point loading keyboard code.
  27. Speaking of code... SHOW ME IT. Photo: http://www.flickr.com/photos/tambako/3535904860/
  28. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  29. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  30. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  31. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  32. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  33. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source)
  34. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source) // Widget-style. YUI().use('autocomplete', function (Y) { var ac = new Y.AutoComplete({ inputNode: '#my-input', render : true, source : 'select * from search.suggest where query="{query}"' }); });
  35. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source) // Widget-style. YUI().use('autocomplete', function (Y) { var ac = new Y.AutoComplete({ inputNode: '#my-input', render : true, source : 'select * from search.suggest where query="{query}"' }); });
  36. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source) // Widget-style. YUI().use('autocomplete', function (Y) { var ac = new Y.AutoComplete({ inputNode: '#my-input', render : true, source : 'select * from search.suggest where query="{query}"' }); });
  37. // Plugin-style. YUI().use('autocomplete', function (Y) { Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'select * from search.suggest where query="{query}"' }); }); Basic usage (YQL result source) // Widget-style. YUI().use('autocomplete', function (Y) { var ac = new Y.AutoComplete({ inputNode: '#my-input', render : true, source : 'select * from search.suggest where query="{query}"' }); });
  38. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'http://example.com/search?q={query}&callback={callback}' }); JSONP result source
  39. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'http://example.com/search?q={query}&callback={callback}' }); JSONP result source
  40. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'http://example.com/search?q={query}&callback={callback}' }); JSONP result source
  41. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie'] }); Array and object result sources
  42. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie'] }); Array and object result sources
  43. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie'] }); Array and object result sources Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: { pies : ['apple', 'peach', 'pecan', 'pumpkin'], cookies: ['chocolate chip', 'molasses', 'peanut butter'] } });
  44. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie'] }); Array and object result sources Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: { pies : ['apple', 'peach', 'pecan', 'pumpkin'], cookies: ['chocolate chip', 'molasses', 'peanut butter'] } });
  45. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: ['apple pie', 'peach pie', 'pecan pie', 'pumpkin pie'] }); Array and object result sources Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: { pies : ['apple', 'peach', 'pecan', 'pumpkin'], cookies: ['chocolate chip', 'molasses', 'peanut butter'] } });
  46. var ds = new Y.DataSource.IO({ source: 'http://example.com/search' }); Y.one('#my-input').plug(Y.Plugin.AutoComplete, { requestTemplate: '?q={query}', source: ds }); DataSource result source
  47. var ds = new Y.DataSource.IO({ source: 'http://example.com/search' }); Y.one('#my-input').plug(Y.Plugin.AutoComplete, { requestTemplate: '?q={query}', source: ds }); DataSource result source
  48. Deep Dive Photo: http://www.flickr.com/photos/steelcityhobbies/1084984228/
  49. Locating Results Photo: http://www.flickr.com/photos/st3f4n/3951143570/
  50. [ "apple pie", "peach pie", "pecan pie", "pumpkin pie" ] Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'http://example.com/search?q={query}&callback={callback}' }); ✓ No problem.
  51. { "status": "success", "search": { "results": [ "apple pie", "peach pie", "pecan pie", "pumpkin pie" ] } } Y.one('#my-input').plug(Y.Plugin.AutoComplete, { source: 'http://example.com/search?q={query}&callback={callback}' }); ✗ Bit of a problem.
  52. { "status": "success", "search": { "results": [ "apple pie", "peach pie", "pecan pie", "pumpkin pie" ] } } Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'search.results', source: 'http://example.com/search?q={query}&callback={callback}' }); ✓ Awesome.
  53. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: function (response) { return response && response.search && response.search.results; }, source: 'http://example.com/search?q={query}&callback={callback}' }); The list locator can also be a function.
  54. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'results', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  55. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'results', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  56. { "results": [ { "created_at": "Fri, 29 Oct 2010 07:00:58 +0000", "from_user": "EricF", "to_user_id": null, "text": "YUIConf is looking like it's gonna be crazy good!", "id": 29064356310, "from_user_id": 2469883, "iso_language_code": "en" }, ... ] } Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'results', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  57. { "results": [ { "created_at": "Fri, 29 Oct 2010 07:00:58 +0000", "from_user": "EricF", "to_user_id": null, "text": "YUIConf is looking like it's gonna be crazy good!", "id": 29064356310, "from_user_id": 2469883, "iso_language_code": "en" }, ... ] } Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'results', resultTextLocator: 'text', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  58. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultListLocator: 'results', resultTextLocator: function (result) { return result.text; }, source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' }); Like the list locator, the text locator can be a function.
  59. Filtering & Highlighting Results Photo: http://www.flickr.com/photos/27953349@N06/4465442322/
  60. Prepackaged Filters & Highlighters • All are case-insensitive by default, but case- sensitive versions are available (charMatchCase, phraseMatchCase, etc.). • Accent-folding versions are available as well (charMatchFold, phraseMatchFold, etc.). charMatch phraseMatch startsWith wordMatch
  61. YUIConf  is  super  awesome,  and  so  is  YUI. charMatch: 'yui'
  62. YUIConf  is  super  awesome,  and  so  is  YUI. phraseMatch: 'yui'
  63. YUIConf  is  super  awesome,  and  so  is  YUI. startsWith: 'yui'
  64. YUIConf  is  super  awesome,  and  so  is  YUI. wordMatch: 'yui'
  65. function customFilter(query, results) { return Y.Array.filter(results, function (result) { result = result.toLowerCase(); // Only include results that start with an "a" and contain // the query string. return result.charAt(0) === 'a' && result.indexOf(query) !== -1; }); } Custom Filter
  66. function customFilter(query, results) { return Y.Array.filter(results, function (result) { result = result.toLowerCase(); // Only include results that start with an "a" and contain // the query string. return result.charAt(0) === 'a' && result.indexOf(query) !== -1; }); } Custom Filter
  67. function customFilter(query, results) { return Y.Array.filter(results, function (result) { result = result.toLowerCase(); // Only include results that start with an "a" and contain // the query string. return result.charAt(0) === 'a' && result.indexOf(query) !== -1; }); } Custom Filter
  68. function customFilter(query, results) { return Y.Array.filter(results, function (result) { result = result.toLowerCase(); // Only include results that start with an "a" and contain // the query string. return result.charAt(0) === 'a' && result.indexOf(query) !== -1; }); } Custom Filter
  69. function customFilter(query, results) { return Y.Array.filter(results, function (result) { result = result.toLowerCase(); // Only include results that start with an "a" and contain // the query string. return result.charAt(0) === 'a' && result.indexOf(query) !== -1; }); } Custom Filter
  70. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultFilters: customFilter, source: 'select * from search.suggest where query="{query}"' }); Custom Filter
  71. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultFilters: customFilter, source: 'select * from search.suggest where query="{query}"' }); Custom Filter
  72. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultFilters: [customFilter, 'wordMatch', otherFilter, ...], source: 'select * from search.suggest where query="{query}"' }); Custom Filter
  73. function customHighlighter(query, results) { return Y.Array.map(results, function (result) { return Y.Highlight.all(result, query); }); } Custom Highlighter
  74. function customHighlighter(query, results) { return Y.Array.map(results, function (result) { return Y.Highlight.all(result, query); }); } Custom Highlighter
  75. function customHighlighter(query, results) { return Y.Array.map(results, function (result) { return Y.Highlight.all(result, query); }); } Custom Highlighter
  76. function customHighlighter(query, results) { return Y.Array.map(results, function (result) { return Y.Highlight.all(result, query); }); } Custom Highlighter
  77. function customHighlighter(query, results) { return Y.Array.map(results, function (result) { return Y.Highlight.all(result, query); }); } Custom Highlighter
  78. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultHighlighter: customHighlighter, source: 'select * from search.suggest where query="{query}"' }); Custom Highlighter
  79. Y.one('#my-input').plug(Y.Plugin.AutoComplete, { resultHighlighter: customHighlighter, source: 'select * from search.suggest where query="{query}"' }); Custom Highlighter
  80. Formatting Results Photo: http://www.flickr.com/photos/doug88888/4544745031/
  81. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  82. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  83. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  84. { "results": [ { "created_at": "Fri, 29 Oct 2010 07:00:58 +0000", "from_user": "EricF", "to_user_id": null, "text": "YUIConf is looking like it's gonna be crazy good!", "id": 29064356310, "from_user_id": 2469883, "iso_language_code": "en" }, ... ] } user: result.from_user } ); }); }
  85. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  86. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  87. [ "<b class="yui3-highlight">YUIConf</b> is looking like it's gonna be crazy good!", ... ] user: result.from_user } ); }); }
  88. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  89. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  90. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  91. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  92. function twitterFormatter(query, raw, highlighted) { return Y.Array.map(raw, function (result, i) { return Y.Lang.sub( '<div class="tweet">' + '<div class="hd">' + '<img src="{img}" class="photo" ' + 'alt="Profile photo for {user}">' + '</div>' + '<div class="bd">' + '<strong class="user">{user}</strong>' + '<span class="tweet-text">{text}</span>' + '</div>' + '<div class="ft">{time}</div>' + '</div>', { id : result.id, img : result.profile_image_url, text: highlighted[i], time: result.created_at, user: result.from_user } ); }); }
  93. Y.one('#ac-input').plug(Y.Plugin.AutoComplete, { resultFormatter: twitterFormatter, resultHighlighter: 'phraseMatch', resultListLocator: 'results', resultTextLocator: 'text', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  94. Y.one('#ac-input').plug(Y.Plugin.AutoComplete, { resultFormatter: twitterFormatter, resultHighlighter: 'phraseMatch', resultListLocator: 'results', resultTextLocator: 'text', source: 'http://search.twitter.com/search.json?q={query}&' + 'callback={callback}' });
  95. .tweet { clear: both; margin: 6px 0; padding: 2px 0; } .tweet .hd { float: left; } .tweet .bd, .tweet .ft { margin-left: 52px; } .tweet .ft { color: #cfcfcf; font-size: 11px; } .tweet .photo { height: 48px; margin: 2px 0; width: 48px; } .tweet .user { margin-right: 6px; }
  96. Download video: http://j.mp/yui3ac2
  97. Other new modules Photo: http://www.flickr.com/photos/thomashawk/55519741/
  98. • Synthetic event. Fires when an input node’s value changes due to user input. • Handles keystrokes, pastes, and IME input. • Creates a level playing field across browsers, particularly with languages that have multi-stroke characters. event-valuechange
  99. Y.one('#my-input').on('valueChange', function (e) { Y.log('Old value: ' + e.prevVal); Y.log('New value: ' + e.newVal); }); event-valuechange
  100. Y.one('#my-input').on('valueChange', function (e) { Y.log('Old value: ' + e.prevVal); Y.log('New value: ' + e.newVal); }); event-valuechange
  101. Y.one('#my-input').on('valueChange', function (e) { Y.log('Old value: ' + e.prevVal); Y.log('New value: ' + e.newVal); }); event-valuechange
  102. escape • Static utility methods for escaping strings. • Currently has methods for escaping HTML and regex strings. More to come in future releases. • Feel free to add your own escaping methods to the Y.Escape namespace (and share on the Gallery).
  103. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  104. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  105. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  106. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  107. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  108. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  109. Y.Escape.html('<script>alert("pwned!")</script>'); // => '&lt;script&gt;alert(&quot;pwned!&quot;)&lt;/script&gt;' Y.Escape.regex('$3.14 (plus tax)'); // => '$3.14 (plus tax)' escape
  110. And now, a brief interlude wherein I whine about having discovered, yesterday afternoon, that “Unicode” is a registered trademark of the Unicode® Consortium.
  111. ®?
  112. ®?
  113. As a result, the word “Unicode” has been replaced with ☃ in the following slides.
  114. I apologize for the inconvenience.
  115. ☃-accentfold • Helpers for creating and working with accent- folded strings. • Accent folding converts “résumé” to “resume” (etc.) for easier comparison. • Should be a last resort. Only use it when better tools aren’t available on the server. Don’t fold strings you will display to the user. • Will have an actual name before 3.3.0 final.
  116. Y.☃.AccentFold.fold('résumé'); // => 'resume' Y.☃.AccentFold.compare('résumé', 'resume'); // => true Y.☃.AccentFold.filter(['föö', 'bår', 'móó'], function (str) { return str.indexOf('o') !== -1; }); // => ['föö', 'móó'] ☃-accentfold
  117. Y.☃.AccentFold.fold('résumé'); // => 'resume' Y.☃.AccentFold.compare('résumé', 'resume'); // => true Y.☃.AccentFold.filter(['föö', 'bår', 'móó'], function (str) { return str.indexOf('o') !== -1; }); // => ['föö', 'móó'] ☃-accentfold
  118. Y.☃.AccentFold.fold('résumé'); // => 'resume' Y.☃.AccentFold.compare('résumé', 'resume'); // => true Y.☃.AccentFold.filter(['föö', 'bår', 'móó'], function (str) { return str.indexOf('o') !== -1; }); // => ['föö', 'móó'] ☃-accentfold
  119. Y.☃.AccentFold.fold('résumé'); // => 'resume' Y.☃.AccentFold.compare('résumé', 'resume'); // => true Y.☃.AccentFold.filter(['föö', 'bår', 'móó'], function (str) { return str.indexOf('o') !== -1; }); // => ['föö', 'móó'] ☃-accentfold
  120. ☃-wordbreak • Implements ☃ text segmentation guidelines for word breaking. • Handles edge cases like contractions, decimals, thousands separators, Katakana, non-Latin punctuation, etc. • Not perfect, but much smarter than /b/. • Will have an actual name before 3.3.0 final.
  121. Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes."); // => ["A", "kilobyte's", "just", "1,024", "bytes"] Y.☃.WordBreak.getWords('パイが好きです'); // => ["パイ", "が", "好", "き", "で", "す"] ☃-wordbreak
  122. Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes."); // => ["A", "kilobyte's", "just", "1,024", "bytes"] Y.☃.WordBreak.getWords('パイが好きです'); // => ["パイ", "が", "好", "き", "で", "す"] ☃-wordbreak
  123. Y.☃.WordBreak.getWords("A kilobyte's just 1,024 bytes."); // => ["A", "kilobyte's", "just", "1,024", "bytes"] Y.☃.WordBreak.getWords('パイが好きです'); // => ["パイ", "が", "好", "き", "で", "す"] ☃-wordbreak
  124. highlight • Static utility methods for highlighting strings using HTML. • Supports phrase highlighting, start-of-string highlighting, and word highlighting. • Can use accent folded strings for comparisons while highlighting the original, non-folded string. • Smart enough not to highlight inside HTML entities like &quot;. • Doesn’t infringe any trademarks.
  125. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  126. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  127. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  128. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  129. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  130. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  131. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  132. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  133. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  134. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  135. Y.Highlight.all('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' Y.Highlight.start('YUIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YUI</b>Conf 2010: YUI rocks!' Y.Highlight.words('YUIConf 2010: YUI rocks!', 'yui'); // => 'YUIConf 2010: <b class="yui3-highlight">YUI</b> rocks!' Y.Highlight.allFold('YÜIConf 2010: YUI rocks!', 'yui'); // => '<b class="yui3-highlight">YÜI</b>Conf 2010: <b class="yui3- highlight">YUI</b> rocks!' highlight
  136. Why <b>? • HTML5 defines a new <mark> element for denoting the relevance (as opposed to the importance) of a span of text. • It recommends using <mark> “to highlight a part of quoted text that was not originally emphasized”. • But, since <mark> isn’t yet supported in all browsers, we use <b>, which HTML5 defines as a last resort for highlighting text without implying importance. • You can customize the highlighting markup by changing Y.Highlight._TEMPLATE. More details: http://www.whatwg.org/specs/web-apps/current-work/multipage/text- level-semantics.html#the-mark-element
  137. Photo: http://www.flickr.com/photos/tim_norris/2789759648/
  138. What I just said but with bullets • Modular architecture makes it easy to implement a range of autocomplete patterns. • Dead simple JSONP and YQL support. • Use prepackaged filters and highlighters with word breaking and accent folding, or roll your own. • Create custom result formatters with just a few lines of code. • AutoComplete and friends are available now in YUI 3.3.0pr1. Photo: http://www.flickr.com/photos/tim_norris/2789759648/
  139. One more thing... Photo: http://www.flickr.com/photos/jabb/3502160522/
  140. Download video: http://j.mp/yui3ac3
  141. YUI().use('gallery-node-tokeninput', function (Y) { Y.one('#my-input').plug(Y.Plugin.TokenInput); }); node-tokeninput
  142. YUI().use('gallery-node-tokeninput', function (Y) { Y.one('#my-input').plug(Y.Plugin.TokenInput); }); node-tokeninput
  143. YUI().use('gallery-node-tokeninput', function (Y) { Y.one('#my-input').plug(Y.Plugin.TokenInput); }); node-tokeninput
  144. YUI().use('gallery-node-tokeninput', function (Y) { Y.one('#my-input').plug(Y.Plugin.TokenInput); }); node-tokeninput
  145. ...but beware, there are some rough edges at the moment.
  146. Photo: http://www.flickr.com/photos/damaradeaella/2822846819/
  147. Ryan Grove,YUI Team @yaypie on Twitter https://github.com/rgrove/ Slides: http://lanyrd.com/smym Photo: http://www.flickr.com/photos/damaradeaella/2822846819/

×