JavaScript and DOM Pattern Implementation

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    5 Favorites & 1 Event

    JavaScript and DOM Pattern Implementation - Presentation Transcript

    1. JavaScript DOM Pattern Implementations Dave Johnson [email_address]
    2. Agenda
      • About me
      • Patterns Overview
      • Patterns
        • Inline Editing
        • Composite Controls
        • Popup
        • Copy and Paste
        • Live Scrolling
    3. About
      • Author Enterprise Ajax
      • http://blogs.nitobi.com/dave
    4. Nitobi
      • Nitobi co-founder, CTO
      • Located in Vancouver, Canada
      • Declarative, server integrated, Ajax user-interface components
      • User interface consulting and training services
      • Online usability service RobotReplay
    5.  
    6. Customers
    7. Patterns OVERVIEW
      • “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice”
      • A Pattern Language
    8. Architectural Patterns
      • Literally.
      • MVC
      • Peer-to-peer
      • SOA
    9. Software Design Patterns
      • Gang of Four (GoF)
        • Creational
        • Behavioural
        • Structural
      • Others
        • Concurrency
    10. UI Design Patterns
      • Bill Scott and others
      • Described as
        • Problem
        • Context
        • Principle
        • Solution
        • Why / How
    11. Ajax Design Patterns
      • What we are talking about today
      • Applies principles from all areas:
        • MVC
        • UI
        • OOP
    12. Bad Patterns
      • Increased complexity
      • Does not provide re-use
      • Language hacks
      THE PROBLEMS
    13. Observer
      • Event = function(type) {
      • this.handlers = {};
      • this.guid = 0;
      • }
      • Event.prototype.subscribe = function(func) {
      • this.handlers[this.guid++] = func;
      • return guid;
      • }
      • Event.prototype.notify = function(evtArgs) {
      • for (var item in this.handlers) {
      • this.handlers[item].apply(this, arguments);
      • }
      • }
      • “The meaning of life is that it is to be lived, and it is not to be traded and conceptualized and squeezed into a pattern of systems”
      • Bruce Lee
    14. Programmers Are Lazy
      • “ If you have a difficult task, give it to a lazy person - they will find an easier way to do it.”
      • Hlade's Law
    15. Ajax Patterns - Goals
      • Making the web like the desktop
      • Improving user experience
      • More responsive applications
      • Remove web / desktop divide
      • Marriage of JavaScript, DOM, CSS
    16. Describing Ajax Patterns
      • What is the pattern
      • When is the pattern applied
      • Why use the pattern
      • How is the pattern implemented
    17. Best Practices
      • Consider the user and the developer
      • Common approaches
        • Progressive enhancement
          • http://en.wikipedia.org/wiki/Progressive_enhancement
        • Unobtrusive JavaScript
          • http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
    18. Pitfalls
      • Cross browser
      • Cross doctype
      • I18n and localization
      • Accessibility
    19. THE PATTERNS
    20. Inline Edit
      • What edit in page without page refresh
      • When titles, tags etc
      • Why remove page refreshes
    21. How
      • User invited to click on data field
      • Field is replaced with an editing control
      • User blurs or saves and field is saved behind the scenes and editor removed
    22.  
    23. DOM
      • <div id=&quot;title&quot; class=&quot;editable&quot;>Edit me!</div>
    24. CSS
      • #title {
      • width:200px;
      • border:1px solid black;
      • cursor:pointer;
      • cursor:hand;
      • }
    25. Edit
      • edit: function(evt) {
      • //create the editor
      • this.editor = nitobi.html.createElement( “input”, { id : ”editor”, type : ”text”, value : this.node.innerHTML }, { width: this.node.offsetWidth, height: this.node.offsetHeight );
      • this.node.replaceChild(this.editor, this.node.firstChild);
      • //set the focus so that it is ready to go
      • this.editor.focus();
      • //attach events for bluring and key handling
      • nitobi.html.attachEvent(this.editor, &quot;blur&quot;, this.save);
      • nitobi.html.attachEvent(this.editor, &quot;keydown&quot;, this.keydown);
      • //detach the event for going into edit mode
      • nitobi.html.detachEvent(this.node, &quot;click&quot;, this.edit);
      • }
    26. Key Handling
      • keydown: function(evt) {
      • //check for enter key at least
      • if (evt.keyCode == 13) {
      • this.editor.blur();
      • }
      • }
    27. Saving
      • save: function(evt) {
      • //send the data to the server
      • var xhr = new HttpRequest();
      • xhr.onRequestComplete.subscribe(this.afterSave);
      • xhr.open(“POST”, “mysite.com”, true);
      • xhr.send(“title=“+this.editor.value);
      • //revert to the view only
      • this.node.innerHTML = this.editor.value;
      • //show an activity indicator
      • this.activity.style.display = “inline”;
      • },
      • afterSave: function(httpResponse) {
      • //concurrency pattern
      • //undo with command pattern
      • attachEvent(this.node, &quot;click&quot;, this.edit);
      • }
    28. Pitfalls / Best Practices
      • Potential Pitfalls
        • page contents can move when changing “modes”
        • too subtle invitation to edit
        • too many edit invitations
        • concurrency or failure
      • Best Practices
        • avoid page jitter
        • make render & edit modes same size
        • activate on click
        • deactivate on blur
    29. Composite Controls
      • What inline edit multiple text fields
      • When simple forms, combo box
      • Why remove page refreshes
    30. How
      • Create a Form JavaScript class that implements IBlurable interface
      • All form elements have key and mouse events attached through IBlurable
      • When user clicks on fields the mousedown event on the newly clicked field blocks the blur on the previous field
      • When user clicks outside of the composite control the blur event is not blocked
    31. Aside: Event Order
      • Click on the first name field
        • mousedown
        • focus
        • mouseup
        • click
      • Click on the last name field
        • mousedown (last name)
        • blur (first name)
        • focus (last name)
        • mouseup (last name)
        • click (last name)
      • Also consider relatedTarget / fromElement
    32.  
    33. DOM
      • <form id=&quot;form&quot; name=&quot;form&quot;>
      • <label for=&quot;first&quot;>First: </label>
      • <input name=&quot;first&quot; id=&quot;first&quot;>
      • <label for=&quot;last&quot;>Last: </label>
      • <input name=&quot;last&quot; id=&quot;last&quot;>
      • </form>
    34. NameForm
      • NameForm = function(node) {
      • this.form = node;
      • //setup the blurable interface
      • IBlurable.call(this, this.form.elements);
      • this.onBlur.subscribe(this.save, this);
      • }
      • //implement the interface (ie copy over the methods)
      • nitobi.lang.implement(NameForm, IBlurable);
      • NameForm.prototype.save = function(evt) {
      • //same issues as inline edit case
      • var xhr = new nitobi.ajax.HttpRequest();
      • xhr.open(&quot;POST&quot;, &quot;http://nitobi.com/name&quot;, true);
      • xhr.send(this.form);
      • };
    35. Pitfalls / Best Practices
      • Potential Pitfalls
        • event order differences across browsers
        • event problems on certain controls (select, scrollbars)
      • Best Practices
        • use for data validation behind the scenes on sub-forms
        • consider both keyboard (tabbing) and mouse events
    36. Popup
      • What display additional information
      • When details are required in context
      • Why remove page refresh
    37. How
      • User moves mouse over element that has mouseover event attached
      • Popup is displayed
      • User moves over another part of the trigger element firing mouseout event on a timeout
      • If show is called while waiting for a hide the hide is cancelled preventing flicker and allowing user to mouse over the contents of the popup
    38.  
    39. DOM
      • <span id=&quot;title&quot;>
      • <strong>
      • <a href=&quot;#&quot;>Iron Man</a>
      • </strong>
      • <span class=&quot;year&quot;>(2008)</span>
      • </span>
      • <div id=&quot;details&quot;>
      • When wealthy ...
      • <a href=&quot;#&quot;>(more)</a>
      • </div>
    40. Aside: Event Bubbling
      • Events bubble up through the DOM
      • They are also “captured”
      • Event handlers fire when trigged from any child node
    41. CSS
      • #details {
      • position: absolute;
      • display: none;
      • top: 0px;
      • left: 0px;
      • width: 300px;
      • height: 100px;
      • border: 1px solid black;
      • background-color: white;
      • }
    42. Constructor
      • Popup = function(title, detail) {
      • this.detail = detail;
      • //attach mouseover event for show
      • nitobi.html.attachEvent(title, &quot;mouseover&quot;, this.show);
      • var _t = this;
      • this.hideTimeout = null;
      • //attach a delayed mouseout event for hide
      • nitobi.html.attachEvent(title, &quot;mouseout&quot;, function() {
      • _t.hideTimeout = setTimeout(_t.hide, 200);
      • });
      • }
    43. Show
      • Popup.prototype.show = function(evt) {
      • if (this.hideTimeout != null) {
      • //clear the hide timeout clearTimeout(this.hideTimeout);
      • this.hideTimeout
      • } else {
      • //show the popup
      • var style = this.detail.style;
      • style.display = &quot;block&quot;;
      • style.top = (evt.clientY + 5) + &quot;px&quot;;
      • style.left = (evt.clientX + 5) + &quot;px&quot;;
      • }
      • }
    44. Pitfalls / Best Practices
      • Potential Pitfalls
        • mouse event bubbling causes flickering or moving of the popup
        • rogue popups
        • Interaction between trigger and contents
      • Best Practices
        • enable keyboard access
        • provide some way to close manually
        • make certain it disappears!
    45. Copy and Paste
      • What user can enter bulk data
      • When interop desktop and browser
      • Why remove page refreshes
    46. How - Copy
      • User clicks on focusable element (<a>)
      • Filter for ctrl+c on keydown event
      • Set value of hidden <textarea> to the data that is to be copied
      • Focus on the hidden <textarea>
      • Magic
      • Capture keyup event on hidden <textarea> to focus back on your control
      • <textarea> value now on OS clipboard
    47. How - Paste
      • User clicks on focusable element (<a>)
      • Filter for ctrl+v on keydown event
      • Focus on the hidden <textarea>
      • Magic
      • Capture keyup event on hidden <textarea>
      • Data from OS clipboard now in the <textarea> where you can access it and focus back on your control
    48.  
    49. DOM
      • <div id=&quot;copyable&quot;>
      • Copy this text
      • </div>
      • <textarea id=“clipboard”></textarea>
    50. CSS
      • #clipboard {
        • position: absolute;
        • left: -5000px;
      • }
    51. Constructor
      • var Copyable = function(node) {
      • //replace the contents with an <a> tag so that it is focusable
      • this.source = node;
      • this.source.innerHTML = &quot;<a href=&quot;#&quot; class=&quot;focusable&quot;>&quot;+this.source.innerHTML+&quot;</a>&quot;;
      • //intercept all key presses to look for ctrl+c/v
      • nitobi.html.attachEvent(this.source, &quot;keydown&quot;, this.handleKey);
      • //create the clipboard
      • this.clipboard = nitobi.html.createElement(&quot;textarea&quot;, { id : &quot;clipboard&quot;+node.id } );
      • document.body.appendChild(this.clipboard);
      • }
    52. handleKey
      • handleKey: function(evt) {
      • var k = evt.keyCode;
      • //offset keycode for modifier keys
      • k = k + (evt.shiftKey?256:0)+
      • (evt.ctrlKey?512:0)+
      • (evt.metaKey?1024:0);
      • //lookup the method in a map
      • var handler = this.keyMap[k];
      • //call that method
      • if (handler != null)
      • handler.call(this);
      • }
    53. Copy
      • copy: function() {
      • //get the data we want to copy
      • var data = this.source.firstChild.innerHTML;
      • if (!nitobi.browser.IE) {
      • //focus back control when the copy is complete
      • attachEvent(this.clipboard, &quot;keyup&quot;, this.focus);
      • //set the value, focus and select the value
      • this.clipboard.value = data;
      • this.clipboard.focus(); this.clipboard.setSelectionRange(0,data.length);
      • } else {
      • window.clipboardData.setData(&quot;Text&quot;,data);
      • }
      • }
    54. Paste
      • paste: function() {
      • //catch the textarea keyup to grab the results
      • nitobi.html.attachEventOnce(this.clipboard, &quot;keyup&quot;, this.pasteReady);
      • this.clipboard.focus();
      • },
      • pasteReady: function() {
      • //get the clipboard value and insert it
      • this.source.firstChild.innerHTML = this.clipboard.value;
      • //focus back on the control
      • this.source.firstChild.focus();
      • }
    55. Pitfalls / Best Practices
      • Pitfalls
        • user is unaware of functionality
        • keyboard short cuts don’t match OS
        • no context menu support in some browsers
      • Best Practices
        • capture ctrl/cmd+c/v/x for different OS
        • support various formats depending on use case
    56. Live Scrolling
      • What scroll through large datasets
      • When viewing, filtering, sorting
      • Why remove page refreshes
    57. How
      • Create clipping <div> and surface <div> where data goes
      • Repeat for a scrollbar
      • Connect scrollbar scroll events to position the data surface
      • Retrieve data from the server as user scrolls
    58.  
    59. DOM
      • <div id=“viewport”>
      • <div id=“surface”>
      • <div id=“data”></div>
      • </div>
      • </div>
      • <div id=“scrollcontainer&quot;>
      • <div id=&quot;scrollbar&quot;>
      • <div id=“range”></div>
      • </div>
      • </div>
    60. CSS
      • #scrollcontainer {
      • width: 16px;
      • height: 300px;
      • overflow: hidden;
      • }
      • #scrollbar {
      • height: 100%;
      • width: 16px;
      • //width: 17px;
      • position: relative;
      • overflow-x: hidden;
      • overflow-y: scroll;
      • }
      • #range {
      • overflow: hidden;
      • width: 1px;
      • height: 3000px;&quot;
      • }
      #viewport { position: relative; overflow: hidden; width: 300px; height: 300px; border: 1px solid black; } #surface { width: 2000px; height: 2000px; }
    61. Scrolling
      • var evt = “mousewheel”;
      • if (nitobi.browser.MOZ)
      • evt = “DOMMouseScroll”;
      • //attach the event to the surface
      • nitobi.html.attachEvent(
      • scollSurface, evt,
      • this.handleMouseWheel);
    62. Pitfalls / Best Practices
      • Potential Pitfalls
        • dual-scrollbar issue
        • sluggish performance
        • extremely large data sets
      • Best Practices
        • provide dynamic tooltip showing location within scroll
        • animate scroll
        • if desire a hybrid, use animation on paging.
        • support mouse scroll wheel
    63. Acknowledgements
      • Bill Scott
      • Michael Mahemoff
      • Andre Charland
    64. Thank You
      • Questions?
      • email: [email_address]
      • blog: blogs.nitobi.com/dave
      • book: enterpriseajax.com
      • tweets: twitter.com/davejohnson
      • http://flickr.com/photos/daveknapik/2115474105/
      • http://flickr.com/photos/preciouskhyatt/2153351428/
      • http://flickr.com/photos/sandcastlematt/403101240/

    + davejohnsondavejohnson, 2 years ago

    custom

    4070 views, 5 favs, 2 embeds more stats

    Covers implementation details of five important Aja more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 4070
      • 3995 on SlideShare
      • 75 from embeds
    • Comments 0
    • Favorites 5
    • Downloads 119
    Most viewed embeds
    • 74 views on http://blogs.nitobi.com
    • 1 views on http://www.cn-cuckoo.com

    more

    All embeds
    • 74 views on http://blogs.nitobi.com
    • 1 views on http://www.cn-cuckoo.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories

    Groups / Events