function ListFacet(div, config, options, selection) { this._div = div; this._config = config; this._options = options || {}; if (!("sort" in this._options)) { this._options.sort = "name"; } this._selection = selection || []; this._blankChoice = null; this._errorChoice = null; this._data = null; this.render(); } ListFacet.reconstruct = function(div, uiState) { return new ListFacet(div, uiState.c, uiState.o, uiState.s); }; ListFacet.prototype.reset = function() { this._selection = []; this._blankChoice = null; this._errorChoice = null; }; ListFacet.prototype.getUIState = function() { var json = { c: this.getJSON(), o: this._options }; json.s = json.c.selection; delete json.c.selection; return json; }; ListFacet.prototype.getJSON = function() { var o = { type: "list", name: this._config.name, columnName: this._config.columnName, expression: this._config.expression, omitBlank: "omitBlank" in this._config ? this._config.omitBlank : false, omitError: "omitError" in this._config ? this._config.omitError : false, selection: [], selectBlank: this._blankChoice !== null && this._blankChoice.s, selectError: this._errorChoice !== null && this._errorChoice.s }; for (var i = 0; i < this._selection.length; i++) { var choice = { v: cloneDeep(this._selection[i].v) }; o.selection.push(choice); } return o; }; ListFacet.prototype.hasSelection = function() { return this._selection.length > 0 || (this._blankChoice !== null && this._blankChoice.s) || (this._errorChoice !== null && this._errorChoice.s); }; ListFacet.prototype.updateState = function(data) { this._data = data; if ("choices" in data) { var selection = []; var choices = data.choices; for (var i = 0; i < choices.length; i++) { var choice = choices[i]; if (choice.s) { selection.push(choice); } } this._selection = selection; this._reSortChoices(); this._blankChoice = data.blankChoice || null; this._errorChoice = data.errorChoice || null; } this.render(); }; ListFacet.prototype._reSortChoices = function() { this._data.choices.sort(this._options.sort == "name" ? function(a, b) { return a.v.l.localeCompare(b.v.l); } : function(a, b) { return b.c - a.c; } ); }; ListFacet.prototype.render = function() { var self = this; var scrollTop = 0; try { scrollTop = this._div[0].childNodes[1].scrollTop; } catch (e) { } var container = this._div.empty().html( '
' + '' + '' + '
' ); var elmts = DOM.bind(container); elmts.titleSpan.text(this._config.name); elmts.removeButton.click(function() { self._remove(); }); var bodyDiv = $('
').addClass("facet-body"); if (!("scroll" in this._options) || this._options.scroll) { bodyDiv.addClass("facet-body-scrollable"); } if (!this._data) { $('
').text("Loading...").addClass("facet-body-message").appendTo(bodyDiv); bodyDiv.appendTo(container); } else if ("error" in this._data) { $('
').text(this._data.error).addClass("facet-body-message").appendTo(bodyDiv); bodyDiv.appendTo(container); } else { var choices = this._data.choices; var selectionCount = this._selection.length + (this._blankChoice !== null && this._blankChoice.s ? 1 : 0) + (this._errorChoice !== null && this._errorChoice.s ? 1 : 0); /* * Status */ var statusDiv = $( '
' + '' + '' + '' + '
' + choices.length + ' choicesCluster
' + '
' ).appendTo(container); var statusElmts = DOM.bind(statusDiv); if (this._config.expression == "value") { statusElmts.clusterLink.click(function() { self._doEdit(); }); } else { statusElmts.clusterLink.hide(); } /* * Controls */ var controlsDiv = $( '
' + '' + '' + '' + '
Sort by ' + 'Name ' + 'Count' + '' + 'Reset' + '
' + '
' ).appendTo(container); var controlsElmts = DOM.bind(controlsDiv); if (selectionCount > 0) { controlsElmts.resetButton.click(function() { self._reset(); }); } else { controlsElmts.resetButton.hide(); } if (this._options.sort == "name") { controlsElmts.sortByNameLink.addClass("facet-mode-link-selected"); controlsElmts.sortByCountLink.click(function() { self._options.sort = "count"; self._reSortChoices(); self.render(); }); } else { controlsElmts.sortByCountLink.addClass("facet-mode-link-selected"); controlsElmts.sortByNameLink.click(function() { self._options.sort = "name"; self._reSortChoices(); self.render(); }); } /* * Body */ var renderEdit = this._config.expression == "value"; var renderChoice = function(choice, customLabel) { var label = customLabel || choice.v.l; var count = choice.c; var choiceDiv = $('
').addClass("facet-choice").appendTo(bodyDiv); if (choice.s) { choiceDiv.addClass("facet-choice-selected"); } var a = $('').addClass("facet-choice-label").text(label).appendTo(choiceDiv); $('').addClass("facet-choice-count").text(count).appendTo(choiceDiv); var select = function() { self._select(choice, false); }; var selectOnly = function() { self._select(choice, true); }; var deselect = function() { self._deselect(choice); }; if (renderEdit && customLabel === undefined) { // edit link var editLink = $('') .addClass("facet-choice-link") .text("edit") .css("visibility", "hidden") .click(function() { self._editChoice(choice, choiceDiv); }) .prependTo(choiceDiv); choiceDiv .mouseenter(function() { editLink.css("visibility", "visible"); }) .mouseleave(function() { editLink.css("visibility", "hidden"); }); } if (choice.s) { // selected if (selectionCount > 1) { // select only a.click(selectOnly); } else { // deselect a.click(deselect); } // exclude link $('') .addClass("facet-choice-link") .text("exclude") .click(deselect) .prependTo(choiceDiv); } else if (selectionCount > 0) { a.click(selectOnly); // include link var includeLink = $('') .addClass("facet-choice-link") .text("include") .css("visibility", "hidden") .click(select) .prependTo(choiceDiv); choiceDiv .mouseenter(function() { includeLink.css("visibility", "visible"); }) .mouseleave(function() { includeLink.css("visibility", "hidden"); }); } else { a.click(select); } }; for (var i = 0; i < choices.length; i++) { renderChoice(choices[i]); } if (this._blankChoice !== null) { renderChoice(this._blankChoice, "(blank)"); } if (this._errorChoice !== null) { renderChoice(this._errorChoice, "(error)"); } bodyDiv.appendTo(container); bodyDiv[0].scrollTop = scrollTop; } }; ListFacet.prototype._doEdit = function() { new ClusteringDialog(this._config.columnName, this._config.expression); }; ListFacet.prototype._editChoice = function(choice, choiceDiv) { var self = this; var menu = MenuSystem.createMenu().addClass("data-table-cell-editor").width("400px"); menu.html( '' + '' + '
' + '