PR-15 Профиль настроек исполнителя модификация

Реализовано сохранение/отображения данных пользователя
Доделан дизайн
remotes/origin/PR-15
booblegum 9 years ago
parent 6937616692
commit 7c96a8d748
  1. 7
      .babelrc
  2. 15
      assets/js/jquery.mask.min.js
  3. 8
      assets/lib/proekton-components/css/select-box.css
  4. 2
      assets/lib/proekton-components/css/selected-container.css
  5. 177
      assets/lib/proekton-components/js/build/init_user_profile.js
  6. 16
      assets/lib/proekton-components/js/src/SelectedContainer.js
  7. 24
      assets/lib/proekton-components/js/src/decorators.js
  8. 24
      assets/lib/proekton-components/js/src/init_user_profile.js
  9. 36
      assets/projects-filter.js
  10. 1
      package.json
  11. 29
      projects/static/css/project_filter.css
  12. 72
      users/forms.py
  13. 66
      users/static/css/user_profile_edit.css
  14. 409
      users/templates/user_profile_edit_new.html
  15. 4
      users/urls.py
  16. 40
      users/views.py

@ -1,3 +1,8 @@
{
"presets": ["es2015"]
"presets": [
"es2015"
],
"plugins": [
"transform-decorators-legacy"
]
}

