Implement article search

Need to refactor the javascript into an Articles object or something that can be used to load the article data. The JS pagination functionality would then be seperate to this.
This commit is contained in:
Wesley Moore 2010-03-03 08:03:23 +11:00
parent 52adcd192a
commit 194890e733
5 changed files with 108 additions and 13 deletions

View file

@ -2,20 +2,13 @@
<html> <html>
<head> <head>
<%= render '_head' %> <%= render '_head' %>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script> <link rel="stylesheet" href="/css/jsonSuggest.css" type="text/css" media="screen" charset="utf-8" />
<script src="/js/common.js" type="text/javascript" charset="utf-8"></script> <!--<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script>-->
<% if @item.identifier =~ %r{/page/$} %> <script src="/js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/jquery.ba-bbq.min.js" type="text/javascript" charset="utf-8"></script> <script src="/js/jquery.ba-bbq.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/jquery.jsonSuggest.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/mojo.js" type="text/javascript" charset="utf-8"></script> <script src="/js/mojo.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/articles.js" type="text/javascript" charset="utf-8"></script> <script src="/js/articles.js" type="text/javascript" charset="utf-8"></script>
<% else %>
<script type="text/javascript" charset="utf-8">
jQuery(function() {
show_javascript_widgets();
webkit_search_tweak();
});
</script>
<% end %>
</head> </head>
<body class="articles"> <body class="articles">
<%= render '_header' %> <%= render '_header' %>

View file

@ -17,7 +17,9 @@ module WezM
:title => article[:title], :title => article[:title],
:path => article.identifier, :path => article.identifier,
:date => Time.parse(article[:created_at]).rfc2822, :date => Time.parse(article[:created_at]).rfc2822,
:summary => article[:summary] :summary => article[:summary],
:text => article[:title],
:extra => article[:summary]
} }
end end

49
output/css/jsonSuggest.css Executable file
View file

@ -0,0 +1,49 @@
div.jsonSuggestResults {
position:absolute;
border:1px solid #CCC;
padding:0px;
margin:0px 2px;
z-index:1;
}
div.jsonSuggestResults div.resultItem {
margin:0px;
padding:5px;
position:relative;
height:auto;
cursor:pointer;
}
div.jsonSuggestResults div.resultItem.odd {
background-color:#9ADFFE;
}
div.jsonSuggestResults div.resultItem.even {
background-color:#FFFFFF;
}
div.jsonSuggestResults div.resultItem.hover {
background-color:#3399FF;
}
div.jsonSuggestResults div.resultItem img {
float:left;
margin-right:10px;
}
div.jsonSuggestResults div.resultItem p {
margin:0px;
padding:0px;
}
div.jsonSuggestResults div.resultItem p strong {
font-weight:bold;
text-decoration:underline;
}
div.jsonSuggestResults div.resultItem p.extra {
font-size: x-small !important;
position:absolute;
bottom:3px;
right: 3px;
}

View file

@ -3,6 +3,25 @@
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var per_page = 10; var per_page = 10;
function search_item_selected(item) {
};
function show_javascript_widgets() {
$('.pagination').show();
$('#search').show();
$('#search input').jsonSuggest(articles, {
onSelect: search_item_selected,
width: 400
});
};
function webkit_search_tweak() {
if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0) {
$('#search input').css('paddingTop', 0);
}
};
function render_article(o) { function render_article(o) {
return '<li>\n\ return '<li>\n\
<abbr class="calender date" title="' + (Mojo.escape(Mojo.normalize(o.date))) + '">\n\ <abbr class="calender date" title="' + (Mojo.escape(Mojo.normalize(o.date))) + '">\n\
@ -35,6 +54,9 @@
var page; var page;
var matches; var matches;
var page_fragment = e.fragment; var page_fragment = e.fragment;
if(!page_fragment) {
page_fragment = $.param.fragment();
}
if(matches = page_fragment.match(/(\d+)$/)) { if(matches = page_fragment.match(/(\d+)$/)) {
page = new Number(matches[1]); page = new Number(matches[1]);
} }
@ -76,5 +98,9 @@
}; };
// Load articles JSON ASAP // Load articles JSON ASAP
jQuery.getJSON('../json/articles.json', {}, articles_loaded); var path = 'json/articles.json';
if(document.location.pathname.match(/page\/$/)) {
path = '../json/articles.json';
}
jQuery.getJSON(path, {}, articles_loaded);
})(); })();

25
output/js/jquery.jsonSuggest.js Executable file
View file

