diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.gitignore b/.gitignore index a7ee446..c0144b7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ archilance/settings/local.py media/* static/* +node_modules/* *.log.* *.log !media/_sample_files/ diff --git a/assets/css/main.css b/assets/css/main.css index 62037d6..0afa2c3 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1376,34 +1376,34 @@ footer:after { margin: 33px 0 28px 0; } -label { - width: 23px; - height: 23px; - display: block; - position: relative; - float: left; - margin-right: 10px; -} +/*label {*/ + /*width: 23px;*/ + /*height: 23px;*/ + /*display: block;*/ + /*position: relative;*/ + /*float: left;*/ + /*margin-right: 10px;*/ +/*}*/ -input[type="checkbox"] + span { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: url('../img/check.png') no-repeat center; - background-position: 0 0; - background-size: cover; - cursor: pointer; -} +/*input[type="checkbox"] + span {*/ + /*position: absolute;*/ + /*left: 0;*/ + /*top: 0;*/ + /*width: 100%;*/ + /*height: 100%;*/ + /*background: url('../img/check.png') no-repeat center;*/ + /*background-position: 0 0;*/ + /*background-size: cover;*/ + /*cursor: pointer;*/ +/*}*/ .sro input[type="checkbox"] { opacity: 0; } -input[type="checkbox"]:checked + span { - background-position: 0 -23px; -} +/*input[type="checkbox"]:checked + span {*/ + /*background-position: 0 -23px;*/ +/*}*/ .sro p { font-size: 15px; @@ -4514,26 +4514,26 @@ input[type="checkbox"]:checked + span { color: #009DD9; } -label { - width: 23px; - height: 23px; - display: block; - position: relative; -} +/*label {*/ + /*width: 23px;*/ + /*height: 23px;*/ + /*display: block;*/ + /*position: relative;*/ +/*}*/ -input[type="checkbox"] + span { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: url('../img/check.png') no-repeat; - cursor: pointer; -} +/*input[type="checkbox"] + span {*/ + /*position: absolute;*/ + /*left: 0;*/ + /*top: 0;*/ + /*width: 100%;*/ + /*height: 100%;*/ + /*background: url('../img/check.png') no-repeat;*/ + /*cursor: pointer;*/ +/*}*/ -input[type="checkbox"]:checked + span { - background-position: 0 -23px; -} +/*input[type="checkbox"]:checked + span {*/ + /*background-position: 0 -23px;*/ +/*}*/ .text-block { width: 100%; diff --git a/assets/lib/proekton-components/bash/watchify.sh b/assets/lib/proekton-components/bash/watchify.sh new file mode 100644 index 0000000..299b0cc --- /dev/null +++ b/assets/lib/proekton-components/bash/watchify.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +echo "run watchify" +cd .. +source ~/venv/proekton/bin/activate +watchify ./src/init.js -t babelify -o ./build/init.js \ No newline at end of file diff --git a/assets/lib/proekton-components/build/init.js b/assets/lib/proekton-components/build/init.js new file mode 100644 index 0000000..e082848 --- /dev/null +++ b/assets/lib/proekton-components/build/init.js @@ -0,0 +1,1110 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o\n
\n ' + header + '\n
\n
\n ' + name + '\n
\n \n \n'; +}; + +var SelectedContainer = function () { + function SelectedContainer($container, data) { + var noTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + _classCallCheck(this, SelectedContainer); + + // TODO: rename variables to camelCase + this.$self = $container; + this.elements_id = []; // [spec_id, spec_id, ...] + this.dataTree = noTree ? new _NoTreeData2.default(data) : new _DataTree2.default(data); + this.$input = this.$self.find('input[type="hidden"]'); + this.restoreElements(); + } + + _createClass(SelectedContainer, [{ + key: 'restoreElements', + value: function restoreElements() { + var self = this; + if (this.$input && this.$input.val()) { + var data = this.$input.val().split(',').filter(function (el) { + return el; + }); + console.log("restore data = ", data); + this.elements_id = []; + data.forEach(function (el) { + return self.add(el); + }); + } + } + }, { + key: '_removeById', + value: function _removeById(spec_id) { + var index = this.elements_id.indexOf(spec_id); + if (index >= 0) { + this.elements_id.splice(index, 1); + } + this.$self.find('span[data-id=\'' + spec_id + '\']').parents('.selected-element').remove(); + } + }, { + key: 'remove', + value: function remove(e) { + var spec_id = $(e.target).data("id"); + this._removeById(spec_id); + if (this.$input) this.$input.val(this.elements_id.join(',')); + e.preventDefault(); + } + }, { + key: 'add', + value: function add(_id, max_len) { + var id = Number(_id); + var self = this; + + var has_already = this.elements_id.filter(function (el) { + return self.dataTree.isChild(el, id); + }); + + // console.log(has_already); + if (has_already.length || this.elements_id.indexOf(Number(id)) != -1) { + //TODO: do popup messages + console.log("Not actually"); + return; + } + + var not_valid = this.elements_id.filter(function (el) { + return self.dataTree.isChild(id, el); + }); + + not_valid.forEach(function (el) { + self._removeById(el); + }); + + var header = SelectedContainer.getHeader(this.dataTree.getSpecChain(id), "", max_len); + // console.log("header = ", header); + var name = this.dataTree.getElementById(id).name; + this.elements_id.push(id); + if (this.$input) this.$input.val(this.elements_id.join(',')); + this.$self.append(SelectedContainer.getTemplate(header || " ", name, id)); + this.btn_remove = this.$self.find('.icon-remove'); + this.btn_remove.on("click", this.remove.bind(self)); + } + }], [{ + key: 'getTemplate', + value: function getTemplate(header, name, id) { + return tmpl_selectedElement(header, name, id); + } + }, { + key: 'getHeader', + value: function getHeader(spec_chain, separator, max_len) { + function toShortString(string, max_len) { + return string.slice(0, max_len) + (string.length > max_len ? "..." : ""); + } + + separator = separator || ' / '; + var str_chain = ""; + + spec_chain.forEach(function (el) { + str_chain = (max_len ? toShortString(el.name, max_len) : el.name) + (str_chain ? separator : "") + str_chain; + }); + + return str_chain; + } + }]); + + return SelectedContainer; +}(); + +exports.default = SelectedContainer; + +},{"./data/DataTree":5,"./data/NoTreeData":6}],3:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _AbsBaseSelect2 = require('./base/AbsBaseSelect'); + +var _AbsBaseSelect3 = _interopRequireDefault(_AbsBaseSelect2); + +var _DataTree = require('./data/DataTree'); + +var _DataTree2 = _interopRequireDefault(_DataTree); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var TreeSelect = function (_AbsBaseSelect) { + _inherits(TreeSelect, _AbsBaseSelect); + + function TreeSelect(_ref) { + var $container = _ref.$container, + data = _ref.data, + _ref$hasEditableConta = _ref.hasEditableContainer, + hasEditableContainer = _ref$hasEditableConta === undefined ? false : _ref$hasEditableConta; + + _classCallCheck(this, TreeSelect); + + return _possibleConstructorReturn(this, (TreeSelect.__proto__ || Object.getPrototypeOf(TreeSelect)).call(this, { $container: $container, data: new _DataTree2.default(data), hasEditableContainer: hasEditableContainer })); + } + + _createClass(TreeSelect, [{ + key: 'setNearbySelectBox', + value: function setNearbySelectBox(next, prev) { + this.nextSelectBox = next; + this.prevSelectBox = prev; + } + }, { + key: 'clearAllNext', + value: function clearAllNext() { + // console.log("clearAllNext"); + this.clear(); + if (this.nextSelectBox) { + this.nextSelectBox.hide(); + this.nextSelectBox.clearAllNext(); + } + } + }, { + key: 'clearAllPrev', + value: function clearAllPrev() { + this.clear(); + if (this.prevSelectBox) { + this.clear(); + this.hide(); + // this.prevSelectBox.clear(); + this.prevSelectBox.clearAllPrev(); + } + } + }, { + key: '_onclickOptionsElement', + value: function _onclickOptionsElement(e) { + this.clearAllNext(); + _get(TreeSelect.prototype.__proto__ || Object.getPrototypeOf(TreeSelect.prototype), '_onclickOptionsElement', this).call(this, e); + + if (this.nextSelectBox && this.dataTree.hasChildren(this.selectedEl.id)) { + this.nextSelectBox.setParent(this.selectedEl.id); + this.nextSelectBox.setHeader(this.selectedEl.value); + this.nextSelectBox.show(); + } + if (this.prevSelectBox) this.prevSelectBox.$buttonAddOptions.hide(); + } + }, { + key: '_onButtonAddOptions', + value: function _onButtonAddOptions(e) { + // this._addToSelectedContainer(this.selectedEl.id); + // this.clear(); + // e.preventDefault(); + // return false; + _get(TreeSelect.prototype.__proto__ || Object.getPrototypeOf(TreeSelect.prototype), '_onButtonAddOptions', this).call(this, e); + this.clearAllNext(); + this.clearAllPrev(); + } + }, { + key: '_onButtonAdd', + value: function _onButtonAdd(e) { + _get(TreeSelect.prototype.__proto__ || Object.getPrototypeOf(TreeSelect.prototype), '_onButtonAdd', this).call(this, e); + this.clearAllNext(); + this.clearAllPrev(); + } + }, { + key: '_addToSelectedContainer', + value: function _addToSelectedContainer(id) { + if (this.selectedContainer) { + this.selectedContainer.add(id); + return; + } + + this.prevSelectBox._addToSelectedContainer(id); + } + }]); + + return TreeSelect; +}(_AbsBaseSelect3.default); + +exports.default = TreeSelect; + +},{"./base/AbsBaseSelect":4,"./data/DataTree":5}],4:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +//TEMPLATES +var tmpl_selectBoxEditCont = function tmpl_selectBoxEditCont() { + return "\n
\n
\n \n \n
\n
\n \n
\n
\n"; +}; +var tmpl_selectBox = function tmpl_selectBox() { + return "\n \n \n \n"; +}; +var tmpl_elementResult = function tmpl_elementResult(el, id, header) { + return "
  • "; +}; +var tmpl_elementOption = function tmpl_elementOption(el) { + return "
  • " + el.name + "
  • "; +}; +//${vertical_child} +var htmlTemplate = function htmlTemplate(_ref) { + var header = _ref.header, + selectBox = _ref.selectBox, + id = _ref.id; + return "\n
    \n
    \n
    " + header + "
    \n \n
    \n
    \n " + selectBox + "\n
    \n
    \n
    \n
      \n \n
    \n
    \n
    \n
    \n
    \n
    \n
      \n
    \n
    \n
    \n \u0418\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0439\n
      \n
    \n
    \n
    \n \n
    \n \n
    \n"; +}; +var tmpl_light = function tmpl_light(el) { + return "" + el + ""; +}; + +var AbsBaseSelect = function () { + // constructor($container, data, hasEditableContainer, verticalChild) { + function AbsBaseSelect(_ref2) { + var $container = _ref2.$container, + data = _ref2.data, + _ref2$hasEditableCont = _ref2.hasEditableContainer, + hasEditableContainer = _ref2$hasEditableCont === undefined ? false : _ref2$hasEditableCont; + + _classCallCheck(this, AbsBaseSelect); + + if (new.target === AbsBaseSelect) { + throw new TypeError("Cannot construct Abstract instances directly"); + } + //TODO: добавить применение классов контейнера + //TODO: проверка наличия id контейнера + this.containerId = $container.attr("id"); + this.dataTree = data; + console.log("data = ", data); + // Вариант не выбран + this.hasEditableContainer = hasEditableContainer; + var template = this.getTemplate(); + $container.replaceWith(template); + this._buildComponents(); + this._bindEvents(); + // if (!has_editable_container) this.hide(); + // INIT EMPTY PROP + this.selectedEl = { id: undefined, value: undefined }; + this.parentId = undefined; + this.hide(); + } + + // getTemplate(header, id, editable_container, vertical_child) { + + + _createClass(AbsBaseSelect, [{ + key: "getTemplate", + value: function getTemplate() { + var selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox(); + return htmlTemplate({ header: "TestHeader", selectBox: selectBox, id: this.containerId }); + } + }, { + key: "clear", + value: function clear() { + console.log("clear"); + this.$searchInput.val(""); + this.$optionsBox.hide(); + this.$resultsBox.hide(); + this.$buttonAdd.hide(); + this.$buttonAddOptions.hide(); + this.selectedEl = { id: undefined, value: undefined }; + if (this.hasEditableContainer) { + this.$editableContainer.html(""); + this.$editableContainer.hide(); + } + } + }, { + key: "hide", + value: function hide() { + this.$selectBox.hide(); + } + }, { + key: "show", + value: function show() { + this.$selectBox.show(); + } + }, { + key: "setHeader", + value: function setHeader(header) { + this.$header.html(header); + // default hide + this.show(); + } + }, { + key: "setParent", + value: function setParent(parentId) { + this.parentId = parentId; + this._fillOptionsData(); + } + }, { + key: "connectSelectedContainer", + value: function connectSelectedContainer(selectedContainer) { + this.selectedContainer = selectedContainer; + } + }, { + key: "getIdsSelectedElements", + value: function getIdsSelectedElements() { + var allChecked = this.$resultsBox.find(":checked"); + return allChecked.map(function () { + return $(this).data("id"); + }); + } + }, { + key: "updateEditableContainer", + value: function updateEditableContainer(elId) { + // Если нет контейнера для отображения ... + if (this.$editableContainer.length) { + var separator = ' / '; + var chainHeader = AbsBaseSelect.getHeader(this.dataTree.getSpecChain(elId, true), { separator: separator }); + console.log('chainHeader = ', chainHeader); + chainHeader = AbsBaseSelect.highlight(chainHeader, separator, true); + var elTemplate = "" + chainHeader + ""; + this.$editableContainer.html(elTemplate); + this.$editableContainer.show(); + return; + } + //..., передаем отображение предыдущему selectBox + if (this.prevSelectBox) this.prevSelectBox.updateEditableContainer(elId); + } + }, { + key: "_buildComponents", + value: function _buildComponents() { + this.$selectBox = $("#" + this.containerId); + this.$header = this.$selectBox.find('.select-box-header .header'); + this.$resultsBox = this.$selectBox.find('.select-box-results'); + this.$optionsBox = this.$selectBox.find('.select-box-options'); + this.$searchInput = this.$selectBox.find('input.select-box-search'); + this.$buttonAdd = this.$selectBox.find('.button-add.results'); + this.$buttonAddOptions = this.$selectBox.find('.button-add.options'); + this.$editableContainer = this.$selectBox.find('.editable-container'); + if (this.hasEditableContainer) this.$editableContainer.hide(); + this._fillOptionsData(); + this.$resultsBox.hide(); + this.$optionsBox.hide(); + this.$buttonAddOptions.hide(); + // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select + } + }, { + key: "_fillOptionsData", + value: function _fillOptionsData() { + var self = this; + var dataList = this.dataTree.dataToList(this.parentId); + var $container = this.$optionsBox.find('ul'); + $container.html(""); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = dataList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var el = _step.value; + + $container.append($(tmpl_elementOption(el))); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + this.$selectBox.find('li').on("click", this._onclickOptionsElement.bind(self)); + } + }, { + key: "_fillResultsData", + value: function _fillResultsData(searchText) { + var self = this; + + function search(_ref3) { + var searchText = _ref3.searchText, + _ref3$parentCategoryI = _ref3.parentCategoryId, + parentCategoryId = _ref3$parentCategoryI === undefined ? null : _ref3$parentCategoryI, + _ref3$excludeCategory = _ref3.excludeCategoryId, + excludeCategoryId = _ref3$excludeCategory === undefined ? null : _ref3$excludeCategory; + + // :FORMAT spec_list [{name, id}, ...] + var specList = self.dataTree.dataToList(parentCategoryId, true, excludeCategoryId); + // console.log("search -->", spec_list.length); + // console.log("parent_id ", parentCategoryId); + return specList.filter(function (el) { + return el.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1; + }); + } + + function fillContainer($container, template, _ref4) { + var _ref4$searchText = _ref4.searchText, + searchText = _ref4$searchText === undefined ? "" : _ref4$searchText, + _ref4$parentCategoryI = _ref4.parentCategoryId, + parentCategoryId = _ref4$parentCategoryI === undefined ? null : _ref4$parentCategoryI, + _ref4$excludeCategory = _ref4.excludeCategoryId, + excludeCategoryId = _ref4$excludeCategory === undefined ? null : _ref4$excludeCategory; + + $container.html(""); + $('.other-part').show(); + var searchRes = search({ searchText: searchText, parentCategoryId: parentCategoryId, excludeCategoryId: excludeCategoryId }); + // || (!excludeCategoryId && parentCategoryId === null) + console.log("searchRes = ", searchRes); + if (!searchRes.length) { + if ($container.closest('div').hasClass('main-part')) { + $container.append('
  • Ничего не найдено
  • '); + self.$resultsBox.find('.button-add.results').hide(); + // console.log('not found main-part'); + } else { + $('.other-part').hide(); + // console.log('not found other-part'); + } + return; + } + self.$resultsBox.find('.button-add.results').show(); + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = searchRes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var el = _step2.value; + + var header = AbsBaseSelect.getHeader(self.dataTree.getSpecChain(el.id), {}); + $container.append(template(AbsBaseSelect.highlight(el.name, searchText), el.id, header)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + } + + // FILL RESULTS + // MAIN PART + var $container = this.$resultsBox.find('.main-part ul'); + fillContainer($container, tmpl_elementResult, { searchText: searchText, parentCategoryId: self.parentId }); + + // OTHER PART + // Если нет parentId, не нужно искать в других категориях + // console.log("parentID = ", this.parentId); + if (!this.parentId) { + $('.other-part').hide(); + } else { + $container = this.$resultsBox.find('.other-part ul'); + // console.log("Fill other-part"); + fillContainer($container, tmpl_elementResult, { searchText: searchText, excludeCategoryId: self.parentId }); + } + this.$resultsBox.find('div.header').hide(); + this.$resultsBox.find('li').on("mouseover", function (e) { + $(e.target).children('.header').show(300); + e.preventDefault(); + }); + + this.$resultsBox.find('li').on("mouseout", function (event) { + var e = event.toElement || event.relatedTarget; + console.log(e.parentNode, ' ==', this); + console.log(e, ' ==', this); + if (e.parentNode == this || e == this) { + return; + } + console.log("OUT"); + $(this).find('.header').hide(); + }); + } + }, { + key: "_onclickOptionsElement", + value: function _onclickOptionsElement(e) { + this.selectedEl.id = $(e.target).data("id"); + this.selectedEl.value = $(e.target).html(); + this.$searchInput.val($(e.target).html()); + this.updateEditableContainer($(e.target).data("id")); + this.$buttonAddOptions.show(); + this.$optionsBox.hide(); + } + }, { + key: "_onButtonAddOptions", + value: function _onButtonAddOptions(e) { + this._addToSelectedContainer(this.selectedEl.id); + this.clear(); + e.preventDefault(); + return false; + } + }, { + key: "_onButtonAdd", + value: function _onButtonAdd(e) { + var self = this; + + this.getIdsSelectedElements().each(function () { + console.log("add el -->", this); + self._addToSelectedContainer(this); + }); + this.clear(); + e.preventDefault(); + return false; + } + }, { + key: "_addToSelectedContainer", + value: function _addToSelectedContainer(id) { + this.selectedContainer.add(id); + } + }, { + key: "_bindEvents", + value: function _bindEvents() { + var self = this; + $(document).click(function (event) { + if ($(event.target).closest("#" + self.containerId).length) { + return; + } + self._looseFocus(); + }); + // RESULTS BOX + this.$searchInput.on("input", function (e) { + self._fillResultsData(self.$searchInput.val()); + self.$resultsBox.show(); + self.$optionsBox.hide(); + }); + // OPTIONS BOX + this.$searchInput.on("click", function (e) { + self.$optionsBox.show(); + self.$resultsBox.hide(); + self.$buttonAddOptions.hide(); + self.$searchInput.val(""); + }); + + this.$buttonAdd.on("click", function (e) { + self._onButtonAdd(e); + }); + + this.$buttonAddOptions.on("click", this._onButtonAddOptions.bind(self)); + } + }, { + key: "_looseFocus", + value: function _looseFocus() { + this.$resultsBox.hide(); + this.$optionsBox.hide(); + if (!this.selectedEl.id) { + this.$searchInput.val(""); + } else { + this.$searchInput.val(this.selectedEl.value); + } + console.log("loose ", this.selectedEl.id); + } + }], [{ + key: "getHeader", + value: function getHeader(catChain, _ref5) { + var _ref5$separator = _ref5.separator, + separator = _ref5$separator === undefined ? " / " : _ref5$separator, + _ref5$maxLen = _ref5.maxLen, + maxLen = _ref5$maxLen === undefined ? 60 : _ref5$maxLen; + + function toShortString(string, maxLen) { + return string.slice(0, maxLen) + (string.length > maxLen ? "..." : ""); + } + + var strChain = ""; + + catChain.forEach(function (el) { + strChain = (maxLen ? toShortString(el.name, maxLen) : el.name) + (strChain ? separator : "") + strChain; + }); + + return strChain; + } + }, { + key: "highlight", + value: function highlight(string, sub_string) { + var lastIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var index = lastIndex ? string.toLowerCase().lastIndexOf(sub_string.toLowerCase()) : string.toLowerCase().indexOf(sub_string.toLowerCase()); + console.log("index = ", index); + if (index === -1) return string; + var before = void 0, + select = void 0, + after = void 0; + if (lastIndex) { + var _ref6 = [string.slice(0, index), string.slice(index, string.length), ""]; + before = _ref6[0]; + select = _ref6[1]; + after = _ref6[2]; + } else { + var _ref7 = [string.slice(0, index), string.slice(index, index + sub_string.length), string.slice(index + sub_string.length)]; + before = _ref7[0]; + select = _ref7[1]; + after = _ref7[2]; + } + + return "" + before + tmpl_light(select) + after; + } + }]); + + return AbsBaseSelect; +}(); + +exports.default = AbsBaseSelect; + +},{}],5:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Node = function Node(data, tree) { + _classCallCheck(this, Node); + + this.name = data.name; + this.id = data.id; + if (data.parent === null) { + this.parent = "root"; + data.parent = { id: "root" }; + this.name = ""; + } + if (data.parent.id && data.parent.id !== 'root') { + var el = tree._getElementById(data.parent.id); + this.parent = el.node || new Node(el, tree); + } + data.node = this; + this.children = data.children.map(function (el_obj) { + var el = tree._getElementById(el_obj.id); + if (!el) console.log("el not found with id", el_obj.id); + // console.log("el = ", el, "el.id = ", el_obj.id); + if (el.node) return el.node; + el.node = new Node(el, tree); + return el.node; + }); + + this.children = this.children || []; +}; + +var DataTree = function () { + function DataTree(data) { + _classCallCheck(this, DataTree); + + this.baseData = data; + this._root = new Node(data[0], this); + } + + /** + * получить element в базовой структуре + */ + + + _createClass(DataTree, [{ + key: "_getElementById", + value: function _getElementById(id) { + for (var i = 0; i < this.baseData.length; i++) { + // console.log(this.baseData[i].id, " / ", id); + if (this.baseData[i].id == id) return this.baseData[i]; + } + } + + /** + * получить element в дереве + */ + + }, { + key: "getElementById", + value: function getElementById(id) { + function searchInChildren(children) { + for (var i = 0; i < children.length; i++) { + if (children[i].id == id) return children[i]; + var res = searchInChildren(children[i].children); + if (res) return res; + } + } + + return searchInChildren(this._root.children); + } + + /** + * Является ли узел c el_id дочерним для parent_id + * @param el_id + * @param parent_id + */ + + }, { + key: "isChild", + value: function isChild(elId, parent_id) { + function checkParent(el, parent) { + if (el.parent == parent) return true; + if (el.parent && el.parent != 'root') return checkParent(el.parent, parent); + return false; + } + return checkParent(this.getElementById(elId), this.getElementById(parent_id)); + } + }, { + key: "hasChildren", + value: function hasChildren(elId) { + console.log('id = ', elId); + return this.getElementById(elId).children.length ? true : false; + } + + /** + * @param start_parent_id(number) - начиная с + * @param attached(bool) - включая вложенные/дочерние + * @param exclude_id - исключая узел c exclude_id и всеми его вложенными узлами + * @returns [{name, id}, ...] + */ + + }, { + key: "dataToList", + value: function dataToList(start_parent_id, attached, exclude_id) { + var data_list = []; + + function goInChildren(children) { + for (var i = 0; i < children.length; i++) { + if (children[i].id == exclude_id) continue; + data_list.push({ name: children[i].name, id: children[i].id }); + if (attached) goInChildren(children[i].children); + } + } + var start = start_parent_id ? this.getElementById(start_parent_id) : this._root; + goInChildren(start.children); + return data_list; + } + + /** + * + * @param id + * @param incl(bool) - исключая сам элемент + * @returns {Array} всех узлов/элементов от элемента с id до корня + */ + + }, { + key: "getSpecChain", + value: function getSpecChain(id) { + var incl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var chain = []; + var el = this.getElementById(id); + function getParent(el) { + if (el.parent && el.parent != "root") { + chain.push(el.parent); + getParent(el.parent); + } + } + getParent(el); + if (incl) chain.unshift(el); + return chain; + } + }]); + + return DataTree; +}(); + +exports.default = DataTree; + +},{}],6:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var NoTreeData = function () { + function NoTreeData(data) { + _classCallCheck(this, NoTreeData); + + this.data = data; + this.specChain = []; + } + + _createClass(NoTreeData, [{ + key: "getElementById", + value: function getElementById(id) { + for (var i = 0; i < this.data.length; i++) { + if (this.data[i].id == id) return this.data[i]; + } + } + }, { + key: "getSpecChain", + value: function getSpecChain(id, incl) { + return this.specChain; + } + }, { + key: "isChild", + value: function isChild(el_id, parent_id) { + return false; + } + }, { + key: "hasChildren", + value: function hasChildren() { + return false; + } + }, { + key: "dataToList", + value: function dataToList() { + return this.data; + } + }]); + + return NoTreeData; +}(); + +exports.default = NoTreeData; + +},{}],7:[function(require,module,exports){ +'use strict'; + +var _SelectedContainer = require('./SelectedContainer'); + +var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); + +var _NoTreeSelect = require('./NoTreeSelect'); + +var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); + +var _TreeSelect = require('./TreeSelect'); + +var _TreeSelect2 = _interopRequireDefault(_TreeSelect); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// ` + +$(function () { + function createFilterSpecs(_data) { + // SPECIALIZATIONS FILTER + var data = _data.results; + var sb_main = new _TreeSelect2.default({ $container: $('#select-box-1'), data: data, hasEditableContainer: true }); + sb_main.setHeader("Специализации"); + var select_container = new _SelectedContainer2.default($('#selected-spec'), data); + sb_main.connectSelectedContainer(select_container); + var sb_1 = new _TreeSelect2.default({ $container: $('#select-box-2'), data: data }); + var sb_2 = new _TreeSelect2.default({ $container: $('#select-box-3'), data: data }); + var sb_3 = new _TreeSelect2.default({ $container: $('#select-box-4'), data: data }); + var sb_4 = new _TreeSelect2.default({ $container: $('#select-box-5'), data: data }); + + sb_main.setNearbySelectBox(sb_1); + sb_1.setNearbySelectBox(sb_2, sb_main); + sb_2.setNearbySelectBox(sb_3, sb_1); + sb_3.setNearbySelectBox(sb_4, sb_2); + sb_4.setNearbySelectBox("", sb_3); + } + + function createFilterBuildingClass(_data) { + // BUILDING-CLASSIFICATION FILTER + var data = _data.results; + var sb_build_main = new _TreeSelect2.default({ $container: $('#sb-building-classification'), data: data }); + sb_build_main.setHeader("Классификация здания"); + + var sb_build_1 = new _TreeSelect2.default({ $container: $('#sb-building-sub-classification'), data: data }); + + var select_build_container = new _SelectedContainer2.default($('#selected-building-classification'), data); + sb_build_main.connectSelectedContainer(select_build_container); + + sb_build_main.setNearbySelectBox(sb_build_1); + sb_build_1.setNearbySelectBox("", sb_build_main); + } + + function createFilterConstructionType(_data) { + var data = _data.results; + var sb_constr_main = new _NoTreeSelect2.default({ $container: $('#sb-construction-type'), data: data }); + sb_constr_main.setHeader("Вид строительства"); + var select_constr_type = new _SelectedContainer2.default($('#selected-construction-type'), data, true); + sb_constr_main.connectSelectedContainer(select_constr_type); + } + + function createFilerLocations(data) { + var sb_loc_main = new _TreeSelect2.default({ $container: $('#sb-location-1'), data: data }); + sb_loc_main.setHeader("Местоположение"); + var select_loc = new _SelectedContainer2.default($('#selected-location'), data, true); + sb_loc_main.connectSelectedContainer(select_loc); + var sb_loc_1 = new _TreeSelect2.default({ $container: $('#sb-location-2'), data: data }); + var sb_loc_2 = new _TreeSelect2.default({ $container: $('#sb-location-3'), data: data }); + + sb_loc_main.setNearbySelectBox(sb_loc_1); + sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main); + sb_loc_2.setNearbySelectBox("", sb_loc_1); + //TODO: Временно прелоадер на самом тяжелом объекте + // hidePreloader() + } + + $.ajax({ + url: '/api/specializations_flat', + dataType: 'json', + data: {}, + success: createFilterSpecs + }); + + $.ajax({ + url: '/api/building_classifications', + dataType: 'json', + data: {}, + success: createFilterBuildingClass + }); + + $.ajax({ + url: '/api/construction_type', + dataType: 'json', + data: {}, + success: createFilterConstructionType + }); + + var data = []; + + function fullData(_data) { + data = data.concat(_data.results.length ? _data.results : []); + var url = _data.next; + if (url) { + $.ajax({ + url: url, + dataType: 'json', + data: {}, + success: fullData + }); + } else { + createFilerLocations(data); + } + return data; + } + + fullData({ next: '/api/locations_flat', results: [] }); + + function tuneCheckBoxes($boxes) { + $boxes.each(function () { + if ($(this).find("input").prop("checked")) $(this).toggleClass('checked'); + }); + $boxes.on("click", function (e) { + $(e.target).toggleClass('checked'); + $(e.target).attr('data-state', $(e.target).attr('data-state') == 'enabled' ? 'disabled' : 'enabled'); + var inside_checkBox = $(e.target).find("input"); + inside_checkBox.prop("checked", !inside_checkBox.prop("checked")); + }); + } + + tuneCheckBoxes($('.custom-check')); + + // $(window).on('load', + // function hidePreloader() { + // var $preloader = $('#page-preloader'), + // $spinner = $preloader.find('.spinner'); + // $spinner.fadeOut(); + // $preloader.delay(350).fadeOut('slow'); + // } + + + // $("#myBtn").click(function () { + // $('
    ' + + // '' + + // 'modal info...' + + // '
    ').appendTo("#alerts"); + // }); + +}); + +},{"./NoTreeSelect":1,"./SelectedContainer":2,"./TreeSelect":3}]},{},[7]); diff --git a/assets/lib/proekton-components/css/editable-container.css b/assets/lib/proekton-components/css/editable-container.css new file mode 100644 index 0000000..8104369 --- /dev/null +++ b/assets/lib/proekton-components/css/editable-container.css @@ -0,0 +1,16 @@ +.editable-container { + display: block; + float: left; + background-color: #e5e5e5; + color: #585858; + font-size: 9pt; + padding: 5px 10px; + height: 51px; + margin-left: 8px; + position: relative; + left: -30px; +} + +.vertical-child { + margin-top: 30px; +} \ No newline at end of file diff --git a/assets/lib/proekton-components/css/fix-bags.css b/assets/lib/proekton-components/css/fix-bags.css new file mode 100644 index 0000000..cb2449e --- /dev/null +++ b/assets/lib/proekton-components/css/fix-bags.css @@ -0,0 +1,16 @@ +body { + font-size: 11pt; + font-family: Arial-MT-Regular, Arial, sans-serif; +} + +/*input[type="checkbox"] + span, input[type="checkbox"]:checked + span {*/ + /*all: initial;*/ + /*font-size: 9pt;*/ + /*color: #494546;*/ + /*cursor: pointer;*/ + /*font-family: Arial-MT-Regular, Arial, sans-serif;*/ +/*}*/ + +/*label {*/ + /*all: initial;*/ +/*}*/ diff --git a/assets/lib/proekton-components/css/fonts.css b/assets/lib/proekton-components/css/fonts.css new file mode 100644 index 0000000..5dfbfcd --- /dev/null +++ b/assets/lib/proekton-components/css/fonts.css @@ -0,0 +1,22 @@ +@font-face { +font-family: "Myriad"; + src: url("../fonts/MyriadPro/MyriadPro-Cond.otf"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: "Myriad"; + src: url("../fonts/MyriadPro/MyriadPro-BoldCond.otf"); + + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: "Myriad"; + src: url("../fonts/MyriadPro/MyriadPro-CondIt.otf"); + + font-weight: normal; + font-style: italic; +} diff --git a/assets/lib/proekton-components/css/other.css b/assets/lib/proekton-components/css/other.css index 21206b3..0a73de3 100644 --- a/assets/lib/proekton-components/css/other.css +++ b/assets/lib/proekton-components/css/other.css @@ -1,69 +1,3 @@ -label { - all: initial; -} - -.selected-container { - /*display: inline-block;*/ - /*width: 100%;*/ - min-height: 40px; - padding-bottom: 20px; -} - -.selected-container .selected-element { - /*display: inline-block;*/ - padding: 5px 35px 5px 10px; - margin-top: 8px; - min-height: 45px; - background-color: #e3e3e3; - border: 1px solid #dbdbdb; - position: relative; - -moz-border-radius: 10px; /* Firefox */ - -webkit-border-radius: 10px; /* Safari 4 */ - border-radius: 10px; /* IE 9, Safari 5, Chrome */ -} -.horizontal .selected-element{ - display: inline-block; -} - -.selected-element .header,.name{ - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - width: 100%; -} - -.selected-element .header{ - font-size: 7pt; - color: #676363; - /*white-space: nowrap;*/ - /*text-overflow: ellipsis;*/ - /*overflow: hidden;*/ - /*word-wrap: break-word;*/ - /*width: 100%;*/ -} - -.selected-element .name { - font-size: 11pt; - /*white-space: nowrap;*/ - /*text-overflow: ellipsis;*/ - /*overflow: hidden;*/ - /*width: 100%;*/ -} - - -.selected-element .icon-remove{ - background-image: url('../img/cross01.png'); - background-size: 20px 20px; - /*display: inline-block;*/ - position: absolute; - right: 5px; - top: 15px; - width: 20px; - height: 20px; - cursor: pointer; - margin-left: -20px; -} - /*DEMO*/ .wrapper{ background-color: #f2f2f2; @@ -80,18 +14,6 @@ label { margin-bottom: 5px; } -.max-width { - display: table !important; - width: 100% -} - -.vertical{ - width: 100%; -} - -.cell { - display: table-cell; -} .custom-check { background: url("../img/rect01.png") no-repeat center; background-size: 210px 51px; diff --git a/assets/lib/proekton-components/css/select-box.css b/assets/lib/proekton-components/css/select-box.css index 54eeb1a..5b8def4 100644 --- a/assets/lib/proekton-components/css/select-box.css +++ b/assets/lib/proekton-components/css/select-box.css @@ -1,16 +1,4 @@ -body { - font-size: 11pt; - font-family: Arial-MT-Regular, Arial, Sans-Serif; -} - -input[type="checkbox"] + span, input[type="checkbox"]:checked + span { - all: initial; - font-size: 9pt; - color: #494546; - cursor: pointer; -} - -.noselect { +.no-select { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Chrome/Safari/Opera */ -moz-user-select: none; /* Firefox */ @@ -33,7 +21,7 @@ input[type="checkbox"] + span, input[type="checkbox"]:checked + span { } .select-box-header { - font-size: 14pt; + font-size: 12pt; white-space: nowrap; word-wrap: break-word; /*position: relative;*/ @@ -50,13 +38,10 @@ input[type="checkbox"] + span, input[type="checkbox"]:checked + span { } -/*.select-box-header i {*/ -/*position: relative;*/ -/*top: -5px;*/ -/*}*/ - .select-box-header .fa { - color: #565656; + color: #5e5e5e; + position: relative; + top: -5px; } .select-box-header .fa:hover { @@ -68,29 +53,30 @@ input[type="checkbox"] + span, input[type="checkbox"]:checked + span { } .select-box-results, .select-box-options { - display: block; - /*clear: both;*/ + /*display: block;*/ + /*box-shadow: 0px 0px 10px #777, 0px 15px 10px #000;*/ position: absolute; - /*margin-top: -5px;*/ z-index: 99999; - opacity: 0.9; + opacity: 0.95; } .box-wrapper { display: block; max-height: 200px; - overflow-y: scroll; - border: 1px solid #868686; + overflow-y: auto; + /*border: 1px solid #cccccc;*/ background-color: #F2F2F2; + box-shadow: 0 12px 10px -6px rgba(0, 0, 0, .2); } .select-box-results input[type=checkbox] { margin: 0 5px 0 5px; } -.select-box-results i { - font-weight: normal; - font-style: normal; +.select-box-results .header{ + font-size: 8pt; + color: #757575; + pointer-events: none; } .select-box-results, .select-box-options li, ul { @@ -100,7 +86,9 @@ input[type="checkbox"] + span, input[type="checkbox"]:checked + span { .select-box-results li, .select-box-options li { padding: 2px 10px; - border-bottom: 1px solid #afb2b6; + border: 1px solid #cccccc; + /*border-right: 1px solid #cccccc;*/ + list-style: none; font-size: 9pt; color: #494546; @@ -110,18 +98,22 @@ input[type="checkbox"] + span, input[type="checkbox"]:checked + span { .select-box-results li, .select-box-options li { cursor: pointer; display: inline-block; + font-weight: normal; width: 100%; } .select-box-results li:hover, .select-box-options li:hover { background-color: #dcdcdc; border-left: 2px solid red; - color: #0b0b0b; + color: #0e0e0e; } -.select-box-search { - display: block; -} +/*.select-box-results span:hover{*/ + /*color: green;*/ +/*}*/ +/*.select-box-search{*/ + /*position: relative;*/ +/*}*/ input.select-box-search { height: 51px; @@ -132,13 +124,16 @@ input.select-box-search { background: url("../img/magnifying-glass-308581.svg") no-repeat right; background-size: 40px 40px; background-color: white; - /*padding-left: 40px;*/ + margin-bottom: -1px; +} + +.select-box-results .main-part { + display: block; } .select-box-results .other-part { + border-top: 1px solid #000000; color: darkgray; - /*border: 1px solid #00fa17;*/ - display: block; } .select-box-results .other-header { @@ -147,22 +142,29 @@ input.select-box-search { margin-left: 10px; } -.select-box-results .main-part { - border-bottom: 1px solid #000000; - display: block; -} - +/*???*/ .select-box-options .box-wrapper, .select-box-results { /*padding: 0 10px;*/ min-width: 300px; max-width: 400px; } +button.button-add{ + box-shadow: none; + border: none; +} .button-add { + /*position: absolute;*/ + float: right; + z-index: 999; + font-family: Myriad; + font-weight: normal; + font-style: normal; + font-size: 12pt; -moz-border-radius: 15px; /* Firefox */ -webkit-border-radius: 15px; /* Safari 4 */ border-radius: 15px; /* IE 9, Safari 5, Chrome */ - background-color: red; + background-color: #FF0029; padding: 0 15px; /*border: none;*/ text-decoration: none; @@ -170,39 +172,23 @@ input.select-box-search { } -.button-add .results { - position: absolute; - left: 280px; - z-index: 999; -} +/*.button-add .results {*/ + /*position: absolute;*/ + /*left: 280px;*/ + /*z-index: 999;*/ +/*}*/ -.button-add.options { - position: absolute; - /*FIXME: костыль*/ - left: 160px; - z-index: 999; - /*right: auto;*/ - /*@position: absolute;*/ - /*top: 40px;*/ -} +/*.button-add.options {*/ + /*position: absolute;*/ + /*!*FIXME: костыль*!*/ + /*left: 160px;*/ + /*z-index: 999;*/ + /*!*right: auto;*!*/ + /*!*@position: absolute;*!*/ + /*!*top: 40px;*!*/ +/*}*/ .highlight { color: red; } -.editable-container { - display: block; - float: left; - background-color: #e5e5e5; - color: #585858; - font-size: 9pt; - padding: 5px 10px; - height: 51px; - margin-left: 8px; - position: relative; - left: -30px; -} - -.vertical-child { - margin-top: 30px; -} \ No newline at end of file diff --git a/assets/lib/proekton-components/css/selected-container.css b/assets/lib/proekton-components/css/selected-container.css new file mode 100644 index 0000000..6c50261 --- /dev/null +++ b/assets/lib/proekton-components/css/selected-container.css @@ -0,0 +1,61 @@ +.selected-container { + /*display: inline-block;*/ + /*width: 100%;*/ + min-height: 40px; + padding-bottom: 20px; +} + +.selected-container .selected-element { + /*display: inline-block;*/ + padding: 5px 35px 5px 10px; + margin-top: 8px; + min-height: 45px; + background-color: #e3e3e3; + border: 1px solid #dbdbdb; + position: relative; + -moz-border-radius: 10px; /* Firefox */ + -webkit-border-radius: 10px; /* Safari 4 */ + border-radius: 10px; /* IE 9, Safari 5, Chrome */ +} +.horizontal .selected-element{ + display: inline-block; +} + +.selected-element .header,.name{ + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + width: 100%; +} + +.selected-element .header{ + font-size: 7pt; + color: #676363; + /*white-space: nowrap;*/ + /*text-overflow: ellipsis;*/ + /*overflow: hidden;*/ + /*word-wrap: break-word;*/ + /*width: 100%;*/ +} + +.selected-element .name { + font-size: 11pt; + /*white-space: nowrap;*/ + /*text-overflow: ellipsis;*/ + /*overflow: hidden;*/ + /*width: 100%;*/ +} + + +.selected-element .icon-remove{ + background-image: url('../img/cross01.png'); + background-size: 20px 20px; + /*display: inline-block;*/ + position: absolute; + right: 5px; + top: 15px; + width: 20px; + height: 20px; + cursor: pointer; + margin-left: -20px; +} \ No newline at end of file diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.css b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.css new file mode 100644 index 0000000..2156515 --- /dev/null +++ b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.css @@ -0,0 +1,11 @@ +/** Created by TTF.in.ua **/ +@font-face { + font-family: 'Arial-MT-Regular'; + src: url('Arial-MT-Regular.eot'); + src: url('Arial-MT-Regular.eot?#iefix') format('embedded-opentype'), + url('Arial-MT-Regular.woff') format('woff'), + url('Arial-MT-Regular.ttf') format('truetype'), + url('Arial-MT-Regular.svg#Arial-MT-Regular') format('svg'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.eot b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.eot new file mode 100644 index 0000000..f0e6331 Binary files /dev/null and b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.eot differ diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.otf b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.otf new file mode 100644 index 0000000..4176330 Binary files /dev/null and b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.otf differ diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.svg b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.svg new file mode 100644 index 0000000..01e1995 --- /dev/null +++ b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.svg @@ -0,0 +1,928 @@ + + + + +Created by FontForge 20090914 at Wed Mar 27 10:04:00 2013 + By www-data +Digitized data copyright The Monotype Corporation 1991-1995. All rights reserved. Arial® is a trademark of The Monotype Corporation which may be registered in certain jurisdictions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.ttf b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.ttf new file mode 100644 index 0000000..c19112c Binary files /dev/null and b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.ttf differ diff --git a/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.woff b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.woff new file mode 100644 index 0000000..8fb09bc Binary files /dev/null and b/assets/lib/proekton-components/fonts/Arial-MT-Regular/Arial-MT-Regular.woff differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Bold.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Bold.otf new file mode 100644 index 0000000..e80b807 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Bold.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCond.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCond.otf new file mode 100644 index 0000000..c6864bd Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCond.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCondIt.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCondIt.otf new file mode 100644 index 0000000..2179333 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldCondIt.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldIt.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldIt.otf new file mode 100644 index 0000000..9c37583 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-BoldIt.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Cond.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Cond.otf new file mode 100644 index 0000000..fe187b8 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Cond.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-CondIt.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-CondIt.otf new file mode 100644 index 0000000..bbf4de8 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-CondIt.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-It.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-It.otf new file mode 100644 index 0000000..0b74757 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-It.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Regular.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Regular.otf new file mode 100644 index 0000000..f686221 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Regular.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Semibold.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Semibold.otf new file mode 100644 index 0000000..1b33d74 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-Semibold.otf differ diff --git a/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-SemiboldIt.otf b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-SemiboldIt.otf new file mode 100644 index 0000000..e92ba39 Binary files /dev/null and b/assets/lib/proekton-components/fonts/MyriadPro/MyriadPro-SemiboldIt.otf differ diff --git a/assets/lib/proekton-components/img/cross.ico b/assets/lib/proekton-components/img/cross.ico deleted file mode 100644 index 1c7fde2..0000000 Binary files a/assets/lib/proekton-components/img/cross.ico and /dev/null differ diff --git a/assets/lib/proekton-components/img/zoom.png b/assets/lib/proekton-components/img/zoom.png new file mode 100644 index 0000000..cfd0e74 Binary files /dev/null and b/assets/lib/proekton-components/img/zoom.png differ diff --git a/assets/lib/proekton-components/img/zoom1.png b/assets/lib/proekton-components/img/zoom1.png new file mode 100644 index 0000000..873693f Binary files /dev/null and b/assets/lib/proekton-components/img/zoom1.png differ diff --git a/assets/lib/proekton-components/js/SelectBox.js b/assets/lib/proekton-components/js/SelectBox.js deleted file mode 100644 index e0a2497..0000000 --- a/assets/lib/proekton-components/js/SelectBox.js +++ /dev/null @@ -1,306 +0,0 @@ -// ` -class SelectBox { - constructor($container, data, has_editable_container, vertical_child) { - this.container_id = $container.attr("id"); - this.tree_data = new SpecTree(data); - // Вариант не выбран - this.selected_id = undefined; - let template = SelectBox.getTemplate("Header", this.container_id, has_editable_container, vertical_child); - $container.replaceWith(template); - this._buildComponents(); - this._bindEvents(); - if (!has_editable_container) this.hide(); - } - - static getTemplate(header, id, editable_container, vertical_child) { - let main = ` -
    -
    - - -
    -
    - -
    -
    -`; - let child = ` - - - -`; - let insert_template = editable_container ? main : child; - vertical_child = vertical_child ? 'vertical-child' : ''; - let htmlTemplate = - ` - -
    - ${header} - -
    - - ${insert_template} - - - -
      - -
    -
    -
    - - - -
      -
    -
    - - Из других категорий -
      -
    -
    -
    - -
    - -
    -`; - return htmlTemplate; - } - - _buildComponents() { - this.$select_box = $(`#${this.container_id}`); - this.$header = this.$select_box.find('.select-box-header .header'); - this.$results_box = this.$select_box.find('.select-box-results'); - this.$options_box = this.$select_box.find('.select-box-options'); - this.$search_input = this.$select_box.find('input.select-box-search'); - this.$button_add = this.$results_box.find('.button-add'); - this.$button_add_options = this.$select_box.find('.button-add.options'); - this.$editable_container = this.$select_box.find('.editable-container'); - this._fillOptionsData(); - this.$results_box.hide(); - this.$options_box.hide(); - this.$button_add_options.hide(); - // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select - } - - static highlight(string, sub_string) { - let index = string.toLowerCase().indexOf(sub_string.toLowerCase()); - if (index === -1) return string; - let light_template = (el) => `${el}`; - let [to, select, after] = [string.slice(0, index), - string.slice(index, index + sub_string.length), - string.slice(index + sub_string.length)]; - return `${to}${light_template(select)}${after}` - } - - hide() { - this.$select_box.hide(); - } - - show() { - this.$select_box.show(); - } - - clear() { - this.$search_input.val(""); - this.$options_box.hide(); - this.$results_box.hide(); - this.$button_add_options.hide(); - this.element_id = undefined; - this.parent_id = undefined; - this.$editable_container.html(""); - if (this.prev_select_box) this.hide(); - this.selected_id = undefined; - this.selected_val = ""; - } - - clearAll(only_next) { - // console.log("only_next = ", only_next); - if (this.next_select_box) { - this.next_select_box.clear() - } - if (!only_next) { - this.clear(); - if (this.prev_select_box) this.prev_select_box.clearAll(only_next) - } else { - if (this.next_select_box) this.next_select_box.clearAll(only_next) - } - - } - - setHeader(header) { - this.$header.html(header); - this.show(); - } - - setParent(parent_id) { - // console.log("setParent id -->", parent_id); - this.parent_id = parent_id; - this._fillOptionsData(); - } - - setNearbySelectBox(next, prev) { - this.next_select_box = next; - this.prev_select_box = prev; - } - - getSelectedElements() { - let all_checked = this.$results_box.find(":checked"); - return all_checked.map(function () { - return $(this).data("id"); - }) - } - - connectSelectedContainer(selected_container) { - this.selected_container = selected_container; - this.selected_container = selected_container; - - } - - updateEditableContainer(el_id) { - // Если нет контейнера для отображения ... - if (this.$editable_container.length) { - let chain_header = SelectedContainer.getHeader( - this.tree_data.getSpecChain(el_id, true), " / "); - let el_template = `${chain_header}`; - this.$editable_container.html(el_template); - return; - } - //..., передаем отображение предыдущему selectBox - if (this.prev_select_box) this.prev_select_box.updateEditableContainer(el_id); - } - - _onclickOptionsElement(e) { - this.clearAll(true); - let el_id = $(e.target).data("id"); - this.selected_id = el_id; - this.selected_val = $(e.target).html(); - this.updateEditableContainer(el_id); - this.$search_input.val($(e.target).html()); - // this.element_id = el_id; - if (this.next_select_box) { - this.next_select_box.setParent(el_id); - this.next_select_box.setHeader($(e.target).html()); - } - if (this.prev_select_box) this.prev_select_box.$button_add_options.hide(); - - this.$button_add_options.show(); - this.$options_box.hide(); - } - - _onButtonAdd(e) { - let self = this; - - this.getSelectedElements().each(function () { - console.log("add el -->", this); - self.selected_container.add(this, 40); - }); - this.clearAll(); - e.preventDefault(); - return false; - } - - _onButtonAddOptions(e) { - this.selected_container.add(this.element_id, 40); - this.clearAll(); - e.preventDefault(); - return false; - } - - _fillOptionsData() { - let self = this; - let spec_list = this.tree_data.dataToList(this.parent_id); - let $container = this.$options_box.find('ul'); - $container.html(""); - spec_list.forEach(function (el) { - let el_html = `
  • ${el.name}
  • `; - $container.append($(el_html)) - }); - this.$select_box.find('li').on("click", this._onclickOptionsElement.bind(self)); - - } - - _fillResultsData(search_text) { - let self = this; - - function search(search_text, parent_id, exclude_id) { - // :FORMAT spec_list [{name, id}, ...] - let spec_list = self.tree_data.dataToList(parent_id, true, exclude_id); - // console.log("search -->", spec_list.length); - console.log("parent_id ", parent_id); - return spec_list.filter(function (el) { - return el.name.toLowerCase().indexOf(search_text.toLowerCase()) !== -1; - }); - } - - function fillContainer($container, template, search_text, parent_id, exclude_id) { - $container.html(""); - let search_res = search(search_text, parent_id, exclude_id); - if (!search_res.length || (!exclude_id && parent_id === null)) { - $container.append('No Found'); - return; - } - search_res.forEach(function (el) { - $container.append(template(SelectBox.highlight(el.name, search_text), el.id)); - }); - } - - // FILL RESULTS - let result_template = (el, id) => - `
  • `; - // MAIN PART - let $container = this.$results_box.find('.main-part ul'); - fillContainer($container, result_template, search_text, self.parent_id); - - // OTHER PART - $container = this.$results_box.find('.other-part ul'); - fillContainer($container, result_template, search_text, null, self.parent_id); - } - - _looseFocus() { - this.$results_box.hide(); - this.$options_box.hide(); - if (!this.selected_id) { - this.$search_input.val(""); - } else { - this.$search_input.val(this.selected_val); - } - } - - _bindEvents() { - let self = this; - $(document).click(function (event) { - if ($(event.target).closest(`#${self.container_id}`).length) { - return; - } - self._looseFocus(); - }); - // console.log("out ", this.$options_box); - this.$search_input.on("input", function (e) { - self._fillResultsData(self.$search_input.val()); - self.$results_box.show(); - self.$options_box.hide(); - - }); - - this.$search_input.on("click", function (e) { - // console.log("in ", self.$options_box); - self.$options_box.show(); - self.$results_box.hide(); - self.$button_add_options.hide(); - self.$search_input.val(""); - - }); - - - this.$button_add.on("click", function (e) { - self._onButtonAdd(e); - }); - - this.$button_add_options.on("click", this._onButtonAddOptions.bind(self)) - } - -} - - diff --git a/assets/lib/proekton-components/js/SimpleSelect.js b/assets/lib/proekton-components/js/SimpleSelect.js deleted file mode 100644 index c8b9f1d..0000000 --- a/assets/lib/proekton-components/js/SimpleSelect.js +++ /dev/null @@ -1,203 +0,0 @@ -// ` -class SimpleSelect { - constructor($container, data) { - this.container_id = $container.attr("id"); - this.data = data || SimpleSelect._collectData($container); - let template = SimpleSelect.getTemplate("Header", this.container_id); - $container.replaceWith(template); - this._buildComponents(); - this._bindEvents(); - } - - static getTemplate(header, id) { - let insert_template = ` - - -`; - - let htmlTemplate = - ` - -
    - ${header} - -
    - - ${insert_template} - - - -
      - -
    -
    -
    - - - -
      -
    -
    - -
    -
    - -
    -`; - return htmlTemplate; - } - - clear() { - this.$search_input.val(""); - this.$options_box.hide(); - this.$results_box.hide(); - this.selected_id = undefined; - } - - connectSelectedContainer(selected_container) { - this.selected_container = selected_container; - - } - - - setHeader(header) { - this.$header.html(header); - } - - getSelectedElements() { - let all_checked = this.$results_box.find(":checked"); - return all_checked.map(function () { - return $(this).data("id"); - }) - } - - - static _collectData($container) { - let $options = $container.find('option'); - let data = []; - $options.each(function () { - data.push({id: $(this).val(), name: $(this).html()}); - // $(this).remove(); - }); - return data - } - - _fillOptionsData() { - let self = this; - let $container = this.$options_box.find('ul'); - $container.html(""); - this.data.forEach(function (el) { - let el_html = `
  • ${el.name}
  • `; - $container.append($(el_html)) - }); - this.$select_box.find('li').on("click", this._onclickOptionsElement.bind(self)); - } - - _fillResultsData(search_text) { - let self = this; - - function search(search_text) { - // :FORMAT spec_list [{name, id}, ...] - return self.data.filter(function (el) { - return el.name.toLowerCase().indexOf(search_text.toLowerCase()) !== -1; - }); - } - - function fillContainer($container, template, search_text, parent_id, exclude_id) { - $container.html(""); - let search_res = search(search_text, parent_id, exclude_id); - if (!search_res.length || (!exclude_id && parent_id === null)) { - $container.append('No Found'); - return; - } - search_res.forEach(function (el) { - $container.append(template(SelectBox.highlight(el.name, search_text), el.id)); - }); - } - - // FILL RESULTS - let result_template = (el, id) => - `
  • `; - // MAIN PART - let $container = this.$results_box.find('.main-part ul'); - fillContainer($container, result_template, search_text, self.parent_id); - - // OTHER PART - $container = this.$results_box.find('.other-part ul'); - fillContainer($container, result_template, search_text, null, self.parent_id); - //FIXME: duplicate code --^ - } - - _buildComponents() { - this.$select_box = $(`#${this.container_id}`); - this.$header = this.$select_box.find('.select-box-header .header'); - this.$results_box = this.$select_box.find('.select-box-results'); - this.$options_box = this.$select_box.find('.select-box-options'); - this.$search_input = this.$select_box.find('input.select-box-search'); - this.$button_add = this.$results_box.find('.button-add'); - // this.$button_add_options = this.$select_box.find('.button-add.options'); - // this.$editable_container = this.$select_box.find('.editable-container'); - this._fillOptionsData(); - this.$results_box.hide(); - this.$options_box.hide(); - // this.$button_add_options.hide(); - // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select - } - - _looseFocus() { - this.$results_box.hide(); - this.$options_box.hide(); - this.$search_input.val(""); - } - - _bindEvents() { - let self = this; - $(document).click(function (event) { - if ($(event.target).closest(`#${self.container_id}`).length) { - return; - } - self._looseFocus(); - }); - // console.log("out ", this.$options_box); - this.$search_input.on("input", function (e) { - self._fillResultsData(self.$search_input.val()); - self.$results_box.show(); - self.$options_box.hide(); - - }); - - this.$search_input.on("click", function (e) { - self.$options_box.show(); - self.$results_box.hide(); - self.$search_input.val(""); - - }); - - - this.$button_add.on("click", function (e) { - self._onButtonAdd(e); - }); - - } - - _onclickOptionsElement(e) { - console.log("selelc with id =", $(e.target).data("id")); - this.selected_id = $(e.target).data("id"); - if (this.selected_container) this.selected_container.add(this.selected_id, 40); - this.$options_box.hide(); - } - - _onButtonAdd(e) { - let self = this; - - this.getSelectedElements().each(function () { - console.log("add el -->", this); - self.selected_container.add(this, 40); - }); - this.clear(); - e.preventDefault(); - return false; - } - - -} \ No newline at end of file diff --git a/assets/lib/proekton-components/js/SimpleSelectedContainer.js b/assets/lib/proekton-components/js/SimpleSelectedContainer.js deleted file mode 100644 index 6c77e57..0000000 --- a/assets/lib/proekton-components/js/SimpleSelectedContainer.js +++ /dev/null @@ -1,74 +0,0 @@ -// ` -class SimpleSelectedContainer { - constructor($container, data) { - this.$self = $container; - this.elements_id = []; // [spec_id, spec_id, ...] - this.data = data; - this.$input = this.$self.find('input[type="hidden"]'); - this.restoreElements(); - } - - restoreElements() { - const self = this; - if (this.$input && this.$input.val()){ - let data = this.$input.val().split(',').filter((el) => el); - console.log("restore data = ", data); - this.elements_id = []; - data.forEach((el) => self.add(el)); - } - } - - static getTemplate(name, id) { - let htmlTemplate = - ` -
    -
    - ${name} -
    - -
    -`; - return htmlTemplate - } - - - _removeById(spec_id) { - let index = this.elements_id.indexOf(spec_id); - if (index >= 0) { - this.elements_id.splice(index, 1); - } - $(`span[data-id='${spec_id}']`).parents('.selected-element').remove(); - } - - remove(e) { - let spec_id = $(e.target).data("id"); - this._removeById(spec_id); - if (this.$input) this.$input.val(this.elements_id.join(',')); - e.preventDefault(); - } - - getElementById(id) { - for (let i = 0; i < this.data.length; i++) { - if (this.data[i].id == id) return this.data[i] - } - } - - add(_id, max_len) { - const id = Number(_id); - // TODO: добавить учет max_len - let self = this; - if ((this.elements_id).indexOf(id) != -1) { - //TODO: do popup messages - console.log("Not actually"); - return; - } - // console.log("!", this.getElementById(id)); - const name = this.getElementById(id).name; - this.elements_id.push(id); - if (this.$input) this.$input.val(this.elements_id.join(',')); - this.$self.append(SimpleSelectedContainer.getTemplate(name, id)); - this.btn_remove = this.$self.find('.icon-remove'); - this.btn_remove.on("click", this.remove.bind(self)); - console.log(); - } -} diff --git a/assets/lib/proekton-components/src/NoTreeSelect.js b/assets/lib/proekton-components/src/NoTreeSelect.js new file mode 100644 index 0000000..6f71488 --- /dev/null +++ b/assets/lib/proekton-components/src/NoTreeSelect.js @@ -0,0 +1,28 @@ +import AbsBaseSelect from './base/AbsBaseSelect' +import NoTreeData from './data/NoTreeData' + +export default class NoTreeSelect extends AbsBaseSelect{ + constructor({$container, data}){ + super({$container, data: new NoTreeData(data)}); + this.$buttonAddOptions.hide(); + } + + _onclickOptionsElement(e) { + this.selectedEl.id = $(e.target).data("id"); + this.selectedEl.value = $(e.target).html(); + this.$searchInput.val($(e.target).html()); + + this.$buttonAddOptions.show(); + this.$optionsBox.hide(); + + this.selectedContainer.add(this.selectedEl.id); + this.clear(); + e.preventDefault(); + return false; + } + + _onButtonAddOptions(e) { + // pass + } + +} diff --git a/assets/lib/proekton-components/js/SelectedContainer.js b/assets/lib/proekton-components/src/SelectedContainer.js similarity index 73% rename from assets/lib/proekton-components/js/SelectedContainer.js rename to assets/lib/proekton-components/src/SelectedContainer.js index 43e0b30..109aad7 100644 --- a/assets/lib/proekton-components/js/SelectedContainer.js +++ b/assets/lib/proekton-components/src/SelectedContainer.js @@ -1,16 +1,33 @@ // ` -class SelectedContainer { - constructor($container, data) { +import DataTree from './data/DataTree' +import NoTreeData from './data/NoTreeData' + +let tmpl_selectedElement = (header, name, id) => + ` +
    +
    + ${header} +
    +
    + ${name} +
    + +
    +`; + +export default class SelectedContainer { + constructor($container, data, noTree = false) { + // TODO: rename variables to camelCase this.$self = $container; this.elements_id = []; // [spec_id, spec_id, ...] - this.tree_data = new SpecTree(data); + this.dataTree = noTree ? new NoTreeData(data) : new DataTree(data); this.$input = this.$self.find('input[type="hidden"]'); this.restoreElements(); } - restoreElements(){ + restoreElements() { const self = this; - if (this.$input && this.$input.val()){ + if (this.$input && this.$input.val()) { let data = this.$input.val().split(',').filter((el) => el); console.log("restore data = ", data); this.elements_id = []; @@ -19,19 +36,7 @@ class SelectedContainer { } static getTemplate(header, name, id) { - let htmlTemplate = - ` -
    -
    - ${header} -
    -
    - ${name} -
    - -
    -`; - return htmlTemplate + return tmpl_selectedElement(header, name, id) } static getHeader(spec_chain, separator, max_len) { @@ -54,7 +59,7 @@ class SelectedContainer { if (index >= 0) { this.elements_id.splice(index, 1); } - $(`span[data-id='${spec_id}']`).parents('.selected-element').remove(); + this.$self.find(`span[data-id='${spec_id}']`).parents('.selected-element').remove(); } remove(e) { @@ -69,7 +74,7 @@ class SelectedContainer { let self = this; let has_already = this.elements_id.filter(function (el) { - return self.tree_data.hasChildren(el, id) + return self.dataTree.isChild(el, id) }); // console.log(has_already); @@ -80,19 +85,19 @@ class SelectedContainer { } let not_valid = this.elements_id.filter(function (el) { - return self.tree_data.hasChildren(id, el) + return self.dataTree.isChild(id, el) }); not_valid.forEach(function (el) { - self._removeById(el); + self._removeById(el); }); - const header = SelectedContainer.getHeader(this.tree_data.getSpecChain(id), "", max_len); + const header = SelectedContainer.getHeader(this.dataTree.getSpecChain(id), "", max_len); // console.log("header = ", header); - const name = this.tree_data.getElementById(id).name; + const name = this.dataTree.getElementById(id).name; this.elements_id.push(id); if (this.$input) this.$input.val(this.elements_id.join(',')); - this.$self.append(SelectedContainer.getTemplate(header || "root", name, id)); + this.$self.append(SelectedContainer.getTemplate(header || " ", name, id)); this.btn_remove = this.$self.find('.icon-remove'); this.btn_remove.on("click", this.remove.bind(self)); } diff --git a/assets/lib/proekton-components/src/TreeSelect.js b/assets/lib/proekton-components/src/TreeSelect.js new file mode 100644 index 0000000..bfae415 --- /dev/null +++ b/assets/lib/proekton-components/src/TreeSelect.js @@ -0,0 +1,70 @@ +import AbsBaseSelect from './base/AbsBaseSelect' +import DataTree from './data/DataTree' + +export default class TreeSelect extends AbsBaseSelect{ + constructor({$container, data, hasEditableContainer = false}){ + super({$container, data: new DataTree(data), hasEditableContainer}); + } + + setNearbySelectBox(next, prev) { + this.nextSelectBox = next; + this.prevSelectBox = prev; + } + + clearAllNext() { + // console.log("clearAllNext"); + this.clear(); + if (this.nextSelectBox) { + this.nextSelectBox.hide(); + this.nextSelectBox.clearAllNext() + } + } + + clearAllPrev(){ + this.clear(); + if (this.prevSelectBox) { + this.clear(); + this.hide(); + // this.prevSelectBox.clear(); + this.prevSelectBox.clearAllPrev() + } + } + + _onclickOptionsElement(e) { + this.clearAllNext(); + super._onclickOptionsElement(e); + + if (this.nextSelectBox && this.dataTree.hasChildren(this.selectedEl.id)) { + this.nextSelectBox.setParent(this.selectedEl.id); + this.nextSelectBox.setHeader(this.selectedEl.value); + this.nextSelectBox.show(); + } + if (this.prevSelectBox) this.prevSelectBox.$buttonAddOptions.hide(); + } + + _onButtonAddOptions(e) { + // this._addToSelectedContainer(this.selectedEl.id); + // this.clear(); + // e.preventDefault(); + // return false; + super._onButtonAddOptions(e); + this.clearAllNext(); + this.clearAllPrev(); + } + + _onButtonAdd(e) { + super._onButtonAdd(e); + this.clearAllNext(); + this.clearAllPrev(); + } + + _addToSelectedContainer(id){ + if (this.selectedContainer){ + this.selectedContainer.add(id); + return + } + + this.prevSelectBox._addToSelectedContainer(id); + } + +} diff --git a/assets/lib/proekton-components/src/base/AbsBaseSelect.js b/assets/lib/proekton-components/src/base/AbsBaseSelect.js new file mode 100644 index 0000000..d54bc76 --- /dev/null +++ b/assets/lib/proekton-components/src/base/AbsBaseSelect.js @@ -0,0 +1,362 @@ +//TEMPLATES +const tmpl_selectBoxEditCont = () =>` +
    +
    + + +
    +
    + +
    +
    +`; +const tmpl_selectBox = () =>` + + + +`; +const tmpl_elementResult = (el, id, header) => + `
  • `; +const tmpl_elementOption = (el) => + `
  • ${el.name}
  • `; +//${vertical_child} +const htmlTemplate = ({header, selectBox, id}) => + ` +
    +
    +
    ${header}
    + +
    + +
    +
    +
      + +
    +
    +
    +
    +
    +
    +
      +
    +
    +
    + Из других категорий +
      +
    +
    +
    + +
    + +
    +`; +let tmpl_light = (el) => `${el}`; + +export default class AbsBaseSelect { + // constructor($container, data, hasEditableContainer, verticalChild) { + constructor({$container, data, hasEditableContainer = false}) { + if (new.target === AbsBaseSelect) { + throw new TypeError("Cannot construct Abstract instances directly"); + } + //TODO: добавить применение классов контейнера + //TODO: проверка наличия id контейнера + this.containerId = $container.attr("id"); + this.dataTree = data; + console.log("data = ", data); + // Вариант не выбран + this.hasEditableContainer = hasEditableContainer; + let template = this.getTemplate(); + $container.replaceWith(template); + this._buildComponents(); + this._bindEvents(); + // if (!has_editable_container) this.hide(); + // INIT EMPTY PROP + this.selectedEl = {id: undefined, value: undefined}; + this.parentId = undefined; + this.hide(); + } + + // getTemplate(header, id, editable_container, vertical_child) { + getTemplate() { + let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox(); + return htmlTemplate({header: "TestHeader", selectBox, id: this.containerId}) + } + + static getHeader(catChain, {separator = " / ", maxLen = 60}) { + function toShortString(string, maxLen) { + return string.slice(0, maxLen) + (string.length > maxLen ? "..." : ""); + } + + let strChain = ""; + + catChain.forEach(function (el) { + strChain = (maxLen ? toShortString(el.name, maxLen) : el.name) + (strChain ? separator : "") + strChain; + }); + + return strChain; + } + + static highlight(string, sub_string, lastIndex = false) { + let index = lastIndex + ? string.toLowerCase().lastIndexOf(sub_string.toLowerCase()) + : string.toLowerCase().indexOf(sub_string.toLowerCase()); + console.log("index = ", index); + if (index === -1) return string; + let before, select, after; + if (lastIndex) { + [before, select, after] = [string.slice(0, index), + string.slice(index, string.length), + ""]; + } else { + [before, select, after] = [string.slice(0, index), + string.slice(index, index + sub_string.length), + string.slice(index + sub_string.length)]; + } + + return `${before}${tmpl_light(select)}${after}` + } + + clear() { + console.log("clear"); + this.$searchInput.val(""); + this.$optionsBox.hide(); + this.$resultsBox.hide(); + this.$buttonAdd.hide(); + this.$buttonAddOptions.hide(); + this.selectedEl = {id: undefined, value: undefined}; + if (this.hasEditableContainer) { + this.$editableContainer.html(""); + this.$editableContainer.hide() + } + } + + hide() { + this.$selectBox.hide(); + } + + show() { + this.$selectBox.show(); + } + + setHeader(header) { + this.$header.html(header); + // default hide + this.show(); + } + + setParent(parentId) { + this.parentId = parentId; + this._fillOptionsData(); + } + + connectSelectedContainer(selectedContainer) { + this.selectedContainer = selectedContainer; + } + + getIdsSelectedElements() { + let allChecked = this.$resultsBox.find(":checked"); + return allChecked.map(function () { + return $(this).data("id"); + }) + } + + updateEditableContainer(elId) { + // Если нет контейнера для отображения ... + if (this.$editableContainer.length) { + const separator = ' / '; + let chainHeader = AbsBaseSelect.getHeader(this.dataTree.getSpecChain(elId, true), {separator: separator}); + console.log('chainHeader = ', chainHeader); + chainHeader = AbsBaseSelect.highlight(chainHeader, separator, true); + let elTemplate = `${chainHeader}`; + this.$editableContainer.html(elTemplate); + this.$editableContainer.show(); + return; + } + //..., передаем отображение предыдущему selectBox + if (this.prevSelectBox) this.prevSelectBox.updateEditableContainer(elId); + } + + + _buildComponents() { + this.$selectBox = $(`#${this.containerId}`); + this.$header = this.$selectBox.find('.select-box-header .header'); + this.$resultsBox = this.$selectBox.find('.select-box-results'); + this.$optionsBox = this.$selectBox.find('.select-box-options'); + this.$searchInput = this.$selectBox.find('input.select-box-search'); + this.$buttonAdd = this.$selectBox.find('.button-add.results'); + this.$buttonAddOptions = this.$selectBox.find('.button-add.options'); + this.$editableContainer = this.$selectBox.find('.editable-container'); + if (this.hasEditableContainer) this.$editableContainer.hide(); + this._fillOptionsData(); + this.$resultsBox.hide(); + this.$optionsBox.hide(); + this.$buttonAddOptions.hide(); + // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select + } + + _fillOptionsData() { + let self = this; + let dataList = this.dataTree.dataToList(this.parentId); + let $container = this.$optionsBox.find('ul'); + $container.html(""); + for (let el of dataList) { + $container.append($(tmpl_elementOption(el))) + } + + this.$selectBox.find('li').on("click", this._onclickOptionsElement.bind(self)); + + } + + _fillResultsData(searchText) { + let self = this; + + function search({searchText, parentCategoryId = null, excludeCategoryId = null}) { + // :FORMAT spec_list [{name, id}, ...] + let specList = self.dataTree.dataToList(parentCategoryId, true, excludeCategoryId); + // console.log("search -->", spec_list.length); + // console.log("parent_id ", parentCategoryId); + return specList.filter(function (el) { + return el.name.toLowerCase().indexOf(searchText.toLowerCase()) !== -1; + }); + } + + function fillContainer($container, template, {searchText = "", parentCategoryId = null, excludeCategoryId = null}) { + $container.html(""); + $('.other-part').show(); + let searchRes = search({searchText, parentCategoryId, excludeCategoryId}); + // || (!excludeCategoryId && parentCategoryId === null) + console.log("searchRes = ", searchRes); + if (!searchRes.length) { + if ($container.closest('div').hasClass('main-part')) { + $container.append('
  • Ничего не найдено
  • '); + self.$resultsBox.find('.button-add.results').hide(); + // console.log('not found main-part'); + } else { + $('.other-part').hide(); + // console.log('not found other-part'); + } + return; + } + self.$resultsBox.find('.button-add.results').show(); + for (let el of searchRes) { + let header = AbsBaseSelect.getHeader(self.dataTree.getSpecChain(el.id), {}); + $container.append(template(AbsBaseSelect.highlight(el.name, searchText), el.id, header)); + } + } + + // FILL RESULTS + // MAIN PART + let $container = this.$resultsBox.find('.main-part ul'); + fillContainer($container, tmpl_elementResult, {searchText: searchText, parentCategoryId: self.parentId}); + + // OTHER PART + // Если нет parentId, не нужно искать в других категориях + // console.log("parentID = ", this.parentId); + if (!this.parentId) { + $('.other-part').hide(); + } else { + $container = this.$resultsBox.find('.other-part ul'); + // console.log("Fill other-part"); + fillContainer($container, tmpl_elementResult, {searchText: searchText, excludeCategoryId: self.parentId}); + } + this.$resultsBox.find('div.header').hide(); + this.$resultsBox.find('li').on("mouseover", function (e) { + $(e.target).children('.header').show(300); + e.preventDefault(); + }); + + + this.$resultsBox.find('li').on("mouseout", function (event) { + let e = event.toElement || event.relatedTarget; + console.log(e.parentNode, ' ==', this); + console.log(e, ' ==', this); + if (e.parentNode == this || e == this) { + return; + } + console.log("OUT"); + $(this).find('.header').hide(); + }) + + + } + + _onclickOptionsElement(e) { + this.selectedEl.id = $(e.target).data("id"); + this.selectedEl.value = $(e.target).html(); + this.$searchInput.val($(e.target).html()); + this.updateEditableContainer($(e.target).data("id")); + this.$buttonAddOptions.show(); + this.$optionsBox.hide(); + } + + _onButtonAddOptions(e) { + this._addToSelectedContainer(this.selectedEl.id); + this.clear(); + e.preventDefault(); + return false; + } + + _onButtonAdd(e) { + let self = this; + + this.getIdsSelectedElements().each(function () { + console.log("add el -->", this); + self._addToSelectedContainer(this); + }); + this.clear(); + e.preventDefault(); + return false; + } + + _addToSelectedContainer(id) { + this.selectedContainer.add(id) + } + + _bindEvents() { + let self = this; + $(document).click(function (event) { + if ($(event.target).closest(`#${self.containerId}`).length) { + return; + } + self._looseFocus(); + }); + // RESULTS BOX + this.$searchInput.on("input", function (e) { + self._fillResultsData(self.$searchInput.val()); + self.$resultsBox.show(); + self.$optionsBox.hide(); + + }); + // OPTIONS BOX + this.$searchInput.on("click", function (e) { + self.$optionsBox.show(); + self.$resultsBox.hide(); + self.$buttonAddOptions.hide(); + self.$searchInput.val(""); + }); + + this.$buttonAdd.on("click", function (e) { + self._onButtonAdd(e); + }); + + this.$buttonAddOptions.on("click", this._onButtonAddOptions.bind(self)) + } + + _looseFocus() { + this.$resultsBox.hide(); + this.$optionsBox.hide(); + if (!this.selectedEl.id) { + this.$searchInput.val(""); + } else { + this.$searchInput.val(this.selectedEl.value); + } + console.log("loose ", this.selectedEl.id); + } +} \ No newline at end of file diff --git a/assets/lib/proekton-components/js/SpecTree.js b/assets/lib/proekton-components/src/data/DataTree.js similarity index 91% rename from assets/lib/proekton-components/js/SpecTree.js rename to assets/lib/proekton-components/src/data/DataTree.js index 633984e..c95bd6b 100644 --- a/assets/lib/proekton-components/js/SpecTree.js +++ b/assets/lib/proekton-components/src/data/DataTree.js @@ -25,7 +25,7 @@ class Node { } } -class SpecTree { +export default class DataTree { constructor(data) { this.baseData = data; this._root = new Node(data[0], this); @@ -61,13 +61,18 @@ class SpecTree { * @param el_id * @param parent_id */ - hasChildren(el_id, parent_id){ + isChild(elId, parent_id){ function checkParent(el, parent) { if (el.parent == parent) return true; if (el.parent && el.parent != 'root') return checkParent(el.parent, parent); return false; } - return checkParent(this.getElementById(el_id), this.getElementById(parent_id)) + return checkParent(this.getElementById(elId), this.getElementById(parent_id)) + } + + hasChildren(elId){ + console.log('id = ', elId); + return (this.getElementById(elId).children.length) ? true : false } /** @@ -97,10 +102,9 @@ class SpecTree { * @param incl(bool) - исключая сам элемент * @returns {Array} всех узлов/элементов от элемента с id до корня */ - getSpecChain(id, incl){ + getSpecChain(id, incl=false){ let chain = []; let el = this.getElementById(id); - // console.log("el = ", el); function getParent(el) { if (el.parent && el.parent != "root"){ chain.push(el.parent); @@ -108,7 +112,6 @@ class SpecTree { } } getParent(el); - // console.log("chain = ", chain); if (incl) chain.unshift(el); return chain } diff --git a/assets/lib/proekton-components/src/data/NoTreeData.js b/assets/lib/proekton-components/src/data/NoTreeData.js new file mode 100644 index 0000000..ddd9290 --- /dev/null +++ b/assets/lib/proekton-components/src/data/NoTreeData.js @@ -0,0 +1,28 @@ +export default class NoTreeData { + constructor(data) { + this.data = data; + this.specChain = [] + } + + getElementById(id) { + for (let i = 0; i < this.data.length; i++) { + if (this.data[i].id == id) return this.data[i] + } + } + + getSpecChain(id, incl) { + return this.specChain + } + + isChild(el_id, parent_id) { + return false + } + + hasChildren() { + return false + } + + dataToList() { + return this.data + } +} \ No newline at end of file diff --git a/assets/lib/proekton-components/js/init.js b/assets/lib/proekton-components/src/init.js similarity index 64% rename from assets/lib/proekton-components/js/init.js rename to assets/lib/proekton-components/src/init.js index e10053b..d7a525e 100644 --- a/assets/lib/proekton-components/js/init.js +++ b/assets/lib/proekton-components/src/init.js @@ -1,34 +1,21 @@ +import SelectedContainer from './SelectedContainer'; +import NoTreeSelect from './NoTreeSelect'; +import TreeSelect from './TreeSelect'; + // ` -function findProjects() { - console.log("Find"); - const url = '/projects/test_page'; - let keywords = $('input[name=keywords]').val(); - let obj = {keywords}; - console.log("obj --> string", JSON.stringify(obj)); - window.location.href = `${url}?keywords=про`; - // $.ajax({ - // url: "/projects/test_page", - // data: {'foo': 'bar'}, - // async: false - // }); -} + $(function () { function createFilterSpecs(_data) { // SPECIALIZATIONS FILTER let data = _data.results; - let sb_main = new SelectBox($('#select-box-1'), data, true); + let sb_main = new TreeSelect({$container: $('#select-box-1'), data: data, hasEditableContainer: true}); sb_main.setHeader("Специализации"); let select_container = new SelectedContainer($('#selected-spec'), data); sb_main.connectSelectedContainer(select_container); - let sb_1 = new SelectBox($('#select-box-2'), data, null, true); - let sb_2 = new SelectBox($('#select-box-3'), data, null, true); - let sb_3 = new SelectBox($('#select-box-4'), data, null, true); - let sb_4 = new SelectBox($('#select-box-5'), data, null, true); - - sb_1.connectSelectedContainer(select_container); - sb_2.connectSelectedContainer(select_container); - sb_3.connectSelectedContainer(select_container); - sb_4.connectSelectedContainer(select_container); + let sb_1 = new TreeSelect({$container: $('#select-box-2'), data: data}); + let sb_2 = new TreeSelect({$container: $('#select-box-3'), data: data}); + let sb_3 = new TreeSelect({$container: $('#select-box-4'), data: data}); + let sb_4 = new TreeSelect({$container: $('#select-box-5'), data: data}); sb_main.setNearbySelectBox(sb_1); sb_1.setNearbySelectBox(sb_2, sb_main); @@ -41,12 +28,13 @@ $(function () { function createFilterBuildingClass(_data) { // BUILDING-CLASSIFICATION FILTER let data = _data.results; - let sb_build_main = new SelectBox($('#sb-building-classification'), data, false); + let sb_build_main = new TreeSelect({$container: $('#sb-building-classification'), data: data}); sb_build_main.setHeader("Классификация здания"); - let sb_build_1 = new SelectBox($('#sb-building-sub-classification'), data, null, true); - let select_build_container = new SelectedContainer($('#selected-building-classification'), data, true); + + let sb_build_1 = new TreeSelect({$container: $('#sb-building-sub-classification'), data: data}); + + let select_build_container = new SelectedContainer($('#selected-building-classification'), data); sb_build_main.connectSelectedContainer(select_build_container); - sb_build_1.connectSelectedContainer(select_build_container); sb_build_main.setNearbySelectBox(sb_build_1); sb_build_1.setNearbySelectBox("", sb_build_main); @@ -54,28 +42,25 @@ $(function () { function createFilterConstructionType(_data) { let data = _data.results; - let sb_constr_main = new SimpleSelect($('#sb-construction-type'), data); + let sb_constr_main = new NoTreeSelect({$container: $('#sb-construction-type'), data: data}); sb_constr_main.setHeader("Вид строительства"); - let select_constr_type = new SimpleSelectedContainer($('#selected-construction-type'), data); + let select_constr_type = new SelectedContainer($('#selected-construction-type'), data, true); sb_constr_main.connectSelectedContainer(select_constr_type); } function createFilerLocations(data) { - let sb_loc_main = new SelectBox($('#sb-location-1'), data); + let sb_loc_main = new TreeSelect({$container:$('#sb-location-1'), data: data}); sb_loc_main.setHeader("Местоположение"); let select_loc = new SelectedContainer($('#selected-location'), data, true); sb_loc_main.connectSelectedContainer(select_loc); - let sb_loc_1 = new SelectBox($('#sb-location-2'), data, null, true); - let sb_loc_2 = new SelectBox($('#sb-location-3'), data, null, true); - - sb_loc_1.connectSelectedContainer(select_loc); - sb_loc_2.connectSelectedContainer(select_loc); + let sb_loc_1 = new TreeSelect({$container:$('#sb-location-2'), data: data}); + let sb_loc_2 = new TreeSelect({$container:$('#sb-location-3'), data: data}); sb_loc_main.setNearbySelectBox(sb_loc_1); sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main); sb_loc_2.setNearbySelectBox("", sb_loc_1); //TODO: Временно прелоадер на самом тяжелом объекте - hidePreloader() + // hidePreloader() } @@ -136,12 +121,12 @@ $(function () { tuneCheckBoxes($('.custom-check')); // $(window).on('load', - function hidePreloader() { - var $preloader = $('#page-preloader'), - $spinner = $preloader.find('.spinner'); - $spinner.fadeOut(); - $preloader.delay(350).fadeOut('slow'); - } + // function hidePreloader() { + // var $preloader = $('#page-preloader'), + // $spinner = $preloader.find('.spinner'); + // $spinner.fadeOut(); + // $preloader.delay(350).fadeOut('slow'); + // } // $("#myBtn").click(function () { diff --git a/package.json b/package.json new file mode 100644 index 0000000..64f1d62 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "components", + "version": "0.0.3", + "description": "curl http://nodejs.org/dist/node-latest.tar.gz | tar xvz cd node-v* python2 ./configure --prefix=~/venv/proekton/(or $VIRTUAL_ENV) make install", + "main": "init.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Booblegum", + "license": "ISC", + "devDependencies": { + "babel-preset-es2015": "^6.18.0", + "babelify": "^7.3.0" + } +} diff --git a/projects/templates/partials/inc-projects-filter.html b/projects/templates/partials/inc-projects-filter.html index 11a9035..0c83222 100644 --- a/projects/templates/partials/inc-projects-filter.html +++ b/projects/templates/partials/inc-projects-filter.html @@ -1,7 +1,7 @@
    -
    + {#
    #}
    @@ -24,10 +24,10 @@
    -
    - -
    +
    + +
    @@ -51,7 +51,7 @@ placeholder="Ключевые слова, фразы">
    -{# $(this).closest('form').submit(); return false#} + {# $(this).closest('form').submit(); return false#} найти проект @@ -80,37 +80,51 @@
    -
    -
    +
    +
    +
    +
    +
    +
    -
    +
    +
    +
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    - Требуется допуск (СРО) - -
    -
    - +
    +
    + Требуется допуск (СРО) + +
    +
    + +
    diff --git a/projects/templates/project_filter.html b/projects/templates/project_filter.html index f81d7a9..5e38f9d 100644 --- a/projects/templates/project_filter.html +++ b/projects/templates/project_filter.html @@ -1,6 +1,10 @@ {% extends 'partials/base.html' %} {% load staticfiles %} {% block head_css %} + + + + @@ -28,13 +32,7 @@ {% endblock %} {% block js_block %} {{ block.super }} - {# #} - - - - - - +