How to implement MVC using pure Javascript?

How can I implement a topic/tagging system similar to Quora's using Javascript?

  • Interested in the front-end look and feel, particularly the ability to add/edit/remove topics straight from the page itself. Special bonus for the autocomplete component of adding topics.

  • Answer:

    The feature is simply a well designed, AJAX based JavaScript application that coordinates displayed values with user input forms on demand. The following illustrates a very rudimentary inline autocomplete program: <!DOCTYPE html> <html> <head> <title>Inline autocomplete... sort of</title> <script src="http://code.jquery.com/jquery-git.js"></script> <style> [contenteditable] { border: 1px solid gray; width: 100%; height: 100px; } .hidden { display:none; } ul { background: white; border: 1px solid gray; } </style> <script> (function( root, $ ) { var App, selected = 0, Cache = {}; App = { init: function() { // Store reference to the hidden ul Cache.ul = $("ul.hidden"); // Store references to all contenteditable elements Cache.editables = $("[contenteditable]"); // Generate and store lists from data-* attrs Cache.lists = Cache.editables.map(function() { return [ $(this).data("auto-list").split(",") ]; }); // Store a reusable dom elements Cache.clones = { li: $("<li>") }; // Run the setup routine and a callback App.setup( Cache, function() { // keep track of which list we're on var count = 0; // Iterate all of the application's events and bind them // to all contenteditable elements $.each( App.events, function( type, handler ) { Cache.editables.bind( type, { list: Cache.lists[ count ] }, handler ); count++; }); }); }, setup: function( cache, callback ) { var items = []; // Iterate all lists and create li's for each list item $.each( cache.lists, function( i, list ) { $.each( list, function( j, item ) { items.push( cache.clones.li.clone() ); items[ items.length - 1 ].html( item ); }); }); // Append them all at once $.fn.append.apply( cache.ul, items ); // Invoke callback if provided callback && callback(); }, events: { keydown: function( event ) { var html, data = event.data.list, $this = $(this); // Trigger show select list if ( event.which === 50 ) { $this.append( Cache.ul.clone().removeClass("hidden") ); } // Arrow key handling if ( [ 40, 38 ].indexOf( event.which ) !== -1 ) { // Initialized object literal ({ 38: function() { selected--; if ( selected < 0 ) { selected = 0; } }, 40: function() { selected++; if ( selected >= data.length ) { selected = 0; } } })[ event.which ](); } // Item selection if ( event.which === 13 ) { $this.children("ul").remove(); // get usable content html = $this.html().slice( 0, $this.html().length - 1 ); // Set new content $this.html( html + " " + data[ selected ] ); // reset selected index selected = 0; } } } }; root.App = App; })( this, this.jQuery ); $(document).ready( App.init ); </script> </head> <body> Type @ to trigger the select list, arrow up or down and hit enter to select <div contenteditable="true" id="editor" data-auto-list="foo,bar,baz,qux,alpha,beta"></div> <ul class="hidden"></ul> </body> </html> Note: This should be considered "throw away" code. Here is a live, functional demonstration: http://jsfiddle.net/rwaldron/SCgAn/ Additionally, I wrote a bookmarklet that will give any input element a "tab-triggered" set of JavaScript snippets (inspired by Textmate Bundles), that could easily be modified to behave similarly to an inline autocomplete feature. That project is available here: https://github.com/rwldrn/snippets.js

Rick Waldron at Quora Visit the source

Was this solution helpful to you?

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.