@ -0,0 +1,15 @@
// jQuery Mask Plugin v1.14.0
// github.com/igorescobar/jQuery-Mask-Plugin
(function(b){"function"===typeof define&&define.amd?define(["jquery"],b):"object"===typeof exports?module.exports=b(require("jquery")):b(jQuery||Zepto)})(function(b){var y=function(a,e,d){var c={invalid:[],getCaret:function(){try{var r,b=0,e=a.get(0),d=document.selection,f=e.selectionStart;if(d&&-1===navigator.appVersion.indexOf("MSIE 10"))r=d.createRange(),r.moveStart("character",-c.val().length),b=r.text.length;else if(f||"0"===f)b=f;return b}catch(g){}},setCaret:function(r){try{if(a.is(":focus")){var c,
b=a.get(0);b.setSelectionRange?(b.focus(),b.setSelectionRange(r,r)):(c=b.createTextRange(),c.collapse(!0),c.moveEnd("character",r),c.moveStart("character",r),c.select())}}catch(e){}},events:function(){a.on("keydown.mask",function(c){a.data("mask-keycode",c.keyCode||c.which)}).on(b.jMaskGlobals.useInput?"input.mask":"keyup.mask",c.behaviour).on("paste.mask drop.mask",function(){setTimeout(function(){a.keydown().keyup()},100)}).on("change.mask",function(){a.data("changed",!0)}).on("blur.mask",function(){n===
c.val()||a.data("changed")||a.trigger("change");a.data("changed",!1)}).on("blur.mask",function(){n=c.val()}).on("focus.mask",function(a){!0===d.selectOnFocus&&b(a.target).select()}).on("focusout.mask",function(){d.clearIfNotMatch&&!p.test(c.val())&&c.val("")})},getRegexMask:function(){for(var a=[],c,b,d,f,l=0;l<e.length;l++)(c=g.translation[e.charAt(l)])?(b=c.pattern.toString().replace(/.{1}$|^.{1}/g,""),d=c.optional,(c=c.recursive)?(a.push(e.charAt(l)),f={digit:e.charAt(l),pattern:b}):a.push(d||
c?b+"?":b)):a.push(e.charAt(l).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"));a=a.join("");f&&(a=a.replace(new RegExp("("+f.digit+"(.*"+f.digit+")?)"),"($1)?").replace(new RegExp(f.digit,"g"),f.pattern));return new RegExp(a)},destroyEvents:function(){a.off("input keydown keyup paste drop blur focusout ".split(" ").join(".mask "))},val:function(c){var b=a.is("input")?"val":"text";if(0<arguments.length){if(a[b]()!==c)a[b](c);b=a}else b=a[b]();return b},getMCharsBeforeCount:function(a,c){for(var b=0,d=0,
f=e.length;d<f&&d<a;d++)g.translation[e.charAt(d)]||(a=c?a+1:a,b++);return b},caretPos:function(a,b,d,h){return g.translation[e.charAt(Math.min(a-1,e.length-1))]?Math.min(a+d-b-h,d):c.caretPos(a+1,b,d,h)},behaviour:function(d){d=d||window.event;c.invalid=[];var e=a.data("mask-keycode");if(-1===b.inArray(e,g.byPassKeys)){var m=c.getCaret(),h=c.val().length,f=c.getMasked(),l=f.length,k=c.getMCharsBeforeCount(l-1)-c.getMCharsBeforeCount(h-1),n=m<h;c.val(f);n&&(8!==e&&46!==e&&(m=c.caretPos(m,h,l,k)),
c.setCaret(m));return c.callbacks(d)}},getMasked:function(a,b){var m=[],h=void 0===b?c.val():b+"",f=0,l=e.length,k=0,n=h.length,q=1,p="push",u=-1,t,w;d.reverse?(p="unshift",q=-1,t=0,f=l-1,k=n-1,w=function(){return-1<f&&-1<k}):(t=l-1,w=function(){return f<l&&k<n});for(;w();){var x=e.charAt(f),v=h.charAt(k),s=g.translation[x];if(s)v.match(s.pattern)?(m[p](v),s.recursive&&(-1===u?u=f:f===t&&(f=u-q),t===u&&(f-=q)),f+=q):s.optional?(f+=q,k-=q):s.fallback?(m[p](s.fallback),f+=q,k-=q):c.invalid.push({p:k,
v:v,e:s.pattern}),k+=q;else{if(!a)m[p](x);v===x&&(k+=q);f+=q}}h=e.charAt(t);l!==n+1||g.translation[h]||m.push(h);return m.join("")},callbacks:function(b){var g=c.val(),m=g!==n,h=[g,b,a,d],f=function(a,b,c){"function"===typeof d[a]&&b&&d[a].apply(this,c)};f("onChange",!0===m,h);f("onKeyPress",!0===m,h);f("onComplete",g.length===e.length,h);f("onInvalid",0<c.invalid.length,[g,b,a,c.invalid,d])}};a=b(a);var g=this,n=c.val(),p;e="function"===typeof e?e(c.val(),void 0,a,d):e;g.mask=e;g.options=d;g.remove=
function(){var b=c.getCaret();c.destroyEvents();c.val(g.getCleanVal());c.setCaret(b-c.getMCharsBeforeCount(b));return a};g.getCleanVal=function(){return c.getMasked(!0)};g.getMaskedVal=function(a){return c.getMasked(!1,a)};g.init=function(e){e=e||!1;d=d||{};g.clearIfNotMatch=b.jMaskGlobals.clearIfNotMatch;g.byPassKeys=b.jMaskGlobals.byPassKeys;g.translation=b.extend({},b.jMaskGlobals.translation,d.translation);g=b.extend(!0,{},g,d);p=c.getRegexMask();!1===e?(d.placeholder&&a.attr("placeholder",d.placeholder),
a.data("mask")&&a.attr("autocomplete","off"),c.destroyEvents(),c.events(),e=c.getCaret(),c.val(c.getMasked()),c.setCaret(e+c.getMCharsBeforeCount(e,!0))):(c.events(),c.val(c.getMasked()))};g.init(!a.is("input"))};b.maskWatchers={};var A=function(){var a=b(this),e={},d=a.attr("data-mask");a.attr("data-mask-reverse")&&(e.reverse=!0);a.attr("data-mask-clearifnotmatch")&&(e.clearIfNotMatch=!0);"true"===a.attr("data-mask-selectonfocus")&&(e.selectOnFocus=!0);if(z(a,d,e))return a.data("mask",new y(this,
d,e))},z=function(a,e,d){d=d||{};var c=b(a).data("mask"),g=JSON.stringify;a=b(a).val()||b(a).text();try{return"function"===typeof e&&(e=e(a)),"object"!==typeof c||g(c.options)!==g(d)||c.mask!==e}catch(n){}};b.fn.mask=function(a,e){e=e||{};var d=this.selector,c=b.jMaskGlobals,g=c.watchInterval,c=e.watchInputs||c.watchInputs,n=function(){if(z(this,a,e))return b(this).data("mask",new y(this,a,e))};b(this).each(n);d&&""!==d&&c&&(clearInterval(b.maskWatchers[d]),b.maskWatchers[d]=setInterval(function(){b(document).find(d).each(n)},
g));return this};b.fn.masked=function(a){return this.data("mask").getMaskedVal(a)};b.fn.unmask=function(){clearInterval(b.maskWatchers[this.selector]);delete b.maskWatchers[this.selector];return this.each(function(){var a=b(this).data("mask");a&&a.remove().removeData("mask")})};b.fn.cleanVal=function(){return this.data("mask").getCleanVal()};b.applyDataMask=function(a){a=a||b.jMaskGlobals.maskElements;(a instanceof b?a:b(a)).filter(b.jMaskGlobals.dataMaskAttr).each(A)};var p={maskElements:"input,td,span,div",
dataMaskAttr:"*[data-mask]",dataMask:!0,watchInterval:300,watchInputs:!0,useInput:function(a){var b=document.createElement("div"),d;a="on"+a;d=a in b;d||(b.setAttribute(a,"return;"),d="function"===typeof b[a]);return d}("input"),watchDataMask:!1,byPassKeys:[9,16,17,18,36,37,38,39,40,91],translation:{0:{pattern:/\d/},9:{pattern:/\d/,optional:!0},"#":{pattern:/\d/,recursive:!0},A:{pattern:/[a-zA-Z0-9]/},S:{pattern:/[a-zA-Z]/}}};b.jMaskGlobals=b.jMaskGlobals||{};p=b.jMaskGlobals=b.extend(!0,{},p,b.jMaskGlobals);
p.dataMask&&b.applyDataMask();setInterval(function(){b.jMaskGlobals.watchDataMask&&b.applyDataMask()},p.watchInterval)});

