Skip to content

Commit

Permalink
Adding readOnly option. Closing #119.
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelclay committed Feb 10, 2014
1 parent 2476577 commit 0b5c8ea
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 39 deletions.
2 changes: 2 additions & 0 deletions demo.html
Expand Up @@ -188,6 +188,7 @@ <h2 id="demo">Demo <span class="demo-hint"><i>Try searching for: <b>account</b>,
container : $('#search_box_container'),
query : 'country: "United States" account: 5-samuel "U.S. State": California',
showFacets : true,
readOnly : false,
unquotable : [
'text',
'account',
Expand Down Expand Up @@ -328,6 +329,7 @@ <h2 id="demo">Demo <span class="demo-hint"><i>Try searching for: <b>account</b>,
query : '',
minLength : 0,
showFacets : true,
readOnly : false,
unquotable : [
'text',
'account',
Expand Down
2 changes: 1 addition & 1 deletion index.html
Expand Up @@ -186,7 +186,7 @@ <h2 id="demo">Demo <span class="demo-hint"><i>Try searching for: <b>account</b>,

<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var visualSearch = VS.init({
window.visualSearch = VS.init({
container : $('#search_box_container'),
query : 'country: "United States" "U.S. State": "New York" account: 5-samuel',
showFacets : true,
Expand Down
15 changes: 15 additions & 0 deletions lib/css/workspace.css
Expand Up @@ -42,6 +42,9 @@
min-height: 28px;
height: auto;
}
.VS-search.VS-readonly .VS-search-box {
cursor: default;
}
.VS-search .VS-search-box.VS-focus {
border-color: #acf;
-webkit-box-shadow: inset 0px 0px 3px #acf;
Expand Down Expand Up @@ -86,6 +89,9 @@
position: absolute;
right: 9px; top: 8px;
}
.VS-search.VS-readonly .VS-icon-cancel {
display: none;
}

/* ================ */
/* = Search Facet = */
Expand All @@ -100,6 +106,9 @@
height: 20px;
margin: 3px -3px 3px 0;
}
.VS-search.VS-readonly .search_facet {
padding-left: 0;
}
.VS-search .search_facet.is_selected {
margin-left: -3px;
-webkit-border-radius: 16px;
Expand All @@ -122,6 +131,9 @@
cursor: pointer;
padding: 4px 0 0;
}
.VS-search.VS-readonly .search_facet .category {
cursor: default;
}
.VS-search .search_facet.is_selected .category {
margin-left: 3px;
}
Expand All @@ -148,6 +160,9 @@
.VS-search .search_facet.is_selected input {
color: #000;
}
.VS-search.VS-readonly .search_facet .search_facet_remove {
display: none;
}
.VS-search .search_facet .search_facet_remove {
position: absolute;
left: 0;
Expand Down
2 changes: 1 addition & 1 deletion lib/js/templates/search_box.jst
@@ -1,4 +1,4 @@
<div class="VS-search">
<div class="VS-search <% if (readOnly) { %>VS-readonly<% } %>">
<div class="VS-search-box-wrapper VS-search-box">
<div class="VS-icon VS-icon-search"></div>
<div class="VS-placeholder"></div>
Expand Down
2 changes: 1 addition & 1 deletion lib/js/templates/search_facet.jst
Expand Up @@ -3,7 +3,7 @@
<% } %>

<div class="search_facet_input_container">
<input type="text" class="search_facet_input ui-menu VS-interface" value="" />
<input type="text" class="search_facet_input ui-menu VS-interface" value="" <% if (readOnly) { %>disabled="disabled"<% } %> />
</div>

<div class="search_facet_remove VS-icon VS-icon-cancel"></div>
2 changes: 1 addition & 1 deletion lib/js/templates/search_input.jst
@@ -1 +1 @@
<input type="text" class="ui-menu" />
<input type="text" class="ui-menu" <% if (readOnly) { %>disabled="disabled"<% } %> />
6 changes: 3 additions & 3 deletions lib/js/templates/templates.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions lib/js/views/search_box.js
Expand Up @@ -17,7 +17,7 @@ VS.ui.SearchBox = Backbone.View.extend({
// Creating a new SearchBox registers handlers for re-rendering facets when necessary,
// as well as handling typing when a facet is selected.
initialize : function(options) {
if (options) this.options = options;
this.options = _.extend({}, this.options, options);

this.app = this.options.app;
this.flags = {
Expand All @@ -37,7 +37,9 @@ VS.ui.SearchBox = Backbone.View.extend({

// Renders the search box, but requires placement on the page through `this.el`.
render : function() {
$(this.el).append(JST['search_box']({}));
$(this.el).append(JST['search_box']({
readOnly: this.app.options.readOnly
}));
$(document.body).setMode('no', 'search');

return this;
Expand Down Expand Up @@ -212,6 +214,7 @@ VS.ui.SearchBox = Backbone.View.extend({
// allows third-party developers to either clear data asynchronously, or
// prior to performing their custom "clear" logic.
clearSearch : function(e) {
if (this.app.options.readOnly) return;
var actualClearSearch = _.bind(function() {
this.disableFacets();
this.value('');
Expand Down Expand Up @@ -367,6 +370,7 @@ VS.ui.SearchBox = Backbone.View.extend({
},

maybeFocusSearch : function(e) {
if (this.app.options.readOnly) return;
if ($(e.target).is('.VS-search-box') ||
$(e.target).is('.VS-search-inner') ||
e.type == 'keydown') {
Expand All @@ -376,6 +380,7 @@ VS.ui.SearchBox = Backbone.View.extend({

// Bring focus to last input field.
focusSearch : function(e, selectText) {
if (this.app.options.readOnly) return;
var view = this.inputViews[this.inputViews.length-1];
view.enableEdit(selectText);
if (!selectText) view.setCursorAtEnd(-1);
Expand All @@ -393,6 +398,7 @@ VS.ui.SearchBox = Backbone.View.extend({
// Double-clicking on the search wrapper should select the existing text in
// the last search input. Also start the triple-click timer.
highlightSearch : function(e) {
if (this.app.options.readOnly) return;
if ($(e.target).is('.VS-search-box') ||
$(e.target).is('.VS-search-inner') ||
e.type == 'keydown') {
Expand All @@ -409,6 +415,7 @@ VS.ui.SearchBox = Backbone.View.extend({

// Used to show the user is focused on some input inside the search box.
addFocus : function() {
if (this.app.options.readOnly) return;
this.app.options.callbacks.focus();
this.$('.VS-search-box').addClass('VS-focus');
},
Expand Down
56 changes: 30 additions & 26 deletions lib/js/views/search_facet.js
Expand Up @@ -20,19 +20,21 @@ VS.ui.SearchFacet = Backbone.View.extend({
},

initialize : function(options) {
if (options) this.options = options;
this.options = _.extend({}, this.options, options);

this.flags = {
canClose : false
};
_.bindAll(this, 'set', 'keydown', 'deselectFacet', 'deferDisableEdit');
this.app = this.options.app;
},

// Rendering the facet sets up autocompletion, events on blur, and populates
// the facet's input with its starting value.
render : function() {
$(this.el).html(JST['search_facet']({
model : this.model
model : this.model,
readOnly: this.app.options.readOnly
}));

this.setMode('not', 'editing');
Expand Down Expand Up @@ -81,11 +83,11 @@ VS.ui.SearchFacet = Backbone.View.extend({
var originalValue = this.model.get('value');
this.set(ui.item.value);
if (originalValue != ui.item.value || this.box.val() != ui.item.value) {
if (this.options.app.options.autosearch) {
if (this.app.options.autosearch) {
this.search(e);
} else {
this.options.app.searchBox.renderFacets();
this.options.app.searchBox.focusNextFacet(this, 1, {viewPosition: this.options.order});
this.app.searchBox.renderFacets();
this.app.searchBox.focusNextFacet(this, 1, {viewPosition: this.options.order});
}
}
return false;
Expand Down Expand Up @@ -156,7 +158,7 @@ VS.ui.SearchFacet = Backbone.View.extend({
var value = this.model.get('value');
var searchTerm = req.term;

this.options.app.options.callbacks.valueMatches(category, searchTerm, function(matches, options) {
this.app.options.callbacks.valueMatches(category, searchTerm, function(matches, options) {
options = options || {};
matches = matches || [];

Expand Down Expand Up @@ -197,9 +199,9 @@ VS.ui.SearchFacet = Backbone.View.extend({
search : function(e, direction) {
if (!direction) direction = 1;
this.closeAutocomplete();
this.options.app.searchBox.searchEvent(e);
this.app.searchBox.searchEvent(e);
_.defer(_.bind(function() {
this.options.app.searchBox.focusNextFacet(this, direction, {viewPosition: this.options.order});
this.app.searchBox.focusNextFacet(this, direction, {viewPosition: this.options.order});
}, this));
},

Expand All @@ -209,6 +211,7 @@ VS.ui.SearchFacet = Backbone.View.extend({
// This method tells all other facets and inputs to disable so it can have
// the sole focus. It also prepares the autocompletion menu.
enableEdit : function() {
if (this.app.options.readOnly) return;
if (this.modes.editing != 'is') {
this.setMode('is', 'editing');
this.deselectFacet();
Expand All @@ -218,10 +221,10 @@ VS.ui.SearchFacet = Backbone.View.extend({
}

this.flags.canClose = false;
this.options.app.searchBox.disableFacets(this);
this.options.app.searchBox.addFocus();
this.app.searchBox.disableFacets(this);
this.app.searchBox.addFocus();
_.defer(_.bind(function() {
this.options.app.searchBox.addFocus();
this.app.searchBox.addFocus();
}, this));
this.resize();
this.searchAutocomplete();
Expand Down Expand Up @@ -258,7 +261,7 @@ VS.ui.SearchFacet = Backbone.View.extend({
this.box.blur();
this.setMode('not', 'editing');
this.closeAutocomplete();
this.options.app.searchBox.removeFocus();
this.app.searchBox.removeFocus();
},

// Selects the facet, which blurs the facet's input and highlights the facet.
Expand All @@ -267,7 +270,8 @@ VS.ui.SearchFacet = Backbone.View.extend({
// should delete this facet or just deselect it.
selectFacet : function(e) {
if (e) e.preventDefault();
var allSelected = this.options.app.searchBox.allSelected();
if (this.app.options.readOnly) return;
var allSelected = this.app.searchBox.allSelected();
if (this.modes.selected == 'is') return;

if (this.box.is(':focus')) {
Expand All @@ -286,8 +290,8 @@ VS.ui.SearchFacet = Backbone.View.extend({
$(document).unbind('keydown.facet').bind('keydown.facet', this.keydown);
$(document).unbind('click.facet').one('click.facet', this.deselectFacet);
}, this));
this.options.app.searchBox.disableFacets(this);
this.options.app.searchBox.addFocus();
this.app.searchBox.disableFacets(this);
this.app.searchBox.addFocus();
}
return false;
},
Expand All @@ -301,7 +305,7 @@ VS.ui.SearchFacet = Backbone.View.extend({
if (this.modes.selected == 'is') {
this.setMode('not', 'selected');
this.closeAutocomplete();
this.options.app.searchBox.removeFocus();
this.app.searchBox.removeFocus();
}
$(document).unbind('keydown.facet', this.keydown);
$(document).unbind('click.facet', this.deselectFacet);
Expand Down Expand Up @@ -340,12 +344,12 @@ VS.ui.SearchFacet = Backbone.View.extend({
var committed = this.model.get('value');
this.deselectFacet();
this.disableEdit();
this.options.app.searchQuery.remove(this.model);
if (committed && this.options.app.options.autosearch) {
this.app.searchQuery.remove(this.model);
if (committed && this.app.options.autosearch) {
this.search(e, -1);
} else {
this.options.app.searchBox.renderFacets();
this.options.app.searchBox.focusNextFacet(this, -1, {viewPosition: this.options.order});
this.app.searchBox.renderFacets();
this.app.searchBox.focusNextFacet(this, -1, {viewPosition: this.options.order});
}
},

Expand All @@ -367,7 +371,7 @@ VS.ui.SearchFacet = Backbone.View.extend({
} else if (key == 'left') {
if (this.modes.selected == 'is') {
this.deselectFacet();
this.options.app.searchBox.focusNextFacet(this, -1, {startAtEnd: -1});
this.app.searchBox.focusNextFacet(this, -1, {startAtEnd: -1});
} else if (this.box.getCursorPosition() == 0 && !this.box.getSelection().length) {
this.selectFacet();
}
Expand All @@ -380,27 +384,27 @@ VS.ui.SearchFacet = Backbone.View.extend({
} else if (this.box.getCursorPosition() == this.box.val().length) {
e.preventDefault();
this.disableEdit();
this.options.app.searchBox.focusNextFacet(this, 1);
this.app.searchBox.focusNextFacet(this, 1);
}
} else if (VS.app.hotkeys.shift && key == 'tab') {
e.preventDefault();
this.options.app.searchBox.focusNextFacet(this, -1, {
this.app.searchBox.focusNextFacet(this, -1, {
startAtEnd : -1,
skipToFacet : true,
selectText : true
});
} else if (key == 'tab') {
e.preventDefault();
this.options.app.searchBox.focusNextFacet(this, 1, {
this.app.searchBox.focusNextFacet(this, 1, {
skipToFacet : true,
selectText : true
});
} else if (VS.app.hotkeys.command && (e.which == 97 || e.which == 65)) {
e.preventDefault();
this.options.app.searchBox.selectAllFacets();
this.app.searchBox.selectAllFacets();
return false;
} else if (VS.app.hotkeys.printable(e) && this.modes.selected == 'is') {
this.options.app.searchBox.focusNextFacet(this, -1, {startAtEnd: -1});
this.app.searchBox.focusNextFacet(this, -1, {startAtEnd: -1});
this.remove(e);
} else if (key == 'backspace') {
$(document).on('keydown.backspace', function(e) {
Expand Down
9 changes: 6 additions & 3 deletions lib/js/views/search_input.js
Expand Up @@ -19,8 +19,8 @@ VS.ui.SearchInput = Backbone.View.extend({
},

initialize : function(options) {
if (options) this.options = options;

this.options = _.extend({}, this.options, options);
this.app = this.options.app;
this.flags = {
canClose : false
Expand All @@ -31,7 +31,9 @@ VS.ui.SearchInput = Backbone.View.extend({
// Rendering the input sets up autocomplete, events on focusing and blurring
// the input, and the auto-grow of the input.
render : function() {
$(this.el).html(JST['search_input']({}));
$(this.el).html(JST['search_input']({
readOnly: this.app.options.readOnly
}));

this.setMode('not', 'editing');
this.setMode('not', 'selected');
Expand Down Expand Up @@ -259,6 +261,7 @@ VS.ui.SearchInput = Backbone.View.extend({
// `tripleClickTimer` is counting down, ready to be engaged and intercept
// the click event to force a select all instead.
maybeTripleClick : function(e) {
if (this.app.options.readOnly) return;
if (!!this.tripleClickTimer) {
e.preventDefault();
this.app.searchBox.selectAllFacets();
Expand Down
3 changes: 2 additions & 1 deletion lib/js/visualsearch.js
Expand Up @@ -34,14 +34,15 @@
unquotable : [],
remainder : 'text',
showFacets : true,
readOnly : false,
callbacks : {
search : $.noop,
focus : $.noop,
blur : $.noop,
facetMatches : $.noop,
valueMatches : $.noop,
clearSearch : $.noop,
removedFacet : $.noop,
removedFacet : $.noop
}
};
this.options = _.extend({}, defaults, options);
Expand Down

0 comments on commit 0b5c8ea

Please sign in to comment.