[MERGE] new searchview
fp orders bzr revid: xmo@openerp.com-20120406120250-dlwt0kvt0y1e2snr
This commit is contained in:
commit
e7e7548869
|
@ -10,3 +10,5 @@ RE:^include/
|
|||
RE:^share/
|
||||
RE:^man/
|
||||
RE:^lib/
|
||||
|
||||
RE:^doc/_build/
|
||||
|
|
|
@ -35,6 +35,21 @@
|
|||
"static/lib/qweb/qweb2.js",
|
||||
"static/lib/underscore/underscore.js",
|
||||
"static/lib/underscore/underscore.string.js",
|
||||
"static/lib/backbone/backbone.js",
|
||||
|
||||
"static/lib/visualsearch/lib/js/visualsearch.js",
|
||||
"static/lib/visualsearch/lib/js/utils/backbone_extensions.js",
|
||||
"static/lib/visualsearch/lib/js/utils/hotkeys.js",
|
||||
"static/lib/visualsearch/lib/js/utils/inflector.js",
|
||||
"static/lib/visualsearch/lib/js/utils/jquery_extensions.js",
|
||||
"static/lib/visualsearch/lib/js/utils/search_parser.js",
|
||||
"static/lib/visualsearch/lib/js/models/search_facets.js",
|
||||
"static/lib/visualsearch/lib/js/models/search_query.js",
|
||||
"static/lib/visualsearch/lib/js/templates/templates.js",
|
||||
"static/lib/visualsearch/lib/js/views/search_facet.js",
|
||||
"static/lib/visualsearch/lib/js/views/search_input.js",
|
||||
"static/lib/visualsearch/lib/js/views/search_box.js",
|
||||
|
||||
"static/lib/labjs/LAB.src.js",
|
||||
"static/lib/py.js/lib/py.js",
|
||||
"static/lib/novajs/src/nova.js",
|
||||
|
@ -61,6 +76,9 @@
|
|||
"static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css",
|
||||
"static/lib/jquery.ui.notify/css/ui.notify.css",
|
||||
"static/lib/jquery.tipsy/tipsy.css",
|
||||
"static/lib/visualsearch/lib/css/reset.css",
|
||||
"static/lib/visualsearch/lib/css/workspace.css",
|
||||
"static/lib/visualsearch/lib/css/icons.css",
|
||||
"static/src/css/base_old.css",
|
||||
"static/src/css/base.css",
|
||||
"static/src/css/data_export.css",
|
||||
|
|
|
@ -79,7 +79,7 @@ def concat_files(file_list, reader=None, intersperse=""):
|
|||
|
||||
if reader is None:
|
||||
def reader(f):
|
||||
with open(f) as fp:
|
||||
with open(f, 'rb') as fp:
|
||||
return fp.read()
|
||||
|
||||
files_content = []
|
||||
|
@ -261,8 +261,8 @@ class WebClient(openerpweb.Controller):
|
|||
|
||||
def reader(f):
|
||||
"""read the a css file and absolutify all relative uris"""
|
||||
with open(f) as fp:
|
||||
data = fp.read()
|
||||
with open(f, 'rb') as fp:
|
||||
data = fp.read().decode('utf-8')
|
||||
|
||||
path = file_map[f]
|
||||
# convert FS path into web path
|
||||
|
@ -279,7 +279,7 @@ class WebClient(openerpweb.Controller):
|
|||
r"""url(\1%s/""" % (web_dir,),
|
||||
data,
|
||||
)
|
||||
return data
|
||||
return data.encode('utf-8')
|
||||
|
||||
content, checksum = concat_files((f[0] for f in files), reader)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011 Samuel Clay, @samuelclay, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,16 @@
|
|||
__ ___ _ _____ _ _
|
||||
\ \ / (_) | |/ ____| | | (_)
|
||||
\ \ / / _ ___ _ _ __ _| | (___ ___ __ _ _ __ ___| |__ _ ___
|
||||
\ \/ / | / __| | | |/ _` | |\___ \ / _ \/ _` | '__/ __| '_ \ | / __|
|
||||
\ / | \__ \ |_| | (_| | |____) | __/ (_| | | | (__| | | |_| \__ \
|
||||
\/ |_|___/\__,_|\__,_|_|_____/ \___|\__,_|_| \___|_| |_(_) |___/
|
||||
_/ |
|
||||
|__/
|
||||
|
||||
VisualSearch.js enhances ordinary search boxes with the ability to autocomplete
|
||||
faceted search queries. Specify the facets for completion, along with the
|
||||
completable values for any facet. You can retrieve the search query as a
|
||||
structured object, so you don't have to parse the query string yourself.
|
||||
|
||||
For documentation, pre-packed downloads, demos, and tests, see:
|
||||
http://documentcloud.github.com/visualsearch
|
|
@ -0,0 +1,37 @@
|
|||
require 'rubygems'
|
||||
require 'jammit'
|
||||
require 'fileutils'
|
||||
|
||||
desc "Use Jammit to compile the multiple versions of Visual Search"
|
||||
task :build do
|
||||
$VS_MIN = false
|
||||
Jammit.package!({
|
||||
:config_path => "assets.yml",
|
||||
:output_folder => "build"
|
||||
})
|
||||
|
||||
$VS_MIN = true
|
||||
Jammit.package!({
|
||||
:config_path => "assets.yml",
|
||||
:output_folder => "build-min"
|
||||
})
|
||||
|
||||
# Move the JSTs back to lib to accomodate the demo page.
|
||||
FileUtils.mv("build/visualsearch_templates.js", "lib/js/templates/templates.js")
|
||||
|
||||
# Fix image url paths.
|
||||
['build', 'build-min'].each do |build|
|
||||
File.open("#{build}/visualsearch.css", 'r+') do |file|
|
||||
css = file.read
|
||||
css.gsub!(/url\((.*?)images\/embed\/icons/, 'url(../images/embed/icons')
|
||||
file.rewind
|
||||
file.write(css)
|
||||
file.truncate(css.length)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Build the docco documentation"
|
||||
task :docs do
|
||||
sh "docco lib/js/*.js lib/js/**/*.js"
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
embed_assets: datauri
|
||||
javascript_compressor: closure
|
||||
template_function: _.template
|
||||
gzip_assets: <% if $VS_MIN %>on<% else %>off<% end %>
|
||||
compress_assets: <% if $VS_MIN %>on<% else %>off<% end %>
|
||||
|
||||
javascripts:
|
||||
dependencies:
|
||||
- vendor/jquery-*.js
|
||||
- vendor/jquery.ui.core.js
|
||||
- vendor/jquery.ui.widget.js
|
||||
- vendor/jquery.ui.position.js
|
||||
- vendor/jquery.ui.*.js
|
||||
- vendor/underscore-*.js
|
||||
- vendor/backbone-*.js
|
||||
visualsearch:
|
||||
- lib/js/visualsearch.js
|
||||
- lib/js/views/*.js
|
||||
- lib/js/utils/*.js
|
||||
- lib/js/models/*.js
|
||||
- lib/js/templates/*.jst
|
||||
<% unless $VS_MIN %>visualsearch_templates:
|
||||
- lib/js/templates/*.jst
|
||||
<% end %>
|
||||
|
||||
stylesheets:
|
||||
visualsearch:
|
||||
- lib/css/*.css
|
|
@ -0,0 +1,310 @@
|
|||
.VS-search .VS-icon {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
vertical-align: middle;
|
||||
width: 16px; height: 16px;
|
||||
}
|
||||
.VS-search .VS-icon-cancel {
|
||||
width: 11px; height: 11px;
|
||||
background-position: center 0;
|
||||
background-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAWCAYAAAAW5GZjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAb9JREFUeNqUUr1qAkEQ3j0khQp6kihaeGgEEa18gTQR0iRY+BaBSMDGwidIEUKqFL6BopgqBAJ5AMFGjUU0d4WHEvwJarvZ77gRIzGYgb1hZr+Z75vZ40IIzqTNZrPj8Xicn0wmmcViEXS73aaqqq+BQODG6/W+A8MBNk3zfDAY3C6Xy0O2ZS6X6zMSiVwHg8FHLjtq7Xb7RQKj7BeTzVCgJ5PJU2U0GhUk7REuMpkMi8fjFggeMeecrVYrFRId0CgTAgDDMFg4HLbA8IjJgHNgGEr0er0fQIphUmZAwdSUADUB4RFDsz3oSMF6CLzZkQqgGebz+Z75dDqNdTqdp13bgDmdTj2VSp0oWHg0Gr2UNH2Z/9o+yMv7K4/HY/C/XhDUfr//jl7QQVT9fp/V63VWqVRYt9tliUSCZbPZg1wux9Lp9PqFeK1Wu9A0DdXz7YM87i0FrVZLs4Fi1wmFQh/NZjOmVKvVgq7rR/QflMtlixGedjwcDlUpMQ9tbzalkAAB2/R297mNW+sT2wUbUnA//V/nYrH4QOBNABUQuFQq3TNMuc82sDVrz41G42yvPeODAwZQ0QzwiJEnzLcAAwBJ6WXlwoBgZAAAAABJRU5ErkJggg==");
|
||||
cursor: pointer;
|
||||
}
|
||||
.VS-search .VS-icon-cancel:hover {
|
||||
background-position: center -11px;
|
||||
}
|
||||
.VS-search .VS-icon-search {
|
||||
width: 12px; height: 12px;
|
||||
background-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUZJREFUeNpUUM2qgmAQzS8NiUgLzTIXLZQW1QuI9AY9QPSW9gQ9QiriwpJQEBVrVWT2d7p2L9xZzDdzZs7M+YYqy/J8Ptu2vd/v4zgeDAaqqk4mE47jar9GnU6nzWbjOA5FUa/Xq0Jns9l8Pud5vkpp58cwAOzhcBhFkeu6GNztdg3D+Db5vo9nOp2iiWGYTqdDCMFe4LquI0aVpGmKR9M0lmUbjQY8YiBJklTb4YkoilBzOBzq9TogeMQIJEmqmlAlo9EIyXa7tSyrKAp4xEBkWUb5q2k8Hh+PR8/zwjCEgufz+aESstvtoKnVan2GgY31kBkEAfT1ej1FUZDiNIIgrFYr9H1ug3teLpfH43G/3/FBUJGu1+s8z8FZLpc0mmiabrfbf5fEumazuVgsTNO8Xq+3242qRNT+G0CMz7IMzH6//xZgAA60tj6rqzxpAAAAAElFTkSuQmCC");
|
||||
}
|
||||
|
||||
/*------------------------------ RESET + DEFAULT STYLES ---------------------------------*/
|
||||
|
||||
/*
|
||||
Eric Meyer's final reset.css
|
||||
Source: http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
|
||||
*/
|
||||
.VS-search div, .VS-search span, .VS-search a, .VS-search img,
|
||||
.VS-search ul, .VS-search li, .VS-search form, .VS-search label,
|
||||
.VS-interface ul, .VS-interface li, .VS-interface {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.VS-search :focus {
|
||||
outline: 0;
|
||||
}
|
||||
.VS-search {
|
||||
line-height: 1;
|
||||
color: black;
|
||||
}
|
||||
.VS-search ol, .VS-search ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* ===================== */
|
||||
/* = General and Reset = */
|
||||
/* ===================== */
|
||||
|
||||
.VS-search {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #373737;
|
||||
font-size: 12px;
|
||||
}
|
||||
.VS-search input {
|
||||
display: block;
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
margin: 0; padding: 4px;
|
||||
background: transparent;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
.VS-interface, .VS-search .dialog, .VS-search input {
|
||||
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
/* ========== */
|
||||
/* = Layout = */
|
||||
/* ========== */
|
||||
|
||||
.VS-search .VS-search-box {
|
||||
cursor: text;
|
||||
position: relative;
|
||||
background: transparent;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 16px; -webkit-border-radius: 16px; -moz-border-radius: 16px;
|
||||
background-color: #fafafa;
|
||||
-webkit-box-shadow: inset 0px 0px 3px #ccc;
|
||||
-moz-box-shadow: inset 0px 0px 3px #ccc;
|
||||
box-shadow: inset 0px 0px 3px #ccc;
|
||||
min-height: 28px;
|
||||
height: auto;
|
||||
}
|
||||
.VS-search .VS-search-box.VS-focus {
|
||||
border-color: #acf;
|
||||
-webkit-box-shadow: inset 0px 0px 3px #acf;
|
||||
-moz-box-shadow: inset 0px 0px 3px #acf;
|
||||
box-shadow: inset 0px 0px 3px #acf;
|
||||
}
|
||||
.VS-search .VS-search-inner {
|
||||
position: relative;
|
||||
margin: 0 20px 0 22px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.VS-search input {
|
||||
width: 100px;
|
||||
}
|
||||
.VS-search input,
|
||||
.VS-search .VS-input-width-tester {
|
||||
padding: 6px 0;
|
||||
float: left;
|
||||
color: #808080;
|
||||
font: 13px/17px Helvetica, Arial;
|
||||
}
|
||||
.VS-search.VS-focus input {
|
||||
color: #606060;
|
||||
}
|
||||
.VS-search .VS-icon-search {
|
||||
position: absolute;
|
||||
left: 9px; top: 8px;
|
||||
}
|
||||
.VS-search .VS-icon-cancel {
|
||||
position: absolute;
|
||||
right: 9px; top: 8px;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Search Facet = */
|
||||
/* ================ */
|
||||
|
||||
.VS-search .search_facet {
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0 0 0 14px;
|
||||
position: relative;
|
||||
border: 1px solid transparent;
|
||||
height: 20px;
|
||||
margin: 3px -3px 3px 0;
|
||||
}
|
||||
.VS-search .search_facet.is_selected {
|
||||
margin-left: -3px;
|
||||
-webkit-border-radius: 16px;
|
||||
-moz-border-radius: 16px;
|
||||
border-radius: 16px;
|
||||
background-color: #d2e6fd;
|
||||
background-image: -moz-linear-gradient(top, #d2e6fd, #b0d1f9); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d2e6fd), to(#b0d1f9)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #d2e6fd, #b0d1f9);
|
||||
border: 1px solid #6eadf5;
|
||||
}
|
||||
.VS-search .search_facet .category {
|
||||
float: left;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
color: #808080;
|
||||
padding: 8px 0 5px;
|
||||
line-height: 13px;
|
||||
cursor: pointer;
|
||||
padding: 4px 0 0;
|
||||
}
|
||||
.VS-search .search_facet.is_selected .category {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_input_container {
|
||||
float: left;
|
||||
}
|
||||
.VS-search .search_facet input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
padding: 5px 0 5px 4px;
|
||||
height: 16px;
|
||||
width: auto;
|
||||
z-index: 100;
|
||||
position: relative;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 2px;
|
||||
padding-right: 3px;
|
||||
|
||||
}
|
||||
.VS-search .search_facet.is_editing input,
|
||||
.VS-search .search_facet.is_selected input {
|
||||
color: #000;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_remove {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 4px;
|
||||
}
|
||||
.VS-search .search_facet.is_selected .search_facet_remove {
|
||||
opacity: 0.4;
|
||||
left: 3px;
|
||||
filter: alpha(opacity=40);
|
||||
background-position: center -11px;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_remove:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.VS-search .search_facet.is_editing .category,
|
||||
.VS-search .search_facet.is_selected .category {
|
||||
color: #000;
|
||||
}
|
||||
.VS-search .search_facet.search_facet_maybe_delete .category,
|
||||
.VS-search .search_facet.search_facet_maybe_delete input {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Search Input = */
|
||||
/* ================ */
|
||||
|
||||
.VS-search .search_input {
|
||||
height: 28px;
|
||||
float: left;
|
||||
margin-left: -1px;
|
||||
}
|
||||
.VS-search .search_input input {
|
||||
padding: 6px 3px 6px 2px;
|
||||
line-height: 10px;
|
||||
height: 22px;
|
||||
margin-top: -4px;
|
||||
width: 10px;
|
||||
z-index: 100;
|
||||
min-width: 4px;
|
||||
position: relative;
|
||||
}
|
||||
.VS-search .search_input.is_editing input {
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Autocomplete = */
|
||||
/* ================ */
|
||||
|
||||
.VS-interface.ui-autocomplete {
|
||||
position: absolute;
|
||||
border: 1px solid #C0C0C0;
|
||||
border-top: 1px solid #D9D9D9;
|
||||
background-color: #F6F6F6;
|
||||
cursor: pointer;
|
||||
z-index: 10000;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
min-width: 80px;
|
||||
max-width: 220px;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
font-size: 13px;
|
||||
top: 5px;
|
||||
opacity: 0.97;
|
||||
box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5); -moz-box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-autocomplete-category {
|
||||
text-transform: capitalize;
|
||||
font-size: 11px;
|
||||
padding: 4px 4px 4px;
|
||||
border-top: 1px solid #A2A2A2;
|
||||
border-bottom: 1px solid #A2A2A2;
|
||||
background-color: #B7B7B7;
|
||||
text-shadow: 0 -1px 0 #999;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
cursor: default;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item {
|
||||
float: none;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item a {
|
||||
color: #000;
|
||||
outline: none;
|
||||
display: block;
|
||||
padding: 3px 4px 5px;
|
||||
border-radius: none;
|
||||
line-height: 1;
|
||||
background-color: #F8F8F8;
|
||||
background-image: -moz-linear-gradient(top, #F8F8F8, #F3F3F3); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#F8F8F8), to(#F3F3F3)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #F8F8F8, #F3F3F3);
|
||||
border-top: 1px solid #FAFAFA;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item a:active {
|
||||
outline: none;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item .ui-state-hover {
|
||||
background-color: #6483F7;
|
||||
background-image: -moz-linear-gradient(top, #648bF5, #2465f3); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#648bF5), to(#2465f3)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #648bF5, #2465f3);
|
||||
border-top: 1px solid #5b83ec;
|
||||
border-bottom: 1px solid #1459e9;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
color: white;
|
||||
margin: 0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-corner-all {
|
||||
border-radius: 0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete li {
|
||||
list-style: none;
|
||||
width: auto;
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
.VS-search .VS-icon {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
vertical-align: middle;
|
||||
width: 16px; height: 16px;
|
||||
}
|
||||
.VS-search .VS-icon-cancel {
|
||||
width: 11px; height: 11px;
|
||||
background-position: center 0;
|
||||
background-image: url(../images/embed/icons/cancel_search.png?1311104738);
|
||||
cursor: pointer;
|
||||
}
|
||||
.VS-search .VS-icon-cancel:hover {
|
||||
background-position: center -11px;
|
||||
}
|
||||
.VS-search .VS-icon-search {
|
||||
width: 12px; height: 12px;
|
||||
background-image: url(../images/embed/icons/search_glyph.png?1311104738);
|
||||
}
|
||||
|
||||
/*------------------------------ RESET + DEFAULT STYLES ---------------------------------*/
|
||||
|
||||
/*
|
||||
Eric Meyer's final reset.css
|
||||
Source: http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
|
||||
*/
|
||||
.VS-search div, .VS-search span, .VS-search a, .VS-search img,
|
||||
.VS-search ul, .VS-search li, .VS-search form, .VS-search label,
|
||||
.VS-interface ul, .VS-interface li, .VS-interface {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.VS-search :focus {
|
||||
outline: 0;
|
||||
}
|
||||
.VS-search {
|
||||
line-height: 1;
|
||||
color: black;
|
||||
}
|
||||
.VS-search ol, .VS-search ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* ===================== */
|
||||
/* = General and Reset = */
|
||||
/* ===================== */
|
||||
|
||||
.VS-search {
|
||||
font-family: Arial, sans-serif;
|
||||
color: #373737;
|
||||
font-size: 12px;
|
||||
}
|
||||
.VS-search input {
|
||||
display: block;
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
margin: 0; padding: 4px;
|
||||
background: transparent;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
.VS-interface, .VS-search .dialog, .VS-search input {
|
||||
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
/* ========== */
|
||||
/* = Layout = */
|
||||
/* ========== */
|
||||
|
||||
.VS-search .VS-search-box {
|
||||
cursor: text;
|
||||
position: relative;
|
||||
background: transparent;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 16px; -webkit-border-radius: 16px; -moz-border-radius: 16px;
|
||||
background-color: #fafafa;
|
||||
-webkit-box-shadow: inset 0px 0px 3px #ccc;
|
||||
-moz-box-shadow: inset 0px 0px 3px #ccc;
|
||||
box-shadow: inset 0px 0px 3px #ccc;
|
||||
min-height: 28px;
|
||||
height: auto;
|
||||
}
|
||||
.VS-search .VS-search-box.VS-focus {
|
||||
border-color: #acf;
|
||||
-webkit-box-shadow: inset 0px 0px 3px #acf;
|
||||
-moz-box-shadow: inset 0px 0px 3px #acf;
|
||||
box-shadow: inset 0px 0px 3px #acf;
|
||||
}
|
||||
.VS-search .VS-search-inner {
|
||||
position: relative;
|
||||
margin: 0 20px 0 22px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.VS-search input {
|
||||
width: 100px;
|
||||
}
|
||||
.VS-search input,
|
||||
.VS-search .VS-input-width-tester {
|
||||
padding: 6px 0;
|
||||
float: left;
|
||||
color: #808080;
|
||||
font: 13px/17px Helvetica, Arial;
|
||||
}
|
||||
.VS-search.VS-focus input {
|
||||
color: #606060;
|
||||
}
|
||||
.VS-search .VS-icon-search {
|
||||
position: absolute;
|
||||
left: 9px; top: 8px;
|
||||
}
|
||||
.VS-search .VS-icon-cancel {
|
||||
position: absolute;
|
||||
right: 9px; top: 8px;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Search Facet = */
|
||||
/* ================ */
|
||||
|
||||
.VS-search .search_facet {
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 0 0 0 14px;
|
||||
position: relative;
|
||||
border: 1px solid transparent;
|
||||
height: 20px;
|
||||
margin: 3px -3px 3px 0;
|
||||
}
|
||||
.VS-search .search_facet.is_selected {
|
||||
margin-left: -3px;
|
||||
-webkit-border-radius: 16px;
|
||||
-moz-border-radius: 16px;
|
||||
border-radius: 16px;
|
||||
background-color: #d2e6fd;
|
||||
background-image: -moz-linear-gradient(top, #d2e6fd, #b0d1f9); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d2e6fd), to(#b0d1f9)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #d2e6fd, #b0d1f9);
|
||||
border: 1px solid #6eadf5;
|
||||
}
|
||||
.VS-search .search_facet .category {
|
||||
float: left;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
color: #808080;
|
||||
padding: 8px 0 5px;
|
||||
line-height: 13px;
|
||||
cursor: pointer;
|
||||
padding: 4px 0 0;
|
||||
}
|
||||
.VS-search .search_facet.is_selected .category {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_input_container {
|
||||
float: left;
|
||||
}
|
||||
.VS-search .search_facet input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
padding: 5px 0 5px 4px;
|
||||
height: 16px;
|
||||
width: auto;
|
||||
z-index: 100;
|
||||
position: relative;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 2px;
|
||||
padding-right: 3px;
|
||||
|
||||
}
|
||||
.VS-search .search_facet.is_editing input,
|
||||
.VS-search .search_facet.is_selected input {
|
||||
color: #000;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_remove {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 4px;
|
||||
}
|
||||
.VS-search .search_facet.is_selected .search_facet_remove {
|
||||
opacity: 0.4;
|
||||
left: 3px;
|
||||
filter: alpha(opacity=40);
|
||||
background-position: center -11px;
|
||||
}
|
||||
.VS-search .search_facet .search_facet_remove:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.VS-search .search_facet.is_editing .category,
|
||||
.VS-search .search_facet.is_selected .category {
|
||||
color: #000;
|
||||
}
|
||||
.VS-search .search_facet.search_facet_maybe_delete .category,
|
||||
.VS-search .search_facet.search_facet_maybe_delete input {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Search Input = */
|
||||
/* ================ */
|
||||
|
||||
.VS-search .search_input {
|
||||
height: 28px;
|
||||
float: left;
|
||||
margin-left: -1px;
|
||||
}
|
||||
.VS-search .search_input input {
|
||||
padding: 6px 3px 6px 2px;
|
||||
line-height: 10px;
|
||||
height: 22px;
|
||||
margin-top: -4px;
|
||||
width: 10px;
|
||||
z-index: 100;
|
||||
min-width: 4px;
|
||||
position: relative;
|
||||
}
|
||||
.VS-search .search_input.is_editing input {
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
/* ================ */
|
||||
/* = Autocomplete = */
|
||||
/* ================ */
|
||||
|
||||
.VS-interface.ui-autocomplete {
|
||||
position: absolute;
|
||||
border: 1px solid #C0C0C0;
|
||||
border-top: 1px solid #D9D9D9;
|
||||
background-color: #F6F6F6;
|
||||
cursor: pointer;
|
||||
z-index: 10000;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
min-width: 80px;
|
||||
max-width: 220px;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
font-size: 13px;
|
||||
top: 5px;
|
||||
opacity: 0.97;
|
||||
box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5); -moz-box-shadow: 3px 4px 5px -2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-autocomplete-category {
|
||||
text-transform: capitalize;
|
||||
font-size: 11px;
|
||||
padding: 4px 4px 4px;
|
||||
border-top: 1px solid #A2A2A2;
|
||||
border-bottom: 1px solid #A2A2A2;
|
||||
background-color: #B7B7B7;
|
||||
text-shadow: 0 -1px 0 #999;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
cursor: default;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item {
|
||||
float: none;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item a {
|
||||
color: #000;
|
||||
outline: none;
|
||||
display: block;
|
||||
padding: 3px 4px 5px;
|
||||
border-radius: none;
|
||||
line-height: 1;
|
||||
background-color: #F8F8F8;
|
||||
background-image: -moz-linear-gradient(top, #F8F8F8, #F3F3F3); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#F8F8F8), to(#F3F3F3)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #F8F8F8, #F3F3F3);
|
||||
border-top: 1px solid #FAFAFA;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item a:active {
|
||||
outline: none;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-menu-item .ui-state-hover {
|
||||
background-color: #6483F7;
|
||||
background-image: -moz-linear-gradient(top, #648bF5, #2465f3); /* FF3.6 */
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#648bF5), to(#2465f3)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(top, #648bF5, #2465f3);
|
||||
border-top: 1px solid #5b83ec;
|
||||
border-bottom: 1px solid #1459e9;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
color: white;
|
||||
margin: 0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete .ui-corner-all {
|
||||
border-radius: 0;
|
||||
}
|
||||
.VS-interface.ui-autocomplete li {
|
||||
list-style: none;
|
||||
width: auto;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,453 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>DocumentCloud's VisualSearch.js</title>
|
||||
<style>
|
||||
body {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
background: #FEF3CA;
|
||||
color: #022;
|
||||
height: 100%;
|
||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
|
||||
}
|
||||
div.container {
|
||||
width: 720px;
|
||||
margin: 50px 0 50px 50px;
|
||||
}
|
||||
p, li {
|
||||
margin: 16px 0 16px 0;
|
||||
width: 550px;
|
||||
}
|
||||
p.break {
|
||||
margin-top: 35px;
|
||||
}
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
ol li {
|
||||
font-weight: bold;
|
||||
margin-left: 0;
|
||||
}
|
||||
a, a:visited {
|
||||
padding: 0 2px;
|
||||
text-decoration: none;
|
||||
background: #f0c095;
|
||||
color: #252519;
|
||||
}
|
||||
a:active, a:hover {
|
||||
color: #FFF;
|
||||
background: #C25D00;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 40px;
|
||||
}
|
||||
b.header {
|
||||
font-size: 18px;
|
||||
}
|
||||
span.alias {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
margin-left: 20px;
|
||||
}
|
||||
table {
|
||||
margin: 16px 0; padding: 0;
|
||||
}
|
||||
tr, td, th {
|
||||
margin: 0; padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
padding: 24px 0 0;
|
||||
}
|
||||
tr:first-child th {
|
||||
padding-top: 0;
|
||||
}
|
||||
td {
|
||||
padding: 6px 15px 6px 0;
|
||||
}
|
||||
td.definition {
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
}
|
||||
table.downloads td {
|
||||
padding-left: 18px;
|
||||
}
|
||||
.demo-hint {
|
||||
font-size: 13px;
|
||||
margin: 0 0 12px 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
#VS code, #VS pre, #VS tt {
|
||||
font-family: Monaco, Consolas, "Lucida Console", monospace;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
color: #444;
|
||||
background: none;
|
||||
}
|
||||
#VS code {
|
||||
margin-left: 8px;
|
||||
padding: 0 0 0 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
#VS pre {
|
||||
font-size: 12px;
|
||||
padding: 2px 0 2px 0;
|
||||
border-left: 6px solid #829C37;
|
||||
margin: 12px 0;
|
||||
}
|
||||
#search_query {
|
||||
margin: 18px 0;
|
||||
opacity: 0;
|
||||
}
|
||||
#search_query .raquo {
|
||||
font-size: 18px;
|
||||
line-height: 12px;
|
||||
font-weight: bold;
|
||||
margin-right: 4px;
|
||||
}
|
||||
#search_query2 {
|
||||
margin: 18px 0;
|
||||
opacity: 0;
|
||||
}
|
||||
#search_query2 .raquo {
|
||||
font-size: 18px;
|
||||
line-height: 12px;
|
||||
font-weight: bold;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="lib/css/reset.css" type="text/css" media="screen" charset="utf-8">
|
||||
<link rel="stylesheet" href="lib/css/icons.css" type="text/css" media="screen" charset="utf-8">
|
||||
<link rel="stylesheet" href="lib/css/workspace.css" type="text/css" media="screen" charset="utf-8">
|
||||
|
||||
<script src="vendor/jquery-1.6.1.js" type="text/javascript" charset="utf-8"></script>
|
||||
<!-- <script src="vendor/backported/jquery-1.4.4.js" type="text/javascript" charset="utf-8"></script> -->
|
||||
<script src="vendor/jquery.ui.core.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="vendor/jquery.ui.widget.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="vendor/jquery.ui.position.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="vendor/jquery.ui.autocomplete.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="vendor/underscore-1.1.5.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="vendor/backbone-0.5.0.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/visualsearch.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/views/search_box.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/views/search_facet.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/views/search_input.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/models/search_facets.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/models/search_query.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/utils/backbone_extensions.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/utils/hotkeys.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/utils/jquery_extensions.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/utils/search_parser.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/utils/inflector.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="lib/js/templates/templates.js" type="text/javascript" charset="utf-8"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container" id="VS">
|
||||
|
||||
<h1><a href="index.html">VisualSearch.js</a></h1>
|
||||
|
||||
<p>
|
||||
<a href="http://github.com/documentcloud/visualsearch">VisualSearch.js</a>
|
||||
enhances ordinary search boxes with the ability to autocomplete
|
||||
faceted search queries. Specify the facets for completion, along with the
|
||||
completable values for any facet. You can retrieve the search query as a
|
||||
structured object, so you don't have to parse the query string yourself.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="docs/visualsearch.html">The complete annotated source code</a>
|
||||
is also available.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The project is
|
||||
<a href="http://github.com/documentcloud/visualsearch/">hosted on GitHub</a>.
|
||||
You can report bugs and discuss features on the
|
||||
<a href="http://github.com/documentcloud/visualsearch/issues">issues page</a>,
|
||||
on Freenode in the <tt>#documentcloud</tt> channel,
|
||||
or send tweets to <a href="http://twitter.com/documentcloud">@documentcloud</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<i>VisualSearch.js is an open-source component of <a href="http://documentcloud.org/">DocumentCloud</a>.</i>
|
||||
</p>
|
||||
<h2 id="demo">Demo <span class="demo-hint"><i>Try searching for: <b>account</b>, <b>filter</b>, <b>access</b>, <b>title</b>, <b>city</b>, <b>state</b>, or <b>country</b>.</i></span></h2>
|
||||
|
||||
<div id="search_box_container"></div>
|
||||
<div id="search_query"> </div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(document).ready(function() {
|
||||
window.visualSearch = VS.init({
|
||||
container : $('#search_box_container'),
|
||||
query : 'country: "South Africa" account: 5-samuel title: "Pentagon Papers"',
|
||||
// query : '',
|
||||
unquotable : [
|
||||
'text',
|
||||
'account',
|
||||
'filter',
|
||||
'access'
|
||||
],
|
||||
callbacks : {
|
||||
search : function(query, searchCollection) {
|
||||
var $query = $('#search_query');
|
||||
$query.stop().animate({opacity : 1}, {duration: 300, queue: false});
|
||||
$query.html('<span class="raquo">»</span> You searched for: <b>' + searchCollection.serialize() + '</b>');
|
||||
clearTimeout(window.queryHideDelay);
|
||||
window.queryHideDelay = setTimeout(function() {
|
||||
$query.animate({
|
||||
opacity : 0
|
||||
}, {
|
||||
duration: 1000,
|
||||
queue: false
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
valueMatches : function(category, searchTerm, callback) {
|
||||
switch (category) {
|
||||
case 'account':
|
||||
callback([
|
||||
{ value: '1-amanda', label: 'Amanda' },
|
||||
{ value: '2-aron', label: 'Aron' },
|
||||
{ value: '3-eric', label: 'Eric' },
|
||||
{ value: '4-jeremy', label: 'Jeremy' },
|
||||
{ value: '5-samuel', label: 'Samuel' },
|
||||
{ value: '6-scott', label: 'Scott' }
|
||||
]);
|
||||
break;
|
||||
case 'filter':
|
||||
callback(['published', 'unpublished', 'draft']);
|
||||
break;
|
||||
case 'access':
|
||||
callback(['public', 'private', 'protected']);
|
||||
break;
|
||||
case 'title':
|
||||
callback([
|
||||
'Pentagon Papers',
|
||||
'CoffeeScript Manual',
|
||||
'Laboratory for Object Oriented Thinking',
|
||||
'A Repository Grows in Brooklyn'
|
||||
]);
|
||||
break;
|
||||
case 'city':
|
||||
callback([
|
||||
'Cleveland',
|
||||
'New York City',
|
||||
'Brooklyn',
|
||||
'Manhattan',
|
||||
'Queens',
|
||||
'The Bronx',
|
||||
'Staten Island',
|
||||
'San Francisco',
|
||||
'Los Angeles',
|
||||
'Seattle',
|
||||
'London',
|
||||
'Portland',
|
||||
'Chicago',
|
||||
'Boston'
|
||||
])
|
||||
break;
|
||||
case 'state':
|
||||
callback([
|
||||
"Alabama", "Alaska", "Arizona", "Arkansas", "California",
|
||||
"Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
|
||||
"Georgia", "Guam", "Hawaii", "Idaho", "Illinois",
|
||||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
|
||||
"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
|
||||
"Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
|
||||
"New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
|
||||
"North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
|
||||
"Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
|
||||
"Texas", "Utah", "Vermont", "Virginia", "Virgin Islands",
|
||||
"Washington", "West Virginia", "Wisconsin", "Wyoming"
|
||||
]);
|
||||
break
|
||||
case 'country':
|
||||
callback([
|
||||
"China", "India", "United States", "Indonesia", "Brazil",
|
||||
"Pakistan", "Bangladesh", "Nigeria", "Russia", "Japan",
|
||||
"Mexico", "Philippines", "Vietnam", "Ethiopia", "Egypt",
|
||||
"Germany", "Turkey", "Iran", "Thailand", "D. R. of Congo",
|
||||
"France", "United Kingdom", "Italy", "Myanmar", "South Africa",
|
||||
"South Korea", "Colombia", "Ukraine", "Spain", "Tanzania",
|
||||
"Sudan", "Kenya", "Argentina", "Poland", "Algeria",
|
||||
"Canada", "Uganda", "Morocco", "Iraq", "Nepal",
|
||||
"Peru", "Afghanistan", "Venezuela", "Malaysia", "Uzbekistan",
|
||||
"Saudi Arabia", "Ghana", "Yemen", "North Korea", "Mozambique",
|
||||
"Taiwan", "Syria", "Ivory Coast", "Australia", "Romania",
|
||||
"Sri Lanka", "Madagascar", "Cameroon", "Angola", "Chile",
|
||||
"Netherlands", "Burkina Faso", "Niger", "Kazakhstan", "Malawi",
|
||||
"Cambodia", "Guatemala", "Ecuador", "Mali", "Zambia",
|
||||
"Senegal", "Zimbabwe", "Chad", "Cuba", "Greece",
|
||||
"Portugal", "Belgium", "Czech Republic", "Tunisia", "Guinea",
|
||||
"Rwanda", "Dominican Republic", "Haiti", "Bolivia", "Hungary",
|
||||
"Belarus", "Somalia", "Sweden", "Benin", "Azerbaijan",
|
||||
"Burundi", "Austria", "Honduras", "Switzerland", "Bulgaria",
|
||||
"Serbia", "Israel", "Tajikistan", "Hong Kong", "Papua New Guinea",
|
||||
"Togo", "Libya", "Jordan", "Paraguay", "Laos",
|
||||
"El Salvador", "Sierra Leone", "Nicaragua", "Kyrgyzstan", "Denmark",
|
||||
"Slovakia", "Finland", "Eritrea", "Turkmenistan"
|
||||
], {preserveOrder: true});
|
||||
break;
|
||||
}
|
||||
},
|
||||
facetMatches : function(callback) {
|
||||
callback([
|
||||
'account', 'filter', 'access', 'title',
|
||||
{ label: 'city', category: 'location' },
|
||||
{ label: 'address', category: 'location' },
|
||||
{ label: 'country', category: 'location' },
|
||||
{ label: 'state', category: 'location' },
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div id="search_box_container2"></div>
|
||||
<div id="search_query2"> </div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(document).ready(function() {
|
||||
var visualSearch = VS.init({
|
||||
container : $('#search_box_container2'),
|
||||
query : '',
|
||||
// query : '',
|
||||
unquotable : [
|
||||
'text',
|
||||
'account',
|
||||
'filter',
|
||||
'access'
|
||||
],
|
||||
callbacks : {
|
||||
search : function(query, searchCollection) {
|
||||
console.log(["query", searchCollection.facets(), query]);
|
||||
var $query = $('#search_query2');
|
||||
$query.stop().animate({opacity : 1}, {duration: 300, queue: false});
|
||||
$query.html('<span class="raquo">»</span> You searched for: <b>' + searchCollection.serialize() + '</b>');
|
||||
clearTimeout(window.queryHideDelay2);
|
||||
window.queryHideDelay2 = setTimeout(function() {
|
||||
$query.animate({
|
||||
opacity : 0
|
||||
}, {
|
||||
duration: 1000,
|
||||
queue: false
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
valueMatches : function(category, searchTerm, callback) {
|
||||
switch (category) {
|
||||
case 'account':
|
||||
callback([
|
||||
{ value: '1-amanda', label: 'Amanda' },
|
||||
{ value: '2-aron', label: 'Aron' },
|
||||
{ value: '3-eric', label: 'Eric' },
|
||||
{ value: '4-jeremy', label: 'Jeremy' },
|
||||
{ value: '5-samuel', label: 'Samuel' },
|
||||
{ value: '6-scott', label: 'Scott' }
|
||||
]);
|
||||
break;
|
||||
case 'filter':
|
||||
callback(['published', 'unpublished', 'draft']);
|
||||
break;
|
||||
case 'access':
|
||||
callback(['public', 'private', 'protected']);
|
||||
break;
|
||||
case 'title':
|
||||
callback([
|
||||
'Pentagon Papers',
|
||||
'CoffeeScript Manual',
|
||||
'Laboratory for Object Oriented Thinking',
|
||||
'A Repository Grows in Brooklyn'
|
||||
]);
|
||||
break;
|
||||
case 'city':
|
||||
callback([
|
||||
'Cleveland',
|
||||
'New York City',
|
||||
'Brooklyn',
|
||||
'Manhattan',
|
||||
'Queens',
|
||||
'The Bronx',
|
||||
'Staten Island',
|
||||
'San Francisco',
|
||||
'Los Angeles',
|
||||
'Seattle',
|
||||
'London',
|
||||
'Portland',
|
||||
'Chicago',
|
||||
'Boston'
|
||||
])
|
||||
break;
|
||||
case 'state':
|
||||
callback([
|
||||
"Alabama", "Alaska", "Arizona", "Arkansas", "California",
|
||||
"Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
|
||||
"Georgia", "Guam", "Hawaii", "Idaho", "Illinois",
|
||||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
|
||||
"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
|
||||
"Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
|
||||
"New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
|
||||
"North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
|
||||
"Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
|
||||
"Texas", "Utah", "Vermont", "Virginia", "Virgin Islands",
|
||||
"Washington", "West Virginia", "Wisconsin", "Wyoming"
|
||||
]);
|
||||
break
|
||||
case 'country':
|
||||
callback([
|
||||
"China", "India", "United States", "Indonesia", "Brazil",
|
||||
"Pakistan", "Bangladesh", "Nigeria", "Russia", "Japan",
|
||||
"Mexico", "Philippines", "Vietnam", "Ethiopia", "Egypt",
|
||||
"Germany", "Turkey", "Iran", "Thailand", "D. R. of Congo",
|
||||
"France", "United Kingdom", "Italy", "Myanmar", "South Africa",
|
||||
"South Korea", "Colombia", "Ukraine", "Spain", "Tanzania",
|
||||
"Sudan", "Kenya", "Argentina", "Poland", "Algeria",
|
||||
"Canada", "Uganda", "Morocco", "Iraq", "Nepal",
|
||||
"Peru", "Afghanistan", "Venezuela", "Malaysia", "Uzbekistan",
|
||||
"Saudi Arabia", "Ghana", "Yemen", "North Korea", "Mozambique",
|
||||
"Taiwan", "Syria", "Ivory Coast", "Australia", "Romania",
|
||||
"Sri Lanka", "Madagascar", "Cameroon", "Angola", "Chile",
|
||||
"Netherlands", "Burkina Faso", "Niger", "Kazakhstan", "Malawi",
|
||||
"Cambodia", "Guatemala", "Ecuador", "Mali", "Zambia",
|
||||
"Senegal", "Zimbabwe", "Chad", "Cuba", "Greece",
|
||||
"Portugal", "Belgium", "Czech Republic", "Tunisia", "Guinea",
|
||||
"Rwanda", "Dominican Republic", "Haiti", "Bolivia", "Hungary",
|
||||
"Belarus", "Somalia", "Sweden", "Benin", "Azerbaijan",
|
||||
"Burundi", "Austria", "Honduras", "Switzerland", "Bulgaria",
|
||||
"Serbia", "Israel", "Tajikistan", "Hong Kong", "Papua New Guinea",
|
||||
"Togo", "Libya", "Jordan", "Paraguay", "Laos",
|
||||
"El Salvador", "Sierra Leone", "Nicaragua", "Kyrgyzstan", "Denmark",
|
||||
"Slovakia", "Finland", "Eritrea", "Turkmenistan"
|
||||
]);
|
||||
break;
|
||||
}
|
||||
},
|
||||
facetMatches : function(callback) {
|
||||
callback([
|
||||
'account', 'filter', 'access', 'title',
|
||||
{ label: 'city', category: 'location' },
|
||||
{ label: 'address', category: 'location' },
|
||||
{ label: 'country', category: 'location' },
|
||||
{ label: 'state', category: 'location' },
|
||||
], {
|
||||
preserveOrder: true
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,537 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>DocumentCloud's VisualSearch.js</title>
|
||||
<style>
|
||||
body {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
background: #FEF3CA;
|
||||
height: 100%;
|
||||
color: #022;
|
||||
font-family: Arial;
|
||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
|
||||
}
|
||||
div.container {
|
||||
width: 720px;
|
||||
margin: 50px 0 50px 50px;
|
||||
}
|
||||
p, li {
|
||||
margin: 16px 0 16px 0;
|
||||
width: 550px;
|
||||
}
|
||||
p.break {
|
||||
margin-top: 35px;
|
||||
}
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
ol li {
|
||||
font-weight: bold;
|
||||
margin-left: 0;
|
||||
}
|
||||
a, a:visited {
|
||||
padding: 0 2px;
|
||||
text-decoration: none;
|
||||
background: #f0c095;
|
||||
color: #252519;
|
||||
}
|
||||
a:active, a:hover {
|
||||
color: #000;
|
||||
background: #e0a070;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 40px;
|
||||
}
|
||||
b.header {
|
||||
font-size: 18px;
|
||||
}
|
||||
span.alias {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
margin-left: 20px;
|
||||
}
|
||||
table {
|
||||
margin: 16px 0; padding: 0;
|
||||
}
|
||||
tr, td, th {
|
||||
margin: 0; padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
padding: 24px 0 0;
|
||||
}
|
||||
tr:first-child th {
|
||||
padding-top: 0;
|
||||
}
|
||||
td {
|
||||
padding: 6px 15px 6px 0;
|
||||
}
|
||||
td.definition {
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
}
|
||||
table.downloads td {
|
||||
padding-left: 18px;
|
||||
}
|
||||
.demo-hint {
|
||||
font-size: 13px;
|
||||
margin: 0 0 12px 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
#VS code, #VS pre, #VS tt {
|
||||
font-family: Monaco, Consolas, "Lucida Console", monospace;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
color: #444;
|
||||
background: none;
|
||||
}
|
||||
#VS code {
|
||||
margin-left: 8px;
|
||||
padding: 0 0 0 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
#VS pre {
|
||||
font-size: 12px;
|
||||
padding: 2px 0 2px 0;
|
||||
border-left: 6px solid #829C37;
|
||||
margin: 12px 0;
|
||||
}
|
||||
#search_query {
|
||||
margin: 18px 0 -24px;
|
||||
opacity: 0;
|
||||
}
|
||||
#search_query .raquo {
|
||||
font-size: 18px;
|
||||
line-height: 12px;
|
||||
font-weight: bold;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.attribution {
|
||||
margin: -12px 0 24px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="build-min/visualsearch-datauri.css" type="text/css" media="screen" charset="utf-8">
|
||||
<link rel="stylesheet" href="docs/assets/github.css" type="text/css" media="screen" charset="utf-8">
|
||||
|
||||
<script src="build-min/dependencies.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="build-min/visualsearch.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="docs/assets/highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="docs/assets/javascript.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="docs/assets/xml.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
hljs.initHighlightingOnLoad();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container" id="VS">
|
||||
|
||||
<h1>VisualSearch.js</h1>
|
||||
|
||||
<p class="attribution">
|
||||
<i>
|
||||
Created by <a href="http://github.com/samuelclay">Samuel Clay</a>,
|
||||
<a href="http://twitter.com/samuelclay">@samuelclay</a>.
|
||||
</i>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="http://github.com/documentcloud/visualsearch">VisualSearch.js</a>
|
||||
enhances ordinary search boxes with the ability to autocomplete
|
||||
faceted search queries. Specify the facets for completion, along with the
|
||||
completable values for any facet. You can retrieve the search query as a
|
||||
structured object, so you don't have to parse the query string yourself.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://www.documentcloud.org/public/#search/group%3A%20dcloud%20chair%3A%20%22Christopher%20Dodd%22%20TARP">Here's an example of a search on DocumentCloud.org that uses facets.</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The project is
|
||||
<a href="http://github.com/documentcloud/visualsearch/">hosted on GitHub</a>.
|
||||
You can report bugs and discuss features on the
|
||||
<a href="http://github.com/documentcloud/visualsearch/issues">issues page</a>,
|
||||
on Freenode in the <tt>#documentcloud</tt> channel,
|
||||
or send tweets to <a href="http://twitter.com/documentcloud">@documentcloud</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<i>VisualSearch.js is an open-source component of <a href="http://documentcloud.org/">DocumentCloud</a>.
|
||||
<br />
|
||||
<a href="docs/visualsearch.html">The complete annotated source code</a>
|
||||
is also available.</i>
|
||||
</p>
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
|
||||
<a href="#demo">Demo</a> | <a href="#downloads">Downloads</a> | <a href="#usage">Usage</a> | <a href="#changelog">Change Log</a>
|
||||
|
||||
|
||||
<h2 id="demo">Demo <span class="demo-hint"><i>Try searching for: <b>account</b>, <b>filter</b>, <b>access</b>, <b>title</b>, <b>city</b>, <b>state</b>, or <b>country</b>.</i></span></h2>
|
||||
|
||||
|
||||
|
||||
<div id="search_box_container"></div>
|
||||
<div id="search_query"> </div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(document).ready(function() {
|
||||
var visualSearch = VS.init({
|
||||
container : $('#search_box_container'),
|
||||
query : 'country: "United States" state: "New York" account: 5-samuel title: "Pentagon Papers"',
|
||||
unquotable : [
|
||||
'text',
|
||||
'account',
|
||||
'filter',
|
||||
'access'
|
||||
],
|
||||
callbacks : {
|
||||
search : function(query, searchCollection) {
|
||||
var $query = $('#search_query');
|
||||
var count = searchCollection.size();
|
||||
$query.stop().animate({opacity : 1}, {duration: 300, queue: false});
|
||||
$query.html('<span class="raquo">»</span> You searched for: ' +
|
||||
'<b>' + (query || '<i>nothing</i>') + '</b>. ' +
|
||||
'(' + count + ' facet' + (count==1 ? '' : 's') + ')');
|
||||
clearTimeout(window.queryHideDelay);
|
||||
window.queryHideDelay = setTimeout(function() {
|
||||
$query.animate({
|
||||
opacity : 0
|
||||
}, {
|
||||
duration: 1000,
|
||||
queue: false
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
facetMatches : function(callback) {
|
||||
callback([
|
||||
'account', 'filter', 'access', 'title',
|
||||
{ label: 'city', category: 'location' },
|
||||
{ label: 'country', category: 'location' },
|
||||
{ label: 'state', category: 'location' },
|
||||
]);
|
||||
},
|
||||
valueMatches : function(facet, searchTerm, callback) {
|
||||
switch (facet) {
|
||||
case 'account':
|
||||
callback([
|
||||
{ value: '1-amanda', label: 'Amanda' },
|
||||
{ value: '2-aron', label: 'Aron' },
|
||||
{ value: '3-eric', label: 'Eric' },
|
||||
{ value: '4-jeremy', label: 'Jeremy' },
|
||||
{ value: '5-samuel', label: 'Samuel' },
|
||||
{ value: '6-scott', label: 'Scott' }
|
||||
]);
|
||||
break;
|
||||
case 'filter':
|
||||
callback(['published', 'unpublished', 'draft']);
|
||||
break;
|
||||
case 'access':
|
||||
callback(['public', 'private', 'protected']);
|
||||
break;
|
||||
case 'title':
|
||||
callback([
|
||||
'Pentagon Papers',
|
||||
'CoffeeScript Manual',
|
||||
'Laboratory for Object Oriented Thinking',
|
||||
'A Repository Grows in Brooklyn'
|
||||
]);
|
||||
break;
|
||||
case 'city':
|
||||
callback([
|
||||
'Cleveland',
|
||||
'New York City',
|
||||
'Brooklyn',
|
||||
'Manhattan',
|
||||
'Queens',
|
||||
'The Bronx',
|
||||
'Staten Island',
|
||||
'San Francisco',
|
||||
'Los Angeles',
|
||||
'Seattle',
|
||||
'London',
|
||||
'Portland',
|
||||
'Chicago',
|
||||
'Boston'
|
||||
]);
|
||||
break;
|
||||
case 'state':
|
||||
callback([
|
||||
"Alabama", "Alaska", "Arizona", "Arkansas", "California",
|
||||
"Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
|
||||
"Georgia", "Guam", "Hawaii", "Idaho", "Illinois",
|
||||
"Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana",
|
||||
"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
|
||||
"Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
|
||||
"New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
|
||||
"North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
|
||||
"Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
|
||||
"Texas", "Utah", "Vermont", "Virginia", "Virgin Islands",
|
||||
"Washington", "West Virginia", "Wisconsin", "Wyoming"
|
||||
]);
|
||||
break;
|
||||
case 'country':
|
||||
callback([
|
||||
"China", "India", "United States", "Indonesia", "Brazil",
|
||||
"Pakistan", "Bangladesh", "Nigeria", "Russia", "Japan",
|
||||
"Mexico", "Philippines", "Vietnam", "Ethiopia", "Egypt",
|
||||
"Germany", "Turkey", "Iran", "Thailand", "D. R. of Congo",
|
||||
"France", "United Kingdom", "Italy", "Myanmar", "South Africa",
|
||||
"South Korea", "Colombia", "Ukraine", "Spain", "Tanzania",
|
||||
"Sudan", "Kenya", "Argentina", "Poland", "Algeria",
|
||||
"Canada", "Uganda", "Morocco", "Iraq", "Nepal",
|
||||
"Peru", "Afghanistan", "Venezuela", "Malaysia", "Uzbekistan",
|
||||
"Saudi Arabia", "Ghana", "Yemen", "North Korea", "Mozambique",
|
||||
"Taiwan", "Syria", "Ivory Coast", "Australia", "Romania",
|
||||
"Sri Lanka", "Madagascar", "Cameroon", "Angola", "Chile",
|
||||
"Netherlands", "Burkina Faso", "Niger", "Kazakhstan", "Malawi",
|
||||
"Cambodia", "Guatemala", "Ecuador", "Mali", "Zambia",
|
||||
"Senegal", "Zimbabwe", "Chad", "Cuba", "Greece",
|
||||
"Portugal", "Belgium", "Czech Republic", "Tunisia", "Guinea",
|
||||
"Rwanda", "Dominican Republic", "Haiti", "Bolivia", "Hungary",
|
||||
"Belarus", "Somalia", "Sweden", "Benin", "Azerbaijan",
|
||||
"Burundi", "Austria", "Honduras", "Switzerland", "Bulgaria",
|
||||
"Serbia", "Israel", "Tajikistan", "Hong Kong", "Papua New Guinea",
|
||||
"Togo", "Libya", "Jordan", "Paraguay", "Laos",
|
||||
"El Salvador", "Sierra Leone", "Nicaragua", "Kyrgyzstan", "Denmark",
|
||||
"Slovakia", "Finland", "Eritrea", "Turkmenistan"
|
||||
], {preserveOrder: true});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<h2 id="downloads">Downloads <i style="padding-left: 12px; font-size:12px;">(Right-click, and use "Save As")</i></h2>
|
||||
|
||||
<table class="downloads">
|
||||
|
||||
<tr>
|
||||
<th colspan="2">0. Everything (<tt>visualsearch.zip</tt>)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/documentcloud/visualsearch/zipball/master">Download everything</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th colspan="2">1. VisualSearch JavaScript (<tt>visualsearch.js</tt>)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build-min/visualsearch.js">Production Version (0.2.2)</a></td>
|
||||
<td><i>8kb, Minified and Gzipped</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build/visualsearch.js">Development Version (0.2.2)</a></td>
|
||||
<td><i>45kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th colspan="2">2. VisualSearch Stylesheets (<tt>visualsearch.css</tt>)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><i>You should include both the datauri and image urls versions. <a href="#css">See how to include both</a></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build-min/visualsearch-datauri.css">Production Version - datauri</a></td>
|
||||
<td><i>4kb, Minified and Gzipped</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build-min/visualsearch.css">Production Version - image urls</a></td>
|
||||
<td><i>4kb, Minified and Gzipped</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build/visualsearch.css">Development Version</a></td>
|
||||
<td><i>8kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">3. VisualSearch Images</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="lib/images/embed/icons/search_glyph.png"> <a href="lib/images/embed/icons/search_glyph.png">Search Glyph</a></td>
|
||||
<td><i>4kb, embedded in visualsearch-datauri.css</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="lib/images/embed/icons/cancel_search.png"> <a href="lib/images/embed/icons/cancel_search.png">Cancel Button</a></td>
|
||||
<td><i>4kb, embedded in visualsearch-datauri.css</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th colspan="2">4. VisualSearch Dependencies (<tt>jQuery 1.4+, jQuery UI, Underscore.js, Backbone.js</tt>)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><i>You should only include the dependencies you don't already have.</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build-min/dependencies.js">Production Version - All</a></td>
|
||||
<td><i>49kb, Minified and Gzipped</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="build/dependencies.js">Development Version - All</a></td>
|
||||
<td><i>340kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="vendor/jquery-1.6.1.js">jQuery 1.6.1</a></td>
|
||||
<td><i>238kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery UI 1.8.13: <br /><a href="vendor/jquery.ui.core.js">Core</a> <a href="vendor/jquery.ui.position.js">Position</a> <a href="vendor/jquery.ui.widget.js">Widget</a> <a href="vendor/jquery.ui.autocomplete.js">Autocomplete</a></td>
|
||||
<td><i>48kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="vendor/underscore-1.1.5.js">Underscore 1.1.5</a></td>
|
||||
<td><i>29kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="vendor/backbone-0.5.0.js">Backbone 0.5.0</a></td>
|
||||
<td><i>41kb, Uncompressed with Comments</i></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<p>To use VisualSearch.js on your site, follow these instructions on installation, configuration, and customization.</p>
|
||||
|
||||
<ol>
|
||||
<li class="xml" id="css">Insert the JavaScript and CSS into your page:<br />
|
||||
<pre><code><script src="visualsearch.js" type="text/javascript"></script>
|
||||
<!--[if (!IE)|(gte IE 8)]><!-->
|
||||
<link href="visualsearch-datauri.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--<![endif]-->
|
||||
<!--[if lte IE 7]><!-->
|
||||
<link href="visualsearch.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<!--<![endif]--></code></pre>
|
||||
</li>
|
||||
<li>Initialize the Visual Search box:<br />
|
||||
<pre class="javascript"><code><div class="visual_search"></div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(document).ready(function() {
|
||||
var visualSearch = VS.init({
|
||||
container : $('.visual_search'),
|
||||
query : '',
|
||||
callbacks : {
|
||||
search : function(query, searchCollection) {},
|
||||
facetMatches : function(callback) {},
|
||||
valueMatches : function(facet, searchTerm, callback) {}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script></code></pre>
|
||||
</li>
|
||||
<li class="javascript">Customize the autocompleted facets and values:
|
||||
<pre><code>callbacks : {
|
||||
...
|
||||
// These are the facets that will be autocompleted in an empty input.
|
||||
facetMatches : function(callback) {
|
||||
callback([
|
||||
'account', 'filter', 'access', 'title',
|
||||
{ label: 'city', category: 'location' },
|
||||
{ label: 'address', category: 'location' },
|
||||
{ label: 'country', category: 'location' },
|
||||
{ label: 'state', category: 'location' },
|
||||
]);
|
||||
}
|
||||
...
|
||||
// These are the values that match specific categories, autocompleted
|
||||
// in a category's input field. searchTerm can be used to filter the
|
||||
// list on the server-side, prior to providing a list to the widget.
|
||||
valueMatches : function(facet, searchTerm, callback) {
|
||||
switch (facet) {
|
||||
case 'account':
|
||||
callback([
|
||||
{ value: '1-amanda', label: 'Amanda' },
|
||||
{ value: '2-aron', label: 'Aron' },
|
||||
{ value: '3-eric', label: 'Eric' },
|
||||
{ value: '4-jeremy', label: 'Jeremy' },
|
||||
{ value: '5-samuel', label: 'Samuel' },
|
||||
{ value: '6-scott', label: 'Scott' }
|
||||
]);
|
||||
break;
|
||||
case 'filter':
|
||||
callback(['published', 'unpublished', 'draft']);
|
||||
break;
|
||||
case 'access':
|
||||
callback(['public', 'private', 'protected']);
|
||||
break;
|
||||
case 'title':
|
||||
callback([
|
||||
'Pentagon Papers',
|
||||
'CoffeeScript Manual',
|
||||
'Laboratory for Object Oriented Thinking',
|
||||
'A Repository Grows in Brooklyn'
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
...
|
||||
}</code></pre>
|
||||
</li>
|
||||
<li class="javascript">Inspect the Visual Search box
|
||||
<pre><code>// Returns the unstructured search query
|
||||
visualSearch.searchBox.value()
|
||||
// "country: "South Africa" account: 5-samuel title: "Pentagon Papers""
|
||||
|
||||
// Returns an array of Facet model instances
|
||||
visualSearch.searchQuery.facets()
|
||||
// [FacetModel<country:"South Africa">,
|
||||
// FacetModel<account:5-samuel>,
|
||||
// FacetModel<title:"Pentagon Papers">]
|
||||
|
||||
// Set the search query with raw text
|
||||
visualSearch.searchBox.value("Country: US State: \"New York\" Key: Value")
|
||||
|
||||
</code></pre>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2 id="changelog">Change Log</h2>
|
||||
|
||||
<p>
|
||||
<b class="header">0.2.2</b> <i>March 10th, 2012</i><br />
|
||||
If you do not want to automatically filter the value matches, you can pass an
|
||||
options hash with <tt>preserveMatches: true</tt> as the second argument to the callback.
|
||||
<a href="https://github.com/documentcloud/visualsearch/pull/44">See pull request #44</a> for details.
|
||||
</p>
|
||||
<p>
|
||||
<b class="header">0.2.1</b> <i>November 14th, 2011</i><br />
|
||||
The autocompleted facets and values that are provided by your callbacks <tt>facetMatches</tt>
|
||||
and <tt>valueMatches</tt> can now preserve the order of items you give them. Simply pass an
|
||||
options hash with <tt>preserveOrder: true</tt> as the second argument to the callback. See
|
||||
<a href="demo.html">the demo page</a> for an example.
|
||||
</p>
|
||||
<p>
|
||||
<b class="header">0.2.0</b> <i>August 10th, 2011</i><br />
|
||||
Multiple instances of VisualSearch on a single page. <tt>VS.init</tt> now returns
|
||||
a reference to the instance. The <tt>search</tt> callback now contains both the
|
||||
serialized search query and a reference to the search query collection (as a
|
||||
<a href="http://documentcloud.github.com/backbone/#Collection">Backbone.Collection</a>),
|
||||
which can be used to manipulate each facet directly. See
|
||||
<a href="docs/search_query.html">the source code for search_query.js</a> for available
|
||||
methods on the collection.
|
||||
</p>
|
||||
<p>
|
||||
<b class="header">0.1.0</b> <i>June 23rd, 2011</i><br />
|
||||
Initial release of VisualSearch.js.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="http://documentcloud.org/" title="A DocumentCloud Project" style="background:none;">
|
||||
<img src="http://jashkenas.s3.amazonaws.com/images/a_documentcloud_project.png" alt="A DocumentCloud Project" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -30,7 +30,7 @@
|
|||
border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
outline: none;
|
||||
|
@ -56,7 +56,7 @@
|
|||
background-image: linear-gradient(to bottom, #f6f6f6, #e3e3e3);
|
||||
-moz-box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
-webkit-box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
-box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
}
|
||||
.openerp2 a.button:active, .openerp2 a.button.active, .openerp2 button:active, .openerp2 button.active, .openerp2 input[type='submit']:active, .openerp2 input[type='submit'].active {
|
||||
background: #e3e3e3;
|
||||
|
@ -65,14 +65,14 @@
|
|||
background: linear-gradient(top, #e3e3e3, #f6f6f6) #1b468f;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp2 a.button.disabled, .openerp2 button:disabled, .openerp2 input[type='submit']:disabled {
|
||||
background: #efefef !important;
|
||||
border: 1px solid #d1d1d1 !important;
|
||||
-moz-box-shadow: none !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
color: #aaaaaa !important;
|
||||
cursor: default;
|
||||
text-shadow: 0 1px 1px white !important;
|
||||
|
@ -88,7 +88,7 @@
|
|||
background-image: linear-gradient(to bottom, #dc5f59, #b33630);
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp2 button.primary:hover {
|
||||
background-color: #df6b66;
|
||||
|
@ -100,7 +100,7 @@
|
|||
background-image: linear-gradient(to bottom, #df6b66, #bf3a33);
|
||||
-moz-box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp2 button.primary:active {
|
||||
background-color: #b33630;
|
||||
|
@ -112,7 +112,7 @@
|
|||
background-image: linear-gradient(to bottom, #b33630, #dc5f59);
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp2 button.following {
|
||||
color: white;
|
||||
|
@ -254,7 +254,7 @@
|
|||
color: white;
|
||||
-moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
}
|
||||
.openerp2 .oe_topbar .oe_topbar_item .oe_active {
|
||||
background: #303030;
|
||||
|
@ -262,7 +262,7 @@
|
|||
color: white;
|
||||
-moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
}
|
||||
.openerp2 .oe_topbar .oe_topbar_avatar {
|
||||
width: 24px;
|
||||
|
@ -325,7 +325,7 @@
|
|||
border-radius: 0 0 6px 6px;
|
||||
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
|
@ -353,7 +353,7 @@
|
|||
background-image: linear-gradient(to bottom, #292929, #191919);
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp2 .oe_leftbar {
|
||||
width: 220px;
|
||||
|
@ -413,7 +413,7 @@
|
|||
color: white;
|
||||
-moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
}
|
||||
.openerp2 .oe_menu .oe_active {
|
||||
background: #303030;
|
||||
|
@ -421,7 +421,7 @@
|
|||
color: white;
|
||||
-moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
|
||||
}
|
||||
.openerp2 .oe_menu_more_container {
|
||||
position: relative;
|
||||
|
@ -477,7 +477,7 @@
|
|||
border-radius: 4px;
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp2 .oe_secondary_submenu .oe_active {
|
||||
background: #8a89ba;
|
||||
|
@ -486,7 +486,7 @@
|
|||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp2 .oe_secondary_submenu .oe_active a {
|
||||
color: white;
|
||||
|
@ -497,7 +497,7 @@
|
|||
text-shadow: 0 1px 1px white;
|
||||
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp2 .oe_secondary_submenu .oe_menu_toggler:before {
|
||||
width: 0;
|
||||
|
@ -626,7 +626,7 @@
|
|||
border: 1px solid #afafb6;
|
||||
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.openerp2 .oe_form_header {
|
||||
padding: 4px 16px;
|
||||
|
@ -750,7 +750,7 @@
|
|||
border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.openerp2 .oe_dropdown_menu li {
|
||||
list-style-type: none;
|
||||
|
@ -778,7 +778,7 @@
|
|||
background-image: linear-gradient(to bottom, #f0f0fa, #eeeef6);
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp2 .oe_kanban_group_title {
|
||||
margin: 1px 1px 4px;
|
||||
|
@ -814,7 +814,7 @@
|
|||
.openerp2 .oe_kanban_record:hover {
|
||||
-moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.6);
|
||||
-webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.6);
|
||||
-box-shadow: 0 0 3px rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.openerp2 .oe_kanban_record .oe_kanban_title {
|
||||
font-weight: bold;
|
||||
|
@ -828,7 +828,7 @@
|
|||
border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.openerp2 .oe_application a {
|
||||
color: #8a89ba;
|
||||
|
@ -836,6 +836,178 @@
|
|||
.openerp2 .oe_application a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.openerp2 .oe_searchview {
|
||||
position: relative;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-box {
|
||||
min-height: 0;
|
||||
border-width: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-icon {
|
||||
top: 5px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-icon-search {
|
||||
left: 5px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner {
|
||||
margin: 0 40px 0 17px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner input {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .VS-input-width-tester {
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_input {
|
||||
margin-left: 0;
|
||||
height: 22px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_input input, .openerp2 .oe_searchview .VS-search .VS-search-inner .search_input .VS-input-width-tester {
|
||||
padding: 0 2px;
|
||||
height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet {
|
||||
padding: 0;
|
||||
margin: 1px 0;
|
||||
border: 1px solid #afafb6;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background: #f0f0fa;
|
||||
height: 18px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet.is_selected {
|
||||
border-color: #a6a6fe;
|
||||
-moz-box-shadow: 0 0 3px 1px #a6a6fe;
|
||||
-webkit-box-shadow: 0 0 3px 1px #a6a6fe;
|
||||
box-shadow: 0 0 3px 1px #a6a6fe;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet.is_selected .category {
|
||||
margin-left: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet.is_selected .VS-icon-cancel {
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
background-position: center 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet .category {
|
||||
padding: 0 4px 0 14px;
|
||||
color: white;
|
||||
background: #8786b7;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
|
||||
font-weight: normal;
|
||||
text-transform: none;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
font-size: inherit;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet .search_facet_input_container {
|
||||
border-left: 1px solid #afafb6;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
padding: 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-search-inner .search_facet .search_facet_remove {
|
||||
left: 1px;
|
||||
top: 3px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .VS-icon-cancel {
|
||||
right: 24px;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .oe_vs_unfold_drawer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
line-height: 23px;
|
||||
padding: 0 7px 0 4px;
|
||||
color: #cccccc;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp2 .oe_searchview .VS-search .oe_vs_unfold_drawer:before {
|
||||
content: "▾";
|
||||
}
|
||||
.openerp2 .oe_searchview.oe_searchview_open_drawer .oe_searchview_drawer {
|
||||
display: block;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
width: 500px;
|
||||
display: none;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters > div {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: table-cell;
|
||||
width: 50%;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters h3 {
|
||||
margin: 2px 4px 2px 8px;
|
||||
color: #8786b7;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters ul {
|
||||
margin: 0 12px 3px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters li {
|
||||
list-style: none;
|
||||
padding: 3px 6px;
|
||||
height: 14px;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_filters li:hover {
|
||||
background-color: #f0f0fa;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced h4 {
|
||||
border-top: 1px solid #cccccc;
|
||||
margin: 5px 0 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced h4:before {
|
||||
content: "▸ ";
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced div {
|
||||
display: none;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced button.oe_add_condition:before {
|
||||
content: "⊞ ";
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced button.oe_apply:before {
|
||||
content: "⚡ ";
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced.oe_opened h4:before {
|
||||
content: "▾ ";
|
||||
}
|
||||
.openerp2 .oe_searchview .oe_searchview_drawer .oe_searchview_advanced.oe_opened div {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.openerp .oe_form_field_many2one td:first-child {
|
||||
position: relative;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
|
||||
// Variables {{{
|
||||
$section-title-color: #8786b7
|
||||
$facets-border: #afafb6
|
||||
$facets-border-selected: #a6a6fe
|
||||
$colour4: #8a89ba
|
||||
//$colour4: #d14836
|
||||
// }}}
|
||||
|
@ -29,7 +32,7 @@ $colour4: #8a89ba
|
|||
@mixin box-shadow($bsval: 0px 1px 4px #777)
|
||||
-moz-box-shadow: $bsval
|
||||
-webkit-box-shadow: $bsval
|
||||
-box-shadow: $bsval
|
||||
box-shadow: $bsval
|
||||
|
||||
@mixin transition($transval: (border linear 0.2s, box-shadow linear 0.2s))
|
||||
-webkit-transition: $transval
|
||||
|
@ -46,6 +49,12 @@ $colour4: #8a89ba
|
|||
-webkit-background-clip: $clip
|
||||
-moz-background-clip: $clip
|
||||
background-clip: $clip
|
||||
|
||||
@mixin unscrew-box
|
||||
-moz-box-sizing: border-box
|
||||
-webkit-box-sizing: border-box
|
||||
box-sizing: border-box
|
||||
|
||||
// }}}
|
||||
|
||||
.openerp2
|
||||
|
@ -697,6 +706,172 @@ $colour4: #8a89ba
|
|||
text-decoration: underline
|
||||
// }}}
|
||||
|
||||
// Search View {{{
|
||||
.oe_searchview
|
||||
position: relative
|
||||
|
||||
.VS-search
|
||||
.VS-search-box
|
||||
min-height: 0
|
||||
border-width: 1px
|
||||
padding: 0
|
||||
|
||||
.VS-icon
|
||||
top: 5px
|
||||
|
||||
.VS-icon-search
|
||||
left: 5px
|
||||
|
||||
.VS-search-inner
|
||||
margin: 0 40px 0 17px
|
||||
font-size: 13px
|
||||
|
||||
input
|
||||
font-size: inherit
|
||||
line-height: inherit
|
||||
height: auto
|
||||
padding: 0
|
||||
|
||||
.VS-input-width-tester
|
||||
font-size: inherit
|
||||
padding: 0
|
||||
|
||||
.search_input
|
||||
margin-left: 0
|
||||
height: 22px
|
||||
input, .VS-input-width-tester
|
||||
padding: 0 2px
|
||||
height: inherit
|
||||
margin: 0
|
||||
|
||||
.search_facet
|
||||
padding: 0
|
||||
margin: 1px 0
|
||||
border: 1px solid $facets-border
|
||||
@include radius(3px)
|
||||
background: #f0f0fa
|
||||
height: 18px
|
||||
|
||||
&.is_selected
|
||||
border-color: $facets-border-selected
|
||||
@include box-shadow(0 0 3px 1px $facets-border-selected)
|
||||
|
||||
.category
|
||||
margin-left: 0
|
||||
.VS-icon-cancel
|
||||
// don't change the icon on selection
|
||||
@include opacity(1.0)
|
||||
background-position: center 0
|
||||
|
||||
.category
|
||||
padding: 0 4px 0 14px
|
||||
color: white
|
||||
background: #8786b7
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4)
|
||||
font-weight: normal
|
||||
text-transform: none
|
||||
height: 18px
|
||||
line-height: 18px
|
||||
font-size: inherit
|
||||
|
||||
.search_facet_input_container
|
||||
border-left: 1px solid $facets-border
|
||||
height: 18px
|
||||
line-height: 18px
|
||||
padding: 0 4px
|
||||
cursor: pointer
|
||||
|
||||
.search_facet_remove
|
||||
left: 1px
|
||||
top: 3px
|
||||
|
||||
.VS-icon-cancel
|
||||
right: 24px
|
||||
|
||||
.oe_vs_unfold_drawer
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
height: 100%
|
||||
line-height: 23px
|
||||
padding: 0 7px 0 4px
|
||||
color: #ccc
|
||||
cursor: pointer
|
||||
&:before
|
||||
content: "▾"
|
||||
|
||||
&.oe_searchview_open_drawer
|
||||
.oe_searchview_drawer
|
||||
display: block
|
||||
|
||||
.oe_searchview_drawer
|
||||
position: absolute
|
||||
top: 100%
|
||||
right: 0
|
||||
background-color: white
|
||||
width: 500px
|
||||
display: none
|
||||
border: 1px solid #ccc
|
||||
|
||||
.oe_searchview_filters
|
||||
display: table
|
||||
width: 100%
|
||||
|
||||
> div
|
||||
@include unscrew-box
|
||||
display: table-cell
|
||||
width: 50%
|
||||
|
||||
h3
|
||||
margin: 2px 4px 2px 8px
|
||||
color: $section-title-color
|
||||
|
||||
ul
|
||||
margin: 0 12px 3px
|
||||
padding: 0
|
||||
list-style: none
|
||||
|
||||
li
|
||||
list-style: none
|
||||
padding: 3px 6px
|
||||
height: 14px
|
||||
color: inherit
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: #f0f0fa
|
||||
|
||||
.oe_searchview_advanced
|
||||
h4
|
||||
border-top: 1px solid #ccc
|
||||
margin: 5px 0 3px
|
||||
cursor: pointer
|
||||
|
||||
h4:before
|
||||
content: "▸ "
|
||||
|
||||
div
|
||||
display: none
|
||||
|
||||
button.oe_add_condition:before
|
||||
content: "⊞ "
|
||||
button.oe_apply:before
|
||||
content: "⚡ "
|
||||
|
||||
ul
|
||||
list-style: none
|
||||
padding: 0
|
||||
li
|
||||
list-style: none
|
||||
margin: 0
|
||||
|
||||
&.oe_opened
|
||||
h4:before
|
||||
content: "▾ "
|
||||
div
|
||||
display: block
|
||||
// }}}
|
||||
|
||||
// Transitional overrides for old styles {{{
|
||||
.openerp
|
||||
.oe_form_field_many2one
|
||||
|
|
|
@ -13,8 +13,6 @@ openerp.web.core = function(openerp) {
|
|||
|
||||
// a function to override the "extend()" method of JR's inheritance, allowing
|
||||
// the usage of "include()"
|
||||
// TODO: remove usage of include everywhere, not meant to be included in novajs because we don't
|
||||
// include rotten cadavers in novajs
|
||||
var oe_override_class = function(claz){
|
||||
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ?
|
||||
/\b_super\b/ : /.*/;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1298,17 +1298,8 @@
|
|||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="SearchView">
|
||||
<form class="oe_forms">
|
||||
<t t-call="SearchView.render_lines"/>
|
||||
<div class="oe_search-view-buttons">
|
||||
<button class="oe_button">Search</button>
|
||||
<button class="oe_button" type="reset">Clear</button>
|
||||
<select class="oe_search-view-filters-management">
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</t>
|
||||
<div t-name="SearchView" class="oe_searchview"/>
|
||||
|
||||
<t t-name="SearchView.managed-filters">
|
||||
<option class="oe-filters-title" value="">Filters</option>
|
||||
<optgroup label="-- Filters --">
|
||||
|
@ -1364,10 +1355,28 @@
|
|||
<br t-if="attrs.string"/>
|
||||
<t t-esc="attrs.string"/>
|
||||
</button>
|
||||
<span t-name="SearchView.filters" class="filter_label_group"
|
||||
><t t-foreach="filters" t-as="filter"
|
||||
><t t-raw="filter.render(defaults)"/></t
|
||||
></span>
|
||||
<ul t-name="SearchView.filters">
|
||||
<li t-foreach="widget.filters" t-as="filter">
|
||||
<t t-esc="filter.attrs.string or filter.attrs.name or 'Ω'"/>
|
||||
</li>
|
||||
</ul>
|
||||
<t t-name="SearchView.filters.facet">
|
||||
<div class="category oe_filter_category"><t t-esc="facet.get('category')"/></div>
|
||||
|
||||
<t t-set="val" t-value="facet.get('json')"/>
|
||||
|
||||
<div t-if="!(val instanceof Array)" class="search_facet_input_container">
|
||||
<t t-esc="facet.get('value')"/>
|
||||
</div>
|
||||
<t t-if="val instanceof Array">
|
||||
<div class="search_facet_input_container"
|
||||
t-foreach="facet.get('json')" t-as="filter">
|
||||
<t t-esc="filter.attrs.string || filter.attrs.name"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<div class="search_facet_remove VS-icon VS-icon-cancel"/>
|
||||
</t>
|
||||
<t t-name="SearchView.field">
|
||||
<label t-att-class="'oe_label' + (attrs.help ? '_help' : '')"
|
||||
t-att-title="attrs.help"
|
||||
|
@ -1425,8 +1434,7 @@
|
|||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.util.expand">
|
||||
<div t-att-class="'searchview_group ' + (expand == '0' ? 'folded' : 'expanded')"
|
||||
t-att-id="element_id">
|
||||
<div t-att-class="'searchview_group ' + (expand == '0' ? 'folded' : 'expanded')">
|
||||
<a t-if="label" class="searchview_group_string" href="#">
|
||||
<t t-esc="label"/>
|
||||
</a>
|
||||
|
@ -1444,34 +1452,18 @@
|
|||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search">
|
||||
<t t-call="SearchView.util.expand">
|
||||
<t t-set="expand" t-value="false"/>
|
||||
<t t-set="label">Advanced Filters</t>
|
||||
<t t-set="content">
|
||||
<div class="searchview_extended_groups_list">
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.group">
|
||||
<div t-att-id="widget.element_id" class="searchview_extended_group">
|
||||
<select class="searchview_extended_group_choice">
|
||||
<option value="any">Any of the following conditions must match</option>
|
||||
<option value="all">All the following conditions must match</option>
|
||||
<option value="none">None of the following conditions must match</option>
|
||||
</select>
|
||||
<a class="searchview_extended_delete_group"
|
||||
href="javascript:void(0)"><span></span></a>
|
||||
<div class="searchview_extended_propositions_list">
|
||||
</div>
|
||||
<a class="searchview_extended_add_proposition" href="javascript:void(0)">
|
||||
<span>Add condition</span></a>
|
||||
<div class="oe_adv_filters_and"><span>and</span></div>
|
||||
</div>
|
||||
</t>
|
||||
<div t-name="SearchView.advanced" class="oe_searchview_advanced">
|
||||
<h4>Advanced Search...</h4>
|
||||
<form>
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
<button class="oe_add_condition" type="button">Add a condition</button>
|
||||
<button class="oe_apply" type="submit">Apply</button>
|
||||
</form>
|
||||
</div>
|
||||
<t t-name="SearchView.extended_search.proposition">
|
||||
<div t-att-id="widget.element_id">
|
||||
<li>
|
||||
<select class="searchview_extended_prop_field">
|
||||
<t t-foreach="widget.attrs.fields" t-as="field">
|
||||
<option t-if="typeof field.store === 'undefined' || field.store || field.fnct_search"
|
||||
|
@ -1485,7 +1477,7 @@
|
|||
<span class="searchview_extended_prop_value"/>
|
||||
<a class="searchview_extended_delete_prop"
|
||||
href="javascript:void(0)"><span> </span></a>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.char">
|
||||
<input t-att-id="widget.element_id" class="field_char"/>
|
||||
|
|
|
@ -11,6 +11,8 @@ Contents:
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
search-view
|
||||
|
||||
getting-started
|
||||
production
|
||||
widgets
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
Search View
|
||||
===========
|
||||
|
||||
OpenERP Web 6.2 implements a unified facets-based search view instead
|
||||
of the previous form-like search view (composed of buttons and
|
||||
multiple fields). The goal for this change is twofold:
|
||||
|
||||
* Avoid the common issue of users confusing the search view with a
|
||||
form view and trying to create their records through it (or entering
|
||||
all their data, hitting the ``Create`` button expecting their record
|
||||
to be created and losing everything).
|
||||
|
||||
* Improve the looks and behaviors of the view, and the fit within
|
||||
OpenERP Web's new design.
|
||||
|
||||
The faceted search is implemented through a monkey-patched
|
||||
`VisualSearch <http://documentcloud.github.com/visualsearch/>`_
|
||||
[#]_. VisualSearch is based on `Backbone
|
||||
<http://documentcloud.github.com/backbone/>`_ and makes significant
|
||||
use of Backbone's models and views. As a result, understanding the
|
||||
implementation of the OpenERP Web 6.2 search view also requires a
|
||||
basic understanding of Backbone.
|
||||
|
||||
.. note::
|
||||
|
||||
This document may mention *fetching* data. This is a shortcut for
|
||||
"returning a deferred to [whatever is being fetched]". Unless
|
||||
further noted, the function or method may opt to return nothing by
|
||||
fetching ``null`` (which can easily be done by returning
|
||||
``$.when(null)``, which simply wraps the ``null`` in a Deferred).
|
||||
|
||||
Interaction between the Search View and VisualSearch
|
||||
----------------------------------------------------
|
||||
|
||||
The core data abstraction in VisualSearch is
|
||||
:js:class:`VS.model.SearchQuery`, a backbone Collection holding
|
||||
instances of the :js:class:`VS.model.SearchFacet` backbone Model.
|
||||
|
||||
Backbone models can hold any number of informal properties interacted
|
||||
with through the :js:func:`~Backbone.Model.get` and
|
||||
:js:func:`~Backbone.Model.set` methods. VisualSearch reserves three
|
||||
such properties for its behavior, these properties *must* be correctly
|
||||
set on all search facets created programmatically:
|
||||
|
||||
``app``
|
||||
a reference to the VisualSearch instance using this facet. In the
|
||||
search view, this instance is available as the
|
||||
:js:attr:`~openerp.web.SearchView.vs` attribute to the searchview
|
||||
instance.
|
||||
|
||||
``category``
|
||||
the *name* of the facet, displayed in the first section of a facet
|
||||
view.
|
||||
|
||||
``value``
|
||||
the *displayed value* of the facet, it is directly printed to the
|
||||
right of the category.
|
||||
|
||||
The search view uses additional keys to store state and data it needs
|
||||
to associate with facet objects:
|
||||
|
||||
``field``
|
||||
the search field instance which created the facet, used when the
|
||||
search view needs to serialize the facets.
|
||||
|
||||
``json``
|
||||
the "logical" value of the facet, can be absent if the logical and
|
||||
"printable" values of the facet are the same (e.g. for a basic text
|
||||
field).
|
||||
|
||||
This value may be a complex javascript object such as an array (the
|
||||
name stands for json-compatible value, it is not a JSON-encoded
|
||||
string).
|
||||
|
||||
.. note::
|
||||
|
||||
in order to simplify getting the logical value of a search facet
|
||||
model, :js:class:`VS.model.SearchFacet` has been extended with a
|
||||
:js:func:`~VS.model.SearchFacet.value` method
|
||||
|
||||
Extensions and patches to VisualSearch
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
.. js:function:: VS.model.SearchFacet.value()
|
||||
|
||||
Bundles the logic of selecting between ``json`` and ``value`` in
|
||||
order to get the logical value of a facet.
|
||||
|
||||
.. js:attribute:: VS.options.callbacks.make_facet
|
||||
|
||||
Called by :js:class:`VS.ui.SearchBox` when it needs to create a
|
||||
new search facet *view*. By default this is not supported by
|
||||
VisualSearch, and requires monkey-patching
|
||||
:js:func:`VS.ui.SearchBox.renderFacet`.
|
||||
|
||||
This patch should not alter any behavior if
|
||||
:js:attr:`~VS.options.callbacks.make_facet` is not used.
|
||||
|
||||
.. js:attribute:: VS.options.callbacks.make_input
|
||||
|
||||
Similar to :js:attr:`~VS.options.callbacks.make_facet`, but called
|
||||
when the :js:class:`~VS.ui.SearchBox` needs to create a search
|
||||
input view. It requires monkey-patching
|
||||
:js:func:`VS.ui.SearchBox.renderSearchInput`.
|
||||
|
||||
Finally, :js:func:`VS.ui.SearchBox.searchEvent` is monkey-patched to
|
||||
get rid of its serialize/load round-tripping of facet data: the
|
||||
additional attributes needed by the search view don't round-trip (at
|
||||
all) so VisualSearch must not load any data from its (fairly
|
||||
simplistic) text-serialization format.
|
||||
|
||||
.. note::
|
||||
|
||||
a second issue is that — as of `commit 3fca87101d`_ — VisualSearch
|
||||
correctly serializes facet categories containing spaces but is
|
||||
unable to load them back in. It also does not handle facets with
|
||||
*empty* categories correctly.
|
||||
|
||||
Loading Defaults
|
||||
----------------
|
||||
|
||||
After loading the view data, the SearchView will call
|
||||
:js:func:`openerp.web.search.Input.facet_for_defaults` on each of its
|
||||
inputs with the ``defaults`` mapping of key:values (where each key
|
||||
corresponds to an input). This method should look into the
|
||||
``defaults`` mapping and fetch the field's default value as a
|
||||
:js:class:`~VS.models.SearchFacet` if applicable.
|
||||
|
||||
The default implementation is to check if there is a default value for
|
||||
the current input's name (via
|
||||
:js:attr:`openerp.web.search.Input.attrs.name`) and if there is to
|
||||
convert this value to a :js:class:`~VS.models.SearchFacet` by calling
|
||||
:js:func:`openerp.web.search.Input.facet_for`.
|
||||
|
||||
There is no built-in (default) implementation of
|
||||
:js:func:`openerp.web.search.Input.facet_for`. This method should
|
||||
fetch the :js:class:`~VS.models.SearchFacet` corresponding to the
|
||||
"raw" value passed as argument.
|
||||
|
||||
Providing auto-completion
|
||||
-------------------------
|
||||
|
||||
An important component of the unified search view is the faceted
|
||||
autocompletion pane. In order to provide good user and developer
|
||||
experiences, this pane is pluggable (value-wise): each and every
|
||||
control of the search view can check for (and provide) categorized
|
||||
auto-completions for a given value being typed by the user.
|
||||
|
||||
This is done by implementing
|
||||
:js:func:`openerp.web.search.Input.complete`: the method is provided
|
||||
with a value to complete, and should fetch an ``Array`` of completion
|
||||
values. These completion values will then be provided to the global
|
||||
autocompletion list, implemented via `jquery-ui autocomplete
|
||||
<http://jqueryui.com/demos/autocomplete/>`_.
|
||||
|
||||
Because the search view uses a custom renderer for its completion, it
|
||||
was possible to fix some incompatibilities between the attributes of
|
||||
completion items and VisualSearch's facet model:
|
||||
|
||||
Actual completion items
|
||||
+++++++++++++++++++++++
|
||||
|
||||
These are selectable items, and upon selection are turned into actual
|
||||
search facet objects. They should have all the properties of a search
|
||||
facet (as described above) and can have one more optional property:
|
||||
``label``.
|
||||
|
||||
When rendering an item in the list, the renderer will first try to use
|
||||
the ``label`` property if it exists (``label`` can contain HTML and
|
||||
will be inserted as-is, so it can bold or emphasize some of its
|
||||
elements), if it does not the ``value`` property will be used.
|
||||
|
||||
.. note:: the ``app`` key should not be specified on completion item,
|
||||
it will be set automatically when the search view creates
|
||||
the facet from the item.
|
||||
|
||||
Section titles
|
||||
++++++++++++++
|
||||
|
||||
A second kind of completion values is the section titles. Section
|
||||
titles are similar to completion items but only have a ``category``
|
||||
property. They will be rendered in a different style and can not be
|
||||
selected in the auto-completion (they will be skipped).
|
||||
|
||||
.. note::
|
||||
|
||||
Technically, section title items can have any property they want
|
||||
*as long as they do not have a value property*. A ``value``
|
||||
property set to ``false``, ``null`` or ``undefined`` is **not**
|
||||
equivalent to not having a ``value`` property.
|
||||
|
||||
If an input *may* fetch more than one completion item, it *should*
|
||||
prepend a section title (using its own name) to the completion items.
|
||||
|
||||
Converting from facet objects
|
||||
-----------------------------
|
||||
|
||||
Ultimately, the point of the search view is to allow searching. In
|
||||
OpenERP this is done via :ref:`domains <openerpserver:domains>`. On
|
||||
the other hand, the OpenERP Web 6.2 search view's state is modelled
|
||||
after a collection of :js:class:`~VS.model.SearchFacet`, and each
|
||||
field of a search view may have special requirements when it comes to
|
||||
the domains it produces [#]_.
|
||||
|
||||
So there needs to be some way of mapping
|
||||
:js:class:`~VS.model.SearchFacet` objects to OpenERP search data.
|
||||
|
||||
This is done via an input's
|
||||
:js:func:`~openerp.web.search.Input.get_domain` and
|
||||
:js:func:`~openerp.web.search.Input.get_context`. Each takes a
|
||||
:js:class:`~VS.model.SearchFacet` and returns whatever it's supposed
|
||||
to generate (a domain or a context, respectively). Either can return
|
||||
``null`` if the current value does not map to a domain or context, and
|
||||
can throw an :js:class:`~openerp.web.search.Invalid` exception if the
|
||||
value is not valid at all for the field.
|
||||
|
||||
Converting to facet objects
|
||||
---------------------------
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
.. todo:: merge in changelog instead
|
||||
|
||||
The displaying of the search view was significantly altered from
|
||||
OpenERP Web 6.1 to OpenERP Web 6.2.
|
||||
|
||||
As a result, while the external API used to interact with the search
|
||||
view does not change many internal details — including the interaction
|
||||
between the search view and its widgets — were significantly altered:
|
||||
|
||||
Internal operations
|
||||
+++++++++++++++++++
|
||||
|
||||
* :js:func:`openerp.web.SearchView.do_clear` has been removed
|
||||
* :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed
|
||||
|
||||
Widgets API
|
||||
+++++++++++
|
||||
|
||||
* :js:func:`openerp.web.search.Widget.render` has been removed
|
||||
|
||||
* :js:func:`openerp.web.search.Widget.make_id` has been removed
|
||||
|
||||
* Search field objects are not openerp widgets anymore, their
|
||||
``start`` is not generally called
|
||||
|
||||
* :js:func:`~openerp.web.search.Input.clear` has been removed since
|
||||
clearing the search view now simply consists of removing all search
|
||||
facets from VisualSearch
|
||||
|
||||
* :js:func:`~openerp.web.search.Input.get_domain` and
|
||||
:js:func:`~openerp.web.search.Input.get_context` now take a
|
||||
:js:class:`~VS.model.SearchFacet` as parameter, from which it's
|
||||
their job to get whatever value they want
|
||||
|
||||
* :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns
|
||||
an :js:class:`Array` of context-like constructs. By default, it does not do
|
||||
anything in :js:class:`~openerp.web.search.Field` and it returns the various
|
||||
contexts of its enabled filters in
|
||||
:js:class:`~openerp.web.search.FilterGroup`.
|
||||
|
||||
Filters
|
||||
+++++++
|
||||
|
||||
* :js:func:`openerp.web.search.Filter.is_enabled` has been removed
|
||||
|
||||
* :js:class:`~openerp.web.search.FilterGroup` instances are still
|
||||
rendered (and started) in the "advanced search" drawer.
|
||||
|
||||
Fields
|
||||
++++++
|
||||
|
||||
* ``get_value`` now takes a :js:class:`~VS.model.SearchFacet` (instead
|
||||
of taking no argument).
|
||||
|
||||
A default implementation is provided as
|
||||
:js:func:`openerp.web.search.Field.get_value` and simply calls
|
||||
:js:func:`VS.model.SearchFacet.value`.
|
||||
|
||||
* The third argument to
|
||||
:js:func:`~openerp.web.search.Field.make_domain` is now the
|
||||
:js:class:`~VS.model.SearchFacet` received by
|
||||
:js:func:`~openerp.web.search.Field.get_domain`, so child classes
|
||||
have all the information they need to derive the "right" resulting
|
||||
domain.
|
||||
|
||||
Custom filters
|
||||
++++++++++++++
|
||||
|
||||
Instead of being an intrinsic part of the search view, custom filters
|
||||
are now a special case of filter groups. They are treated specially
|
||||
still, but much less so than they used to be.
|
||||
|
||||
Many To One
|
||||
+++++++++++
|
||||
|
||||
* Because the autocompletion service is now provided by the search
|
||||
view itself,
|
||||
:js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has
|
||||
been removed.
|
||||
|
||||
.. [#] the library code is untouched, all patching is performed in the
|
||||
Search view's implementation module. Changes to the
|
||||
VisualSearch code should only update the library to new
|
||||
revisions or releases.
|
||||
.. [#] search view fields may also bundle context data to add to the
|
||||
search context
|
||||
|
||||
.. _commit 3fca87101d:
|
||||
https://github.com/documentcloud/visualsearch/commit/3fca87101d
|
Loading…
Reference in New Issue