@ -62,6 +62,7 @@
.select-box-results input[type=checkbox] {
margin: 0 5px 0 5px;
pointer-events: none;
}
.select-box-results .header {
@ -163,7 +164,7 @@ button.button-add {
.button-add {
position: absolute;
top: 54px;
bottom: -30px;
right: 0;
z-index: 999;
font-family: Myriad;
@ -180,8 +181,13 @@ button.button-add {
}
.select-box-results .button-add{
bottom: inherit;
}
.highlight {
color: #FF0029;
pointer-events: none;
}
#component-preloader {

@ -1,6 +1,6 @@
.selected-container {
min-height: 40px;
padding-bottom: 20px;
/*padding-bottom: 20px;*/
}
.selected-container .selected-element {

@ -4,6 +4,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
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; }; }();
@ -82,8 +83,11 @@ exports.default = NoTreeSelect;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
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 _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 _desc, _value, _class; // `
var _DataTree = require('./data/DataTree');
@ -94,15 +98,48 @@ var _NoTreeData = require('./data/NoTreeData');
var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
var _decorators = require('./decorators');
var _decorators2 = _interopRequireDefault(_decorators);
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 _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var tmpl_selectedElement = function tmpl_selectedElement(header, name, id) {
return '\n <div class="selected-element">\n <div class="header">\n ' + header + '\n </div>\n <div class="name">\n ' + name + '\n </div>\n <span data-id="' + id + '" class="icon-remove"></span>\n </div>\n';
};
var SelectedContainer = function () {
var SelectedContainer = (_class = function () {
function SelectedContainer($container, _ref) {
var _this = this;
@ -119,6 +156,7 @@ var SelectedContainer = function () {
this.elements_id = []; // [spec_id, spec_id, ...]
this.onlyOne = onlyOne;
var self = this;
this.$self.hide();
obj.dataPromise.then(function (data) {
_this.dataTree = noTree ? new _NoTreeData2.default(data.results) : new _DataTree2.default(data.results);
@ -132,15 +170,27 @@ var SelectedContainer = function () {
value: function restoreElements() {
var self = this;
if (this.$input && this.$input.val()) {
var data = this.$input.val().split(',').filter(function (el) {
console.log(" restore 1) ", this.$input.val());
console.log(" restore 2) ", this.$input.val().replace(/[\[\]\'\'\"\"]/g, ''));
// console.log(" restore 2) alter ", JSON.parse(this.$input.val()));
var clearString = this.$input.val().replace(/[\[\]\'\'\"\"]/g, '');
var data = clearString.split(',').filter(function (el) {
return el;
});
console.log(" restore 3) ", data);
this.elements_id = [];
if (this.$input) this.$input.val(this.elements_id.join(','));
data.forEach(function (el) {
return self.add(el);
});
}
}
}, {
key: 'on',
value: function on(methodName, func) {
this[methodName] = this[methodName].bind(this, { func: func, bindFunc: true });
}
}, {
key: '_removeById',
value: function _removeById(id) {
@ -161,6 +211,7 @@ var SelectedContainer = function () {
var spec_id = $(e.target).data("id");
this._removeById(spec_id);
if (this.$input) this.$input.val(this.elements_id.join(','));
if (!this.elements_id.length) this.$self.hide();
e.preventDefault();
}
}, {
@ -185,10 +236,14 @@ var SelectedContainer = function () {
this.$self.append(SelectedContainer.getTemplate(header || "&nbsp;", name, id));
this.btn_remove = this.$self.find('.icon-remove');
this.btn_remove.on("click", this.remove.bind(self));
if (this.elements_id.length) this.$self.show();
}
}, {
key: 'add',
value: function add(_id, max_len) {
console.log("id = ", _id);
// console.log("this = ", this);
// console.log("this.elements_id = ", this.elements_id);
var id = Number(_id);
var self = this;
if (this.onlyOne) {
@ -238,16 +293,16 @@ var SelectedContainer = function () {
}]);
return SelectedContainer;
}();
}(), (_applyDecoratedDescriptor(_class.prototype, 'remove', [_decorators2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'remove'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'add', [_decorators2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'add'), _class.prototype)), _class);
exports.default = SelectedContainer;
},{"./data/DataTree":5,"./data/NoTreeData":6}],3:[function(require,module,exports){
},{"./data/DataTree":5,"./data/NoTreeData":6,"./decorators":7}],3:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
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; }; }();
@ -341,10 +396,6 @@ var TreeSelect = function (_AbsBaseSelect) {
}, {
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();
@ -1095,6 +1146,86 @@ var NoTreeData = function () {
exports.default = NoTreeData;
},{}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = onBind;
function onBind(target, name, descriptor) {
var method = descriptor.value;
descriptor.value = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var binds = [];
args = Array.from(args);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = args.slice()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var arg = _step.value;
// console.log("onBind -->", typeof arg, "arg = ", arg);
// console.log("arg.func -->", typeof arg.originalEvent);
// typeof arg === 'object' && !(arg.originalEvent)
if (arg.bindFunc) {
binds.push(arg);
args.splice(args.indexOf(arg), 1);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
method.apply(this, args);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = binds[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var bind = _step2.value;
bind.func.bind(this)();
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return this;
};
}
// export {onBind};
},{}],8:[function(require,module,exports){
'use strict';
var _SelectedContainer = require('./SelectedContainer');
@ -1159,9 +1290,33 @@ $(function () {
var sb_loc_1 = new _TreeSelect2.default($('#sb-location-2'), { obj: sb_loc_main });
var sb_loc_2 = new _TreeSelect2.default($('#sb-location-3'), { obj: sb_loc_main });
// Убираем кнопки add-options, блокирем поиск, меняем подсказки
sb_loc_main.dataPromise.then(function () {
sb_loc_1.$buttonAddOptions.remove();
sb_loc_main.$buttonAddOptions.remove();
sb_loc_main.$searchInput.prop("readonly", true);
sb_loc_1.$searchInput.prop("readonly", true);
sb_loc_2.$searchInput.prop("readonly", true);
sb_loc_main.$searchInput.prop("placeholder", "Выберите");
sb_loc_1.$searchInput.prop("placeholder", "Выберите");
sb_loc_2.$searchInput.prop("placeholder", "Выберите");
});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
blockNonEmpty(sb_loc_main, select_loc);
}
function blockNonEmpty(select, container) {
container.on("add", function () {
select.$searchInput.parent().append("<div class='simple-select fill'>Местоположение выбрано</div>");
select.$searchInput.hide();
});
container.on("remove", function () {
select.$searchInput.siblings('div.simple-select').remove();
select.$searchInput.show();
});
}
createFilterSpecs('/api/specializations_flat');
@ -1170,4 +1325,4 @@ $(function () {
createFilerLocations('/api/locations_flat');
});
},{"./NoTreeSelect":1,"./SelectedContainer":2,"./TreeSelect":3}]},{},[7]);
},{"./NoTreeSelect":1,"./SelectedContainer":2,"./TreeSelect":3}]},{},[8]);

@ -1,6 +1,7 @@
// `
import DataTree from './data/DataTree'
import NoTreeData from './data/NoTreeData'
import onBind from './decorators'
let tmpl_selectedElement = (header, name, id) =>
`
@ -22,6 +23,7 @@ export default class SelectedContainer {
this.elements_id = []; // [spec_id, spec_id, ...]
this.onlyOne = onlyOne;
const self = this;
this.$self.hide();
obj.dataPromise
.then(
@ -40,8 +42,11 @@ export default class SelectedContainer {
restoreElements() {
const self = this;
if (this.$input && this.$input.val()) {
let data = this.$input.val().split(',').filter((el) => el);
let clearString = this.$input.val().replace(/[\[\]\'\'\"\"]/g, '');
let data = clearString.split(',').filter((el) => el);
this.elements_id = [];
if (this.$input) this.$input.val(this.elements_id.join(','));
data.forEach((el) => self.add(el));
}
}
@ -65,6 +70,10 @@ export default class SelectedContainer {
return str_chain;
}
on(methodName, func) {
this[methodName] = this[methodName].bind(this, {func, bindFunc: true});
}
_removeById(id) {
let index = this.elements_id.indexOf(id);
if (index >= 0) {
@ -77,11 +86,12 @@ export default class SelectedContainer {
console.log("Error loading data -->", error);
}
@onBind
remove(e) {
let spec_id = $(e.target).data("id");
this._removeById(spec_id);
if (this.$input) this.$input.val(this.elements_id.join(','));
if (!this.elements_id.length) this.$self.hide();
e.preventDefault();
}
@ -104,8 +114,10 @@ export default class SelectedContainer {
this.$self.append(SelectedContainer.getTemplate(header || "&nbsp;", name, id));
this.btn_remove = this.$self.find('.icon-remove');
this.btn_remove.on("click", this.remove.bind(self));
if (this.elements_id.length) this.$self.show();
}
@onBind
add(_id, max_len) {
const id = Number(_id);
let self = this;

@ -0,0 +1,24 @@
export default function onBind(target, name, descriptor) {
const method = descriptor.value;
descriptor.value = function (...args) {
let binds = [];
args = Array.from(args);
for (let arg of args.slice()) {
// console.log("onBind -->", typeof arg, "arg = ", arg);
// console.log("arg.func -->", typeof arg.originalEvent);
// typeof arg === 'object' && !(arg.originalEvent)
if (arg.bindFunc) {
binds.push(arg);
args.splice(args.indexOf(arg), 1);
}
}
method.apply(this, args);
for (let bind of binds) {
bind.func.bind(this)();
}
return this;
}
}
// export {onBind};

@ -51,10 +51,34 @@ $(function () {
let sb_loc_1 = new TreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new TreeSelect($('#sb-location-3'), {obj: sb_loc_main});
// Убираем кнопки add-options, блокирем поиск, меняем подсказки
sb_loc_main.dataPromise.then(()=>{
sb_loc_1.$buttonAddOptions.remove();
sb_loc_main.$buttonAddOptions.remove();
sb_loc_main.$searchInput.prop("readonly", true);
sb_loc_1.$searchInput.prop("readonly", true);
sb_loc_2.$searchInput.prop("readonly", true);
sb_loc_main.$searchInput.prop("placeholder", "Выберите");
sb_loc_1.$searchInput.prop("placeholder", "Выберите");
sb_loc_2.$searchInput.prop("placeholder", "Выберите");
});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
blockNonEmpty(sb_loc_main, select_loc);
}
function blockNonEmpty(select, container) {
container.on("add", () => {
select.$searchInput.parent().append("<div class='simple-select fill'>Местоположение выбрано</div>");
select.$searchInput.hide();
});
container.on("remove", () => {
select.$searchInput.siblings('div.simple-select').remove();
select.$searchInput.show();
});
}
createFilterSpecs('/api/specializations_flat');

@ -15,6 +15,8 @@ $(function () {
$slide.toggleClass("active");
});
//CUSTOM-CHECKBOX
function tuneCheckBoxes($boxes) {
let currentState = $boxes.find("input").prop("checked") ? 'checked' : 'not-checked';
$boxes.find("div").hide();
@ -31,6 +33,40 @@ $(function () {
return false;
});
// CUSTOM-SELECT
let $select_container = $('.custom-select');
let $sc_headers = $select_container.find('.simple-select');
let $sc_options = $select_container.find('.select-box-options');
$sc_options.hide();
$sc_headers.on("click", function (e) {
$(e.target).siblings('.select-box-options').show();
});
let $options = $sc_options.find('li');
$options.on("click", function (e) {
const target = $(e.target);
let header = target.closest('.select-box-options').siblings('.simple-select');
let data = target.closest('.select-box-options').siblings('input[type=hidden]');
header.val(target.html());
data.val(target.data("id"));
// $sc_data.val($(e.target).data("id"));
$sc_options.hide();
e.preventDefault()
});
$(document).click(function (event) {
//FIXME: запомнить на ком был клик, и не закрывать именно его
if ($(event.target).closest($select_container).length) {
return;
}
$sc_options.hide();
//...
});
//* Edn CUSTOM SELECT
// $("#myBtn").click(function () {
// $('<div class="alert alert-success alert-dismissable">' +

@ -9,6 +9,7 @@
"author": "Booblegum",
"license": "ISC",
"devDependencies": {
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.18.0",
"babelify": "^7.3.0"
}

@ -22,27 +22,33 @@ body {
margin-top: 30px;
}
.custom-check{
.custom-check {
cursor: pointer;
display: inline-block
display: inline-block;
width: 100%;
}
.header{
.header {
font-size: 12pt;
color: black;
}
.custom-check .checked{
.block-header {
display: inline-block;
padding-top: 10px;
}
.custom-check .checked {
background: url("../img/checkbox_Check.png.png") no-repeat center;
background-size: 210px 51px;
width: 210px;
background-size: 100% 51px;
width: 100%;
height: 51px;
}
.custom-check .not-checked {
background: url("../img/checkbox_notCheck.png") no-repeat center;
background-size: 210px 51px;
width: 210px;
background-size: 100% 51px;
width: 100%;
height: 51px;
}
@ -62,15 +68,18 @@ body {
transition: all 0.3s ease-out;
}
button.resButton:focus {outline:0;}
button.resButton:focus {
outline: 0;
}
.flex {
display: flex;
}
.flex .header{
.flex .header {
padding-right: 10px;
}
.header .fa {
padding-left: 3px;
color: #5e5e5e;

@ -42,6 +42,78 @@ class ContractorResumeFilesForm(forms.ModelForm):
)
class UserProfileEditFullForm(forms.ModelForm):
gender = forms.ChoiceField(
choices=GENDERS,
widget=forms.RadioSelect,
required=False,
)
contractor_status = forms.ChoiceField(
choices=User.STATUSES,
widget=forms.RadioSelect,
required=False,
)
live_image = forms.ModelChoiceField(
queryset=LiveImageUpload.objects.all(),
required=False,
)
class Meta:
model = User
fields = (
'id',
'avatar',
'first_name',
'last_name',
'patronym',
'location',
'contractor_specializations', # Специализации
'contractor_building_classifications', # Классификация зданий
'contractor_construction_types', # Вид строительства
'cro',
# Общая информация
'date_of_birth',
'gender',
'contractor_status',
'skype',
'website',
'phone',
'phone2',
# Финансовая информация
# ...
)
widgets = {
# TODO: Use common format with jQueryUI Datepicker:
'date_of_birth': forms.TextInput(attrs={'class': 'datepicker box-sizing simple-input'}),
'contractor_status': forms.Select(attrs={'class': 'simple-select'})
}
def __init__(self, *args, **kwargs):
if kwargs.get("request"): self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
# def clean_location(self):
# data = self.cleaned_data['location']
# return data
def clean_contractor_specializations(self):
data = self.cleaned_data['contractor_specializations']
return data
def get_gender_display(self):
for gender in GENDERS:
if gender[0] == self.initial['gender']:
return gender[1]
def get_status_display(self):
for status in User.STATUSES:
if status[0] == self.initial['contractor_status']:
return status[1]
class UserProfileEditForm(forms.ModelForm):
gender = forms.ChoiceField(
choices=GENDERS,

@ -2,7 +2,19 @@
padding: 43px 25px 40px 25px;
}
.simple-input {
.avatarInset {
width: 200px;
height: 200px;
}
.avatar {
width: 220px;
height: 220px;
padding: 10px;
}
.simple-input, .simple-select {
height: 51px;
width: 100%;
border: 1px solid #cccccc;
@ -12,6 +24,24 @@
margin-bottom: -1px;
}
.simple-select select {
background-color: darkgray;
}
.simple-select {
display: flex;
align-items: center;
text-align: center;
}
.simple-select.fill{
background-color: #F2F2F2;
}
.simple-select .text{
color: #a3a3a3;
}
.toggle .btn {
padding: 14px 20px;
border-radius: 40px;
@ -29,24 +59,22 @@
/* СУПЕР-костыльная кнопка. Не прикасаться!*/
.upload-new {
width: 75%;
width: 60%;
height: 30px;
overflow: hidden;
cursor: pointer;
/*float: left;*/
/*margin: 0 0 10px 0;*/
border-radius: 40px;
border: 1px solid #FF0029;
}
.upload-new:hover {
.upload-new:hover, .btn-simple:hover {
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
-webkit-transform: scale(1.04);
-moz-transform: scale(1.04);
transform: scale(1.04);
}
.upload-new {
.upload-new, .btn-simple {
transition: all 0.3s;
cursor: pointer;
}
@ -64,9 +92,9 @@
text-transform: uppercase;
margin: -30px 0 0 0;
/*padding: 0 5px 0 5px;*/
font-size: 12px;
font-size: 10px;
text-align: center;
font-family: Arial-MT-Regular;
font-family: Miriad;
}
/** Конец супер-костыля**/
@ -80,7 +108,7 @@
.info {
background-color: #F2F2F2;
padding: 60px 40px;
padding: 50px 40px;
margin-top: 20px;
}
@ -89,8 +117,28 @@
padding: 10px 15px;
border: 1px solid #FF0029;
color: black;
background: none;
font-family: Miriad;
}
/*.btn-simple:hover {*/
/*box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);*/
/*-webkit-transform: scale(1.04);*/
/*-moz-transform: scale(1.04);*/
/*transform: scale(1.04);*/
/*}*/
.no-margin .selected-element {
margin: 0;
}
.-live-image-avatar-upload-container .-position-relative-parent {
position: relative
}
.-live-image-avatar-upload-container .-live-image-delete {
position: absolute;
top: 0;
right: 0;
background-color: white;
}

@ -1,5 +1,6 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% load thumbnail %}
{% block head_css %}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'>
<link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'>
@ -10,14 +11,9 @@
<link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'>
<link rel='stylesheet' href='{% static "css/custom-checkboxes.css" %}'>
{% endblock %}
{% load thumbnail %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
{# <form method="POST" enctype="multipart/form-data" novalidate>#}
{# {% csrf_token %}#}
{##}
{# {% if request.user.is_customer %}#}
{# <input type="hidden" name="next"#}
{# value="{% url 'users:customer-profile-open-projects' pk=pk %}">#}
@ -26,232 +22,279 @@
{# {% endif %}#}
<div class="container mainScore">
<div class="row mainContent">
<div class="col-lg-12">
<div class="row row-eq-height">
<div class="col-lg-3">
<div class="avatar" style="float: none">
<div class="avatarInset -position-relative-parent">
<a href="#" onclick="return false" class="btn close -live-image-delete"
style="display: none">&times;</a>
{# {% thumbnail request.user.avatar "235x224" crop="center" as avatar %}#}
{# {% if request.user.avatar %}#}
{# <img src="{{ avatar.url }}" alt="profile-image" class="-avatar-image">#}
{# {% else %}#}
<img src="{% static 'img/avatar_default.png' %}" alt="profile-image"
class="-avatar-image">
{# {% endif %}#}
{# {% endthumbnail %}#}
<form method="POST" enctype="multipart/form-data" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}">
<div class="col-lg-12">
<div class="row row-eq-height">
<div class="col-lg-3 -live-image-avatar-upload-container">
<div class="avatar" style="float: none">
<div class="avatarInset -position-relative-parent">
<a href="#" onclick="return false" class="btn close -live-image-delete"
style="display: none">&times;</a>
{% if request.user.avatar %}
{% thumbnail request.user.avatar "235x224" crop="center" as avatar %}
<img src="{{ avatar.url }}" alt="profile-image" class="-avatar-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image"
class="-avatar-image">
{% endif %}
</div>
</div>
</div> <!-- avatar -->
<div style="margin-top: 15px">
<div class="upload-new">
<input type="file" name="image" class="-live-image-upload">
<div style="margin-top: 15px">
<div class="upload-new">
{# <div class="upload2 up-l1">#}
<input type="file" name="image" class="-live-image-upload">
<p>Загрузить фотографию</p>
<p>Загрузить фотографию</p>
{# </div>#}
</div>
</div>
<div {% if not TESTING %}style="display: none"{% endif %}>
<input type="text" name="live_image" class="-live-image-id">
</div>
</div>
</div>
<div class="col-lg-9">
<div class="row">
<div class="col-lg-12">
<div class="bottom-line">
<div class="col-lg-9">
<div class="row">
<div class="col-lg-12">
<div class="bottom-line">
<span class="header">
Параметры заполнения прифиля влияют на фильтр поиска специалистов, ранжирования в списке
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12" style="padding-bottom: 10px">
<span class="header">
<div class="row">
<div class="col-lg-12" style="padding-bottom: 10px">
<span class="header block-header">
Личная информация <i class="fa fa-question-circle-o" aria-hidden="true"
title=""></i>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<input name="first_name" class="simple-input" placeholder="Фамилия">
</div>
<div class="col-lg-4">
<input name="last_name" class="simple-input" placeholder="Имя">
</div>
<div class="col-lg-4">
<input name="patronym" class="simple-input" placeholder="Отчество">
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-1">
<div class="row">
<div class="col-lg-4">
<input value="{{ form.last_name.value }}" name="{{ form.last_name.html_name }}"
class="simple-input" placeholder="Фамилия">
</div>
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-2">
<div class="col-lg-4">
<input value="{{ form.first_name.value }}" name="{{ form.first_name.html_name }}"
class="simple-input" placeholder="Имя">
</div>
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-3">
<div class="col-lg-4">
<input value="{{ form.patronym.value }}" name="{{ form.patronym.html_name }}"
class="simple-input" placeholder="Отчество">
</div>
</div>
<div class="col-lg-4">
<div class="selected-container vertical-child no-margin" id="selected-location">
<div class="header">&nbsp;</div>
<input type="hidden" name="location"
value="{{ location }}">
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-1">
</div>
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-2">
</div>
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-3">
</div>
</div>
<div class="col-lg-8">
<div class="selected-container horizontal vertical-child no-margin"
id="selected-location">
<div class="header">&nbsp;</div>
<input type="hidden" name="location"
value="{{ form.location.value }}">
</div>
</div>
</div>
</div>
</div>
</div> <!-- top -->
</div> <!-- top -->
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-offset-3 col-lg-9">
<div class="top-line">
<span class="header">
<div class="row">
<div style="padding-bottom: 10px" class="col-lg-12">
<div class="row">
<div class="col-lg-offset-3 col-lg-9">
<div class="top-line">
<span class="header block-header">
Мой опыт работы в проектировании / дизайне / сопровождении проектной документации
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="" id="select-box-1">
<div class="row">
<div class="col-lg-12">
<div class="" id="select-box-1">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
</div>
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
</div>
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="specialization"
value="{{ specialization }}">
<div class="row">
<div class="col-lg-12">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.contractor_specializations.html_name }}"
value="{{ form.contractor_specializations.value }}">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
</div>
<div class="vertical-child" id="sb-building-sub-classification">
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden"
name="{{ form.contractor_building_classifications.html_name }}"
value="{{ form.contractor_building_classifications.value }}">
</div>
</div>
<div class="vertical-child" id="sb-building-sub-classification">
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden" name="{{ form.contractor_construction_types.html_name }}"
value="{{ form.contractor_construction_types.value }}">
</div>
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden" name="building_classification"
value="{{ building_classification }}">
<div class="col-lg-3">
<div class="select-box-header vertical-child">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span>
<i class="fa fa-question-circle-o" aria-hidden="true"
title="bla-bla-bla..."></i>
</div>
<div class="custom-check">
<div class="checked"></div>
<div style="display: none" class="not-checked"></div>
<input name="{{ form.cro.html_name }}" type="checkbox" hidden
{% if form.cro.value %} checked{% endif %}>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden" name="construction_type"
value="{{ construction_type }}">
</div>
</div> <!-- center -->
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<div class="top-line" style="padding-top: 15px">
<div class="btn-group toggle" role="group" aria-label="...">
<a style="z-index: 0" href="{% url 'users:user-profile-edit' pk=pk %}"
role="button"
class="btn btn-default active">Общая информация</a>
<a href="{% url 'users:user-financial-info-edit' pk=pk %}"
class="btn btn-default" role="button">Финансовая информация</a>
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="select-box-header vertical-child">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span>
<i class="fa fa-question-circle-o" aria-hidden="true"
title="bla-bla-bla..."></i>
<div class="row info">
<div class="col-lg-3">
<div class="header"> Дата рождения</div>
<div class="birth_edit_dat">
{{ form.date_of_birth }}
</div>
</div>
<div class="col-lg-3">
<div style="position: relative" class="select-box-container custom-select"
id="gender">
<div class="select-box-header">
<div class="header">Пол</div>
</div>
<input class="simple-select" placeholder="Выберите"
value="{{ form.get_gender_display }}" readonly>
<input type="hidden" name="{{ form.gender.html_name }}" value="{{ form.gender.value }}">
<div class="select-box-options" style="width: 100%; display: none">
<div style="min-width: inherit" class="box-wrapper">
<ul>
{% for id, text in form.gender.field.choices %}
<li data-id="{{ id }}">{{ text }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="custom-check">
<div class="checked"></div>
<div style="display: none" class="not-checked"></div>
<input name="cro" type="checkbox" hidden {% if cro %} checked{% endif %}>
</div>
</div>
</div>
</div>
</div> <!-- center -->
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<div class="top-line" style="padding-top: 15px">
<div class="btn-group toggle" role="group" aria-label="...">
<a href="{% url 'users:user-profile-edit' pk=pk %}" role="button"
class="btn btn-default">Общая информация</a>
<a href="{% url 'users:user-financial-info-edit' pk=pk %}"
class="btn btn-default" role="button">Финансовая информация</a>
</div>
<div class="col-lg-3">
<div style="position: relative" class="select-box-container custom-select"
id="gender">
<div class="select-box-header">
<div class="header">Статус</div>
</div>
<input class="simple-select" placeholder="Выберите"
value="{{ form.get_status_display }}" readonly>
<input type="hidden" name="{{ form.contractor_status.html_name }}" value="{{ form.contractor_status.value }}">
<div class="select-box-options" style="width: 100%; display: none">
<div style="min-width: inherit" class="box-wrapper">
<ul>
{% for id, text in form.contractor_status.field.choices %}
<li data-id="{{ id }}">{{ text }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="row info">
<div class="col-lg-3">
<div class="header"> Дата рождения</div>
<div class="birth_edit_dat">
{{ form.date_of_birth }}
</div>
</div>
<div class="col-lg-3">
<div class="header">Пол</div>
<div class="checkbox">
<label class="rad">
<input type="radio" name="gender" value="male" id="male">
<i></i>Мужской
</label>
<label class="rad">
<input type="radio" name="gender" value="female" id="female">
<i></i>Женский
</label>
<div class="col-lg-3">
<div class="header">Skype</div>
<input name="{{ form.skype.html_name }}" class="simple-input" placeholder="skype id"
value="{{ form.skype.value }}">
</div>
<div class="clearfix visible-lg"></div>
<div class="col-lg-3 vertical-child">
<div class="header">Сайт</div>
<input name="{{ form.website.html_name }}" class="simple-input"
placeholder="example.com"
value="{{ form.website.value }}">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Телефон</div>
<input name="{{ form.phone.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Второй телефон</div>
<input name="{{ form.phone2.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone2.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="СОХРАНИТЬ">
</div>
</div>
<div class="col-lg-3">
<div class="header">Статус</div>
{{ form.contractor_status }}
</div>
<div class="col-lg-3">
<div class="header">Skype</div>
<input name="skype" class="simple-input" placeholder="skype id">
</div>
<div class="clearfix visible-lg"></div>
<div class="col-lg-3 vertical-child">
<div class="header">Сайт</div>
<input name="site" class="simple-input" placeholder="example.com">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Телефон</div>
<input name="phone-1" class="simple-input" placeholder="+7 909 999 00 00">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Второй телефон</div>
<input name="phone-2" class="simple-input" placeholder="+7 909 999 00 00">
</div>
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<a href="#" class="btn btn-simple">СОХРАНИТЬ</a>
</div>
</div>
</div>
</div> <!-- bottom -->
</div>
</div> <!-- bottom -->
</div>
</form>
</div>
<div class="row">
{% include 'partials/footer.html' %}
@ -263,5 +306,11 @@
{% block js_block %}
{{ block.super }}
<script src='{% static "lib/proekton-components/js/build/init_user_profile.js" %}'></script>
<script src='{% static "projects-filter.js" %}'></script>
<script src='{% static "projects-filter.js" %}'></script>
<script src='{% static "js/jquery.mask.min.js" %}'></script>
<script>
$(function () {
$('.phone').mask('+7(000)000-00-00');
})
</script>
{% endblock %}

@ -18,14 +18,14 @@ from .views import (
TeamProfileView,
UserFinancialInfoEditView,
UserProfileEditView,
UserProfileEditViewPlus,
UserProfileEditViewFull,
)
app_name = 'users'
urlpatterns = [
urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditView.as_view(), name='user-profile-edit'),
urls.url(r'^(?P<pk>\d+)/edit_plus/$', UserProfileEditViewPlus.as_view(), name='user-profile-edit'),
urls.url(r'^(?P<pk>\d+)/edit_full/$', UserProfileEditViewFull.as_view(), name='user-profile-edit'),
urls.url(r'^(?P<pk>\d+)/financial-info/edit/$', UserFinancialInfoEditView.as_view(),
name='user-financial-info-edit'),

@ -1,5 +1,6 @@
import itertools
import json
import re
from pprint import pformat
import natsort
@ -36,6 +37,7 @@ from .forms import (
UserFinancialInfoEditForm,
UserProfileBasicInfoEditForm,
UserProfileEditForm,
UserProfileEditFullForm,
UserProfileExperienceEditForm,
)
@ -100,25 +102,27 @@ class UserProfileEditView(BaseMixin, View):
return render(request, self.template_name, context)
class UserProfileEditViewPlus(BaseMixin, View):
form_class = UserProfileEditForm
class UserProfileEditViewFull(BaseMixin, View):
form_class = UserProfileEditFullForm
template_name = 'user_profile_edit_new.html'
# def dispatch(self, request, *args, **kwargs):
# if request.resolver_match.url_name == 'user-experience-edit':
# if not request.user.is_contractor():
# raise PermissionDenied
# self.form_class = UserProfileExperienceEditForm
# request.experience_edit = True
# if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
# return super().dispatch(request, *args, **kwargs)
# else:
# raise PermissionDenied
def dispatch(self, request, *args, **kwargs):
if request.resolver_match.url_name == 'user-experience-edit':
if not request.user.is_contractor():
raise PermissionDenied
self.form_class = UserProfileExperienceEditForm
request.experience_edit = True
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request, instance=request.user)
form = self.form_class(instance=request.user)
# import code
# code.interact(local=dict(globals(), **locals()))
context.update({'form': form})
return render(request, self.template_name, context)
@ -126,8 +130,14 @@ class UserProfileEditViewPlus(BaseMixin, View):
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
specs = request.POST.getlist('contractor_specializations')
request.POST.setlist('contractor_specializations', _.compact(specs)) # Ignore empty input values
specs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_specializations'))))
request.POST.setlist('contractor_specializations', specs)
builds = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_building_classifications'))))
request.POST.setlist('contractor_building_classifications', builds)
constructs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_construction_types'))))
request.POST.setlist('contractor_construction_types', constructs)
form = self.form_class(request.POST, request=request, instance=request.user)

Loading…
Cancel
Save