diff --git a/app/assets/stylesheets/basic/orbit_bar.css.erb b/app/assets/stylesheets/basic/orbit_bar.css.erb index c381c4d..91076b8 100644 --- a/app/assets/stylesheets/basic/orbit_bar.css.erb +++ b/app/assets/stylesheets/basic/orbit_bar.css.erb @@ -125,8 +125,8 @@ top: 14px; } #orbit-bar #search .icon-search { - left: 13px; - top: 15px; + left: 20px; + top: 12px; font-size: 1.2em; } #orbit-bar #search .search-clear { @@ -138,11 +138,103 @@ cursor:pointer; } +/*Search Container*/ +#search_container{ + display: none; + top: 40px; + right: 20px; + width: 40%; + background: #FAFAFA; + position: absolute; + box-shadow: 0px 5px 20px #666; + color: #666; + font-family: "微軟正黑體", "Raleway"; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + overflow: hidden; +} + +#search_head{ + text-align: right; + padding: 5px 25px 5px 10px; + /*border-bottom: 1px solid #CCC;*/ + color: #666; + /*background: #EEE;*/ + height: 20px; +} + +#search_loading{ + text-align: center; + padding: 20px; +} + +#search_footer{ + height: 10px; + padding: 5px 25px 5px 10px; + border-bottom: 1px solid #CCC; + color: #666; + /*background: #DDD;*/ +} + +#search_results{ + max-height: 500px; + overflow-y: auto; + overflow-x: hidden; +} + +#search_results::-webkit-scrollbar { + width: 8px; + background: #CCC; +} + +#search_results::-webkit-scrollbar-track { +} + +#search_results::-webkit-scrollbar-thumb { + background: #888; +} + +#search_results a{ +} + +#search_results a:hover{ + text-decoration: none; + color: #333; +} + +.seach_title{ + padding: 5px 0; + color: #0053CF; + font-size: 15px; +} + +.search_result{ + padding: 15px 15px; + /*border-bottom: 1px solid #DDD; + border-top: 1px solid #FFF;*/ + font-size: 12px; + line-height: 20px; +} + +.search_result:hover{ + background: #FFF; + box-shadow: 0px 0px 20px #DDD; + /*border-bottom: 1px solid #FFF;*/ +} + +.search_result h5{ +} + +.search_result strong{ + /*font-weight: bold;*/ + color: #B90000; +} + /*User info*/ #orbit-bar #orbit-user .user-pic { width: 40px; height: 40px; - margin: -12px 10px -10px -15px; + margin: -13px 10px -10px -15px; } /*Language & flag*/ diff --git a/app/controllers/site_search_controller.rb b/app/controllers/site_search_controller.rb new file mode 100644 index 0000000..42a9482 --- /dev/null +++ b/app/controllers/site_search_controller.rb @@ -0,0 +1,94 @@ +class SiteSearchController < ApplicationController + + def search + startTime = Time.now + if params[:keywords].present? + modules = [ + {:key=>"announcement", :model=>"Bulletin", :fields=>["title","subtitle","text"], :url=>"/panel/announcement/front_end/bulletin/"} + ] + + key_string = params[:keywords] + keywords = key_string.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/) + regex = Regexp.union(keywords.map{|word| Regexp.new(".*"+word+".*", "i")}) + + result = [] + + # Search Pages + Item.where(:app_frontend_url=>"page_contexts", :is_published=>true).each do |page| + title = page.title + context = PageContext.where(:page_id=>page.id).first.context + context = ActionController::Base.helpers.strip_tags(context).gsub(/ /i," ") rescue "" + title_matches = title.scan(regex).size + context_matches = context.scan(regex).size rescue 0 + if title_matches > 0 or context_matches > 0 + tmp = {} + tmp[:id] = page.id + tmp[:module] = "page" + tmp[:url] = "/"+page.path + tmp[:title] = hight_light(keywords, title) + tmp[:content] = hight_light(keywords, context, true) + tmp[:matches] = title_matches+context_matches + tmp[:matches] += title.scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0 + tmp[:matches] += context.scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0 + result.push(tmp) + end + end + + # Search Modules + modules.each do |mod| + query = mod[:fields].map{|f| {f.to_sym => regex} } + res = Kernel.const_get(mod[:model]).any_of(query) + res.all.each do |r| + tmp = {} + tmp[:id] = r.id + tmp[:module] = mod[:key] + tmp[:url] = mod[:url]+r.id.to_s + tmp[:content] = "" + tmp[:matches] = 0 + mod[:fields].each do |f| + value = ActionController::Base.helpers.strip_tags(eval("r.#{f}")).gsub(/ /i,"") + + if f=="title" or f=="name" + tmp[:title] = value + else + tmp[:content] << value + end + end + + tmp[:matches] = tmp[:content].scan(regex).size + tmp[:title].scan(regex).size + tmp[:matches] += tmp[:title].scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0 + tmp[:matches] += tmp[:content].scan(Regexp.new(".*"+key_string+".*", "i")).size > 0 ? 20 : 0 rescue 0 + + tmp[:title] = hight_light(keywords, tmp[:title]) + tmp[:content] = hight_light(keywords, tmp[:content], true) + + result.push(tmp) unless tmp[:matches]==0 + end + end + end + result = result.sort_by { |k| k[:matches] }.reverse rescue [] + render :json => { "results" => result, "time"=> ((Time.now-startTime)*1000).to_i , "keywords"=>keywords} + end + + def hight_light(keywords, content, filter=false) + matches = 0 + keywords.each do |k| + matches += content.scan(/(#{k})/i).size + content.gsub!(/(#{k})/i, '\1') rescue "" + end + + if filter + index = content.index '' + unless index.nil? + index = index>50 ? index-50 : 0 + deadline = 150 + content = content[index, deadline] + else + content = content[0, 100] + end + end + + return content + end + +end \ No newline at end of file diff --git a/app/views/layouts/_orbit_bar.html.erb b/app/views/layouts/_orbit_bar.html.erb index 5fe0ad5..a88e966 100644 --- a/app/views/layouts/_orbit_bar.html.erb +++ b/app/views/layouts/_orbit_bar.html.erb @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/app/views/layouts/_right_menu.html.erb b/app/views/layouts/_right_menu.html.erb index 3d64dae..e90dab1 100644 --- a/app/views/layouts/_right_menu.html.erb +++ b/app/views/layouts/_right_menu.html.erb @@ -2,14 +2,8 @@ diff --git a/app/views/layouts/_search.erb b/app/views/layouts/_search.erb new file mode 100644 index 0000000..1c4d93e --- /dev/null +++ b/app/views/layouts/_search.erb @@ -0,0 +1,55 @@ +
+
+ +
+
+
+ +
+ \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index f387f91..baac9f1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,9 @@ Orbit::Application.routes.draw do get 'basic_infos/confirmation' => "basic_infos#confirmation" post 'basic_infos/role_update' => "basic_infos#role_update" match 'basic_infos/basic_info_update' => "basic_infos#basic_info_update" + + get "site_search" => "site_search#search" + # routes for admin namespace :admin do match 'user_actions' => 'user_actions#index'