Permalink
Browse files

Added the project files.

  • Loading branch information...
1 parent 1a09278 commit 30cf53ad2ab3768818f6f3141303c701f3b75575 Ronni Rasmussen committed Jun 16, 2011
Showing with 376 additions and 0 deletions.
  1. +82 −0 examples/index.css
  2. +50 −0 examples/index.html
  3. +3 −0 examples/index.js
  4. +241 −0 src/javascripts/jquery.suggest.js
View
@@ -0,0 +1,82 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: white;
+ color: #000;
+ font: 13.34px helvetica,arial,freesans,clean,sans-serif;
+}
+
+#main {
+
+}
+
+#header {
+ height: 90px;
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #ffffff), color-stop(100%, #f5f5f5));
+ background-image: -moz-linear-gradient(top, #ffffff 0%, #f5f5f5 100%);
+ background-image: linear-gradient(top, #ffffff 0%, #f5f5f5 100%);
+ border-bottom: 1px solid #ffffff;
+}
+
+#header-inner {
+ width: 950px;
+ margin: auto;
+}
+
+#page {
+ border-top: 1px solid #dfdfdf;
+}
+
+#page-inner {
+ width: 920px;
+ min-height: 300px;
+ margin: -30px auto 0 auto;
+ padding: 15px;
+ background-color: #ffffff;
+
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -o-border-radius: 5px;
+ -ms-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ border-radius: 5px;
+
+ -moz-box-shadow: #333333 1px 1px 5px 0;
+ -webkit-box-shadow: #333333 1px 1px 5px 0;
+ -o-box-shadow: #333333 1px 1px 5px 0;
+ box-shadow: #333333 1px 1px 5px 0;
+}
+
+#footer {
+ width: 920px;
+ margin: 10px auto;
+}
+
+
+h1 {
+ font-size: 170%;
+ margin-bottom: 1.5em;
+}
+
+h2 {
+ font-size: 150%;
+ margin-top: 1.5em;
+ border-top: 4px solid #E0E0E0;
+ padding-top: .5em;
+}
+
+
+
+
+/* Suggest */
+input, textarea {
+ width: 300px;
+ padding: 7px;
+ letter-spacing: 1px;
+ font-size: 11px;
+ font-family: "Times New Roman",Georgia,Serif;
+
+}
View
@@ -0,0 +1,50 @@
+<html lang="en" locale="en">
+ <head>
+ <title>Suggest plugin for jQuery</title>
+
+ <script src="../../jquery/jquery.js" type="text/javascript"></script>
+ <script src="../src/javascripts/jquery.suggest.js" type="text/javascript"></script>
+ <script src="./index.js" type="text/javascript"></script>
+
+ <link href="./index.css" media="screen, projection" rel="stylesheet" type="text/css" />
+
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('.suggest').suggest({});
+
+ setInterval(function() {
+ //$('#input').suggest(true).setCaret(3,5);
+ }, 2000);
+ });
+ </script>
+ </head>
+ <body>
+ <div>&lrm; - '‎'</div>
+ <div id="main">
+ <div id="header">
+ <div id="header-inner">
+ <span style="margin-top: 10px; text-align: right; display: inline-block;"><strong style="font-size: 16px;">Ronni Steen Rasmussen</strong><br />aka. Iumentum</span>
+ </div>
+ </div>
+
+ <div id="page">
+ <div id="page-inner">
+ <h1>Suggest plugin for jQuery</h1>
+
+ <div id="content">
+
+ <input id="input" class="suggest" type="text" value="Jeg gik mig over så og land, der mødte jeg" /><br />
+ <textarea id="textarea" class="suggest"></textarea>
+
+ </div>
+ </div>
+ </div>
+
+ <div id="footer">
+ footer goes here
+ </div>
+ </div>
+ </body>
+</html>
View
@@ -0,0 +1,3 @@
+(function($) {
+ console.log('index.js');
+})(jQuery);
@@ -0,0 +1,241 @@
+(function($) {
+ // suggestion/completion/prediction/recognition
+ // Think final name will be - jQuery prediction plugin
+ suggestObject = function(element, options) {
+ this.options = options;
+ this.$element = element;
+
+ this.init();
+ };
+
+ suggestObject.prototype = {
+ init: function() {
+ var self = this;
+
+ this.$element.bind('blur keydown click', function(event) {
+ // Clear our timeour no matter what the event might be.
+ clearTimeout(self.delay);
+
+ var key = event.keyCode || event.which;
+
+ switch (event.type) {
+ case 'click':
+ case 'blur':
+ if(self.hasSuggestion()) {
+ self.removeSuggestion(false);
+ }
+ break;
+ case 'keydown':
+ // Here we might want to check for event.ctrlKey || event.metaKey
+ switch (key) {
+ case 16: // SHIFT
+ // DO NOTHING
+ return true;
+ break;
+ case 9: // Tab
+ case 39: // NEXT
+ if(self.hasSuggestion()) {
+ self.useSuggestion();
+ return false;
+ }
+ break;
+ default:
+ if(self.hasSuggestion()) {
+ self.removeSuggestion(true);
+
+ if(key == 8) {
+ return false;
+ }
+ }
+ break;
+ }
+
+ // Here we will check if we should suggest anything at all.
+ // So far we just suggest on [0-9a-z].
+ // When we change this consider if we need to check if caret start and end is the same.
+ // Check is caret is at the end or the next char is the chunk splitter.
+ if (key >= 48 && key <= 105 && !event.ctrlKey && !event.metaKey){
+ self.delay = setTimeout(function() {
+ if(self.$element.val().length) {
+ self.suggest();
+ }
+ }, 250);
+ }
+ break;
+ }
+ });
+ },
+
+ suggest: function() {
+ var caret = this.getCaret();
+ var text = this.$element.val();
+ var string = false;
+
+ // Replace linebreaks with spaces in our text before making it into chunks.
+ text = text.replace(/\n/g, " ");
+
+ // make the text into chunks
+ var chunks = text.split(" ");
+
+ // Lets find the string.
+ if(caret.start == text.length) {
+ string = chunks[chunks.length-1];
+ } else if(caret.start <= chunks[0].length) {
+ string = chunks[0];
+ } else {
+ var length = 0;
+
+ $.each(chunks, function(key, value) {
+ // TODO: rename the length variable.
+ length = length + value.length + 1; // TODO: +1 should be changed with chunk seperator length
+
+ if(caret.start <= length) {
+ string = chunks[key];
+ return false;
+ }
+ });
+ }
+
+ // TODO: Here we should remove ending chars from string, such as ,.!?
+
+ var suggestions = ['ActionScript','AppleScript','ASP','BASIC','Batch','COBOL','ColdFusion','Delphi','ECMAScript','Erlang','F-Script','GLBasic','HTML','IronRuby','Java','JavaScript','JQuery','Limbo'];
+ var suggestion = suggestions.filter(function(suggestion, index, array) {
+ return (suggestion.toLowerCase().substr(0, this.string.length) == this.string.toLowerCase() && suggestion.length != this.string.length)
+ }, {string: string})[0];
+
+ if(suggestion) {
+ suggestion = '' + suggestion.substr(string.length, suggestion.length) + '';
+ // TODO: Make it posible to insetAtCaret wthout settings caret, or with defining caret position so we wont set it twice.
+ this.insertAtCaret(suggestion);
+ this.setCaret(this.$element.val().indexOf(''), this.$element.val().lastIndexOf(''));
+ }
+ },
+
+ hasSuggestion: function() {
+ return this.$element.val().match(/‎(.*)‎/g);
+ },
+
+ removeSuggestion: function(setCaret) {
+ var text = this.$element.val();
+ var caret = this.getCaret();
+ var scrollTop = this.$element.scrollTop();
+
+ this.$element.val(text.replace(/‎(.*)‎/g, ""));
+
+ if(setCaret) {
+ this.$element.scrollTop(scrollTop).focus();
+ this.setCaret(caret.start);
+ }
+ },
+
+ useSuggestion: function() {
+ var text = this.$element.val();
+ var caret = this.getCaret();
+ var scrollTop = this.$element.scrollTop();
+
+ this.$element.val(text.replace(/‎(.*)‎/g, "$1"))
+ .scrollTop(scrollTop)
+ .focus();
+
+ this.setCaret(caret.end-1);
+ },
+
+ /*
+ * CARET
+ */
+ getCaret: function() {
+ // TODO: make cross browser.
+ var caret = {};
+
+ if (this.$element.get(0).setSelectionRange) {
+ caret.start = this.$element.get(0).selectionStart;
+ caret.end = this.$element.get(0).selectionEnd;
+ }
+
+ return caret;
+ },
+
+ setCaret: function(start, end) {
+ // TODO: make cross browser.
+ var element = this.$element;
+
+ start = parseInt(start);
+ end = (end) ? Math.max(start, parseInt(end)) : start;
+
+ if (element.get(0).setSelectionRange) {
+ element.focus();
+ element.get(0).setSelectionRange(start, end);
+ } else if (element.get(0).createTextRange) {
+ var range = element.get(0).createTextRange();
+
+ range.collapse(true);
+ range.moveEnd('character', end);
+ range.moveStart('character', start);
+ range.select();
+ }
+ },
+
+ insertAtCaret: function(string) {
+ // TODO: make cross browser.
+ var element = this.$element;
+ var caret = this.getCaret();
+
+ if(caret.start || caret.start === 0) {
+ var value = element.val().substr(0, caret.start) + string + element.val().substr(caret.end);
+ var scroll = {
+ left: element.get(0).scrollLeft,
+ top: element.get(0).scrollTop
+ };
+
+ // Insert the new value and focus.
+ element.val(value).focus();
+
+ // Set caret.
+ // TODO: Use this.setCaret() instead
+ element.get(0).selectionStart = caret.start+string.length;
+ element.get(0).selectionEnd = caret.start+string.length;
+
+ // If we are at the end we set scroll to max.
+ if(caret.start+string.length >= value.length) {
+ scroll = {
+ left: Math.max(element.get(0).scrollWidth, element.innerWidth()),
+ top: Math.max(element.get(0).scrollHeight, element.innerHeight())
+ };
+ }
+
+ // Scroll into to space.
+ element.get(0).scrollLeft = scroll.left;
+ element.get(0).scrollTop = scroll.top;
+ }
+ }
+ };
+
+ $.fn.suggest = function(options) {
+ if(options == true) {
+ return get_or_create($(this));
+ }
+
+ options = (typeof options === 'object' || typeof options === 'undefined') ? $.extend({}, $.fn.suggest.defaults, options) : options;
+
+ // Focus event handler.
+ this[options.live ? 'live' : 'bind']('focus', function() {
+ var object = get_or_create($(this));
+ });
+
+ // Get or create the object.
+ function get_or_create(element){
+ var object = $.data(element.get(0), 'suggest');
+
+ if (!object) {
+ var object = new suggestObject(element, options);
+ $.data(element.get(0), 'suggest', object);
+ }
+
+ return object;
+ };
+ };
+
+ $.fn.suggest.defaults = {
+ live: false
+ };
+})(jQuery);

0 comments on commit 30cf53a

Please sign in to comment.