@ -0,0 +1,25 @@
(function($){$.fn.jsonSuggest=function(searchData,settings){var defaults={minCharacters:1,maxResults:undefined,wildCard:"",caseSensitive:false,notCharacter:"!",maxHeight:350,highlightMatches:true,onSelect:undefined,ajaxResults:false};settings=$.extend(defaults,settings);return this.each(function(){function regexEscape(txt,omit){var specials=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];if(omit){for(var i=0;i<specials.length;i++){if(specials[i]===omit){specials.splice(i,1);}}}
var escapePatt=new RegExp('(\\'+specials.join('|\\')+')','g');return txt.replace(escapePatt,'\\$1');}
var obj=$(this),wildCardPatt=new RegExp(regexEscape(settings.wildCard||''),'g'),results=$('<div />'),currentSelection,pageX,pageY;function selectResultItem(item){obj.val(item.text);$(results).html('').hide();if(typeof settings.onSelect==='function'){settings.onSelect(item);}}
function setHoverClass(el){$('div.resultItem',results).removeClass('hover');$(el).addClass('hover');currentSelection=el;}
function buildResults(resultObjects,sFilterTxt){sFilterTxt="("+sFilterTxt+")";var bOddRow=true,i,iFound=0,filterPatt=settings.caseSensitive?new RegExp(sFilterTxt,"g"):new RegExp(sFilterTxt,"ig");$(results).html('').hide();for(i=0;i<resultObjects.length;i+=1){var item=$('<div />'),text=resultObjects[i].text;if(settings.highlightMatches===true){text=text.replace(filterPatt,"<strong>$1</strong>");}
$(item).append('<p class="text">'+text+'</p>');if(typeof resultObjects[i].extra==='string'){$(item).append('<p class="extra">'+resultObjects[i].extra+'</p>');}
if(typeof resultObjects[i].image==='string'){$(item).prepend('<img src="'+resultObjects[i].image+'" />').append('<br style="clear:both;" />');}
$(item).addClass('resultItem').addClass((bOddRow)?'odd':'even').click(function(n){return function(){selectResultItem(resultObjects[n]);};}(i)).mouseover(function(el){return function(){setHoverClass(el);};}(item));$(results).append(item);bOddRow=!bOddRow;iFound+=1;if(typeof settings.maxResults==='number'&&iFound>=settings.maxResults){break;}}
if($('div',results).length>0){currentSelection=undefined;$(results).show().css('height','auto');if($(results).height()>settings.maxHeight){$(results).css({'overflow':'auto','height':settings.maxHeight+'px'});}}}
function runSuggest(e){if(this.value.length<settings.minCharacters){$(results).html('').hide();return false;}
var resultObjects=[],sFilterTxt=(!settings.wildCard)?regexEscape(this.value):regexEscape(this.value,settings.wildCard).replace(wildCardPatt,'.*'),bMatch=true,filterPatt,i;if(settings.notCharacter&&sFilterTxt.indexOf(settings.notCharacter)===0){sFilterTxt=sFilterTxt.substr(settings.notCharacter.length,sFilterTxt.length);if(sFilterTxt.length>0){bMatch=false;}}
sFilterTxt=sFilterTxt||'.*';sFilterTxt=settings.wildCard?'^'+sFilterTxt:sFilterTxt;filterPatt=settings.caseSensitive?new RegExp(sFilterTxt):new RegExp(sFilterTxt,"i");if(settings.ajaxResults===true){resultObjects=searchData(this.value,settings.wildCard,settings.caseSensitive,settings.notCharacter);if(typeof resultObjects==='string'){resultObjects=JSON.parse(resultObjects);}}
else{for(i=0;i<searchData.length;i+=1){if(filterPatt.test(searchData[i].text)===bMatch){resultObjects.push(searchData[i]);}}}
buildResults(resultObjects,sFilterTxt);}
function keyListener(e){switch(e.keyCode){case 13:$(currentSelection).trigger('click');return false;case 40:if(typeof currentSelection==='undefined'){currentSelection=$('div.resultItem:first',results).get(0);}
else{currentSelection=$(currentSelection).next().get(0);}
setHoverClass(currentSelection);if(currentSelection){$(results).scrollTop(currentSelection.offsetTop);}
return false;case 38:if(typeof currentSelection==='undefined'){currentSelection=$('div.resultItem:last',results).get(0);}
else{currentSelection=$(currentSelection).prev().get(0);}
setHoverClass(currentSelection);if(currentSelection){$(results).scrollTop(currentSelection.offsetTop);}
return false;default:runSuggest.apply(this,[e]);}}
$(results).addClass('jsonSuggestResults').css({'top':(obj.position().top+obj.height()+5)+'px','left':obj.position().left+'px','width':obj.width()+'px'}).hide();obj.after(results).keyup(keyListener).blur(function(e){var resPos=$(results).offset();resPos.bottom=resPos.top+$(results).height();resPos.right=resPos.left+$(results).width();if(pageY<resPos.top||pageY>resPos.bottom||pageX<resPos.left||pageX>resPos.right){$(results).hide();}}).focus(function(e){$(results).css({'top':(obj.position().top+obj.height()+5)+'px','left':obj.position().left+'px'});if($('div',results).length>0){$(results).show();}}).attr('autocomplete','off');$().mousemove(function(e){pageX=e.pageX;pageY=e.pageY;});if($.browser.opera){obj.keydown(function(e){if(e.keyCode===40){return keyListener(e);}});}
settings.notCharacter=regexEscape(settings.notCharacter||'');if(!settings.ajaxResults){if(typeof searchData==='function'){searchData=searchData();}
if(typeof searchData==='string'){searchData=JSON.parse(searchData);}}});};})(jQuery);