diff options
-rw-r--r-- | askbot/media/js/live_search.js | 145 | ||||
-rw-r--r-- | askbot/media/js/utils.js | 12 | ||||
-rw-r--r-- | askbot/media/style/style.less | 32 |
3 files changed, 168 insertions, 21 deletions
diff --git a/askbot/media/js/live_search.js b/askbot/media/js/live_search.js index 6a01c611..d4e86eac 100644 --- a/askbot/media/js/live_search.js +++ b/askbot/media/js/live_search.js @@ -16,8 +16,8 @@ SearchDropMenu.prototype.setAskHandler = function(handler) { * assumes that data is already set */ SearchDropMenu.prototype.render = function() { - this._element.empty(); - var list = this._element; + var list = this._resultsList; + list.empty(); $.each(this._data, function(idx, item) { var listItem = $('<li></li>'); var link = $('<a></a>'); @@ -26,24 +26,41 @@ SearchDropMenu.prototype.render = function() { listItem.append(link); list.append(listItem); }); - //add ask button, @todo: make into separate class? - var listItem = this.makeElement('li'); - this._element.append(listItem); - var button = this.makeElement('button'); - button.html(gettext('Ask Your Question')) - listItem.append(button); - var handler = this._askHandler; - setupButtonEventHandlers(button, handler); }; SearchDropMenu.prototype.createDom = function() { - this._element = this.makeElement('ul'); + this._element = this.makeElement('div'); this._element.addClass('search-drop-menu'); this._element.hide(); + + this._resultsList = this.makeElement('ul'); + this._element.append(this._resultsList); + + //add ask button, @todo: make into separate class? + var footer = this.makeElement('div'); + this._element.append(footer); + this._footer = footer; + + footer.addClass('footer'); + var button = this.makeElement('button'); + button.addClass('submit'); + button.html(gettext('Ask Your Question')) + footer.append(button); + var handler = this._askHandler; + setupButtonEventHandlers(button, handler); }; SearchDropMenu.prototype.show = function() { - this._element.show(); + var searchBar = this._element.prev(); + var searchBarHeight = searchBar.outerHeight(); + var topOffset = searchBar.offset().top + searchBarHeight; + this._element.show();//show so that size calcs work + var footerHeight = this._footer.outerHeight(); + var windowHeight = $(window).height(); + this._resultsList.css( + 'max-height', + windowHeight - topOffset - footerHeight - 30 //what is this number? + ); }; SearchDropMenu.prototype.hide = function() { @@ -111,6 +128,48 @@ TagWarningBox.prototype.showWarning = function(){ /** * @constructor + * tool tip to be shown on top of the search input + */ +var SearchToolTip = function() { + WrappedElement.call(this); +}; +inherits(SearchToolTip, WrappedElement); + +SearchToolTip.prototype.show = function() { + this._element.show(); +}; + +SearchToolTip.prototype.hide = function() { + this._element.hide(); +}; + +SearchToolTip.prototype.setClickHandler = function(handler) { + this._clickHandler = handler; +}; + +SearchToolTip.prototype.createDom = function() { + var element = this.makeElement('div'); + this._element = element; + + element.html(gettext('search or ask your question')); + element.addClass('tool-tip'); + element.css({ + 'margin-top': '-40px', + 'padding-top': '10px', + 'color': '#999', + 'height': '30px', + 'line-height': '20px', + 'font-size': '20px', + 'font-style': 'italic' + }); + + var handler = this._clickHandler; + element.click(function() { handler() }); +}; + + +/** + * @constructor * provides full text search functionality * which re-draws contents of the main page * in response to the search query @@ -374,16 +433,17 @@ FullTextSearch.prototype.reset = function() { this._dropMenu.reset(); this._element.val(''); this._element.focus(); + this._toolTip.show(); }; FullTextSearch.prototype.refreshXButton = function() { if(this.getSearchQuery().length > 0){ if (this._query.hasClass('searchInput')){ $('#searchBar').attr('class', 'cancelable'); - this._x_button.show(); + this._xButton.show(); } } else { - this._x_button.hide(); + this._xButton.hide(); $('#searchBar').removeClass('cancelable'); } }; @@ -530,17 +590,66 @@ FullTextSearch.prototype.makeAskHandler = function() { }; }; +FullTextSearch.prototype.updateToolTip = function() { + var query = this.getSearchQuery(); + if (query === '') { + this._toolTip.show(); + } else { + this._toolTip.hide(); + } +}; + +/** + * keydown handler operates on the tooltip and the X button + * keyup is not good enough, because in that case + * tooltip will be displayed with the input box simultaneously + */ +FullTextSearch.prototype.makeKeyDownHandler = function() { + var me = this; + var toolTip = this._toolTip; + var xButton = this._xButton; + return function(e) {//don't like the keyup delay to + var keyCode = getKeyCode(e); + var query = me.getSearchQuery(); + if (query.length === 1) { + if (keyCode !== 8 && keyCode !== 46) { + toolTip.hide(); + xButton.show(); + } + } else if (query.length === 0) { + if (keyCode !== 8 && keyCode !== 48) { + toolTip.hide(); + //xButton.show();//causes a jump of search input... + } else { + toolTip.show(); + //xButton.hide(); + } + } else { + me.updateToolTip(); + me.refreshXButton(); + } + }; +}; + FullTextSearch.prototype.decorate = function(element) { this._element = element;/* this is a bit artificial we don't use _element */ this._query = element; - this._x_button = $('input[name=reset_query]'); + this._xButton = $('input[name=reset_query]'); this._prevText = this.getSearchQuery(); this._tag_warning_box = new TagWarningBox(); + var toolTip = new SearchToolTip(); + toolTip.setClickHandler(function() { + toolTip.hide(); + element.focus(); + }); + this._element.after(toolTip.getElement()); + this._toolTip = toolTip; + var dropMenu = new SearchDropMenu(); dropMenu.setAskHandler(this.makeAskHandler()); this._dropMenu = dropMenu; - element.after(this._dropMenu.getElement()); + element.parent().after(this._dropMenu.getElement()); var menuCloser = function(){ dropMenu.reset(); @@ -569,7 +678,7 @@ FullTextSearch.prototype.decorate = function(element) { ); }); // enable x button (search reset) - this._x_button.click(function () { + this._xButton.click(function () { /* wrapped in closure because it's not yet defined at this point */ me.reset(); }); @@ -577,7 +686,9 @@ FullTextSearch.prototype.decorate = function(element) { // enable query box var main_page_eval_handle; + this._query.keydown(this.makeKeyDownHandler()); this._query.keyup(function(e){ + me.updateToolTip(); me.refreshXButton(); if (me.isRunning() === false){ clearTimeout(main_page_eval_handle); diff --git a/askbot/media/js/utils.js b/askbot/media/js/utils.js index 2534fb21..679fd530 100644 --- a/askbot/media/js/utils.js +++ b/askbot/media/js/utils.js @@ -97,6 +97,18 @@ var showMessage = function(element, msg, where) { }; })(jQuery); +/** + * @return {number} key code of the event or `undefined` + */ +var getKeyCode = function(e) { + if (e.which) { + return e.which; + } else if (e.keyCode) { + return e.keyCode; + } + return undefined; +}; + var makeKeyHandler = function(key, callback){ return function(e){ if ((e.which && e.which == key) || (e.keyCode && e.keyCode == key)){ diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less index 2be3aa58..6f28d1e9 100644 --- a/askbot/media/style/style.less +++ b/askbot/media/style/style.less @@ -451,7 +451,7 @@ body.user-messages { display: block; background-color: #fff; border: 1px solid #c9c9b5; - height: auto; + height: 41px; z-index: 10000; position: relative; @@ -471,19 +471,38 @@ body.user-messages { -moz-box-shadow: none; box-shadow: none; } - .search-drop-menu { +} + +.search-drop-menu { + box-sizing: border-box; + background: whitesmoke; + border: 1px solid #c9c9b5; + border-top: none; + position: relative; + top: 1px; + z-index: 10000; + + ul { list-style: none; + overflow: auto; + padding: 10px; + position: relative; li { padding: 5px 0; } } + + .footer { + text-align: center; + padding-bottom: 10px; + } } input[type="submit"].searchBtn { font-size: 10px; color: #666; background-color: #eee; - height: 42px; + height: 41px; border:#FFF 1px solid; line-height: 22px; text-align: center; @@ -507,7 +526,7 @@ input[type="submit"].searchBtn { font-size: 30px; color: #ce8888; background:#fff; - height: 42px; + height: 41px; line-height: 42px; border:0px; border-left:#deded0 1px solid; @@ -548,6 +567,11 @@ input[type="submit"].searchBtn { margin-top: -49px; padding: 0 49px 0 8px; } +/* line up drop menu the same way as the search bar */ +.search-drop-menu { + margin: 0 228px 0 327px; + width: auto; +} body.anon #searchBar { margin-left: 227px;/* we don't have the "followed" scope */ } |