Specialization select changed logic. Done for project creation, editing, filtration and for contractor filtration

remotes/origin/PR-39
ArturBaybulatov 9 years ago
parent 3c3a299152
commit 28f27995f5
  1. 1
      archilance/settings/base.py
  2. 146
      assets/index.js
  3. 2
      assets/js/chat.js
  4. 25
      projects/migrations/0043_auto_20160922_1705.py
  5. 11
      projects/serializers.py
  6. 40
      projects/templates/customer_project_create.html
  7. 42
      projects/templates/customer_project_edit.html
  8. 40
      projects/templates/project_filter.html
  9. 3
      projects/views.py
  10. 5
      specializations/serializers.py
  11. 2
      templates/partials/base.html
  12. 2
      users/forms.py
  13. 24
      users/templates/contractor_filter.html
  14. 20
      work_sell/migrations/0017_auto_20160922_1705.py

@ -280,7 +280,6 @@ REST_FRAMEWORK = {
], ],
'PAGE_SIZE': API_PAGE_SIZE, 'PAGE_SIZE': API_PAGE_SIZE,
'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters 'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters
} }

@ -23,6 +23,12 @@ $('[data-tooltip]').tooltip({
// Specialization select ----------------------------------- // Specialization select -----------------------------------
@ -63,18 +69,65 @@ $('[data-tooltip]').tooltip({
} }
$('.-spec-select-container').each(function(i, container) { $('.-spec-work-type-combo-container').each(function(i, container) {
var $container = $(container) var $container = $(container)
var $specSelects = $container.find('.-spec-select') var $specSelects = $container.find('.-spec-select')
var $chosenSpecId = $container.find('.-chosen-spec-id').first() var $chosenSpecId = $container.find('.-chosen-spec-id').first()
var $specSelect1 = $container.find('.-spec-select-level-1').first() var $specSelect1 = $container.find('.-spec-select-level-1').first()
window.select = $specSelect1
var $specSelect2 = $container.find('.-spec-select-level-2').first() var $specSelect2 = $container.find('.-spec-select-level-2').first()
var $specSelect3 = $container.find('.-spec-select-level-3').first() var $specSelect3 = $container.find('.-spec-select-level-3').first()
var $specSelect4 = $container.find('.-spec-select-level-4').first() var $specSelect4 = $container.find('.-spec-select-level-4').first()
var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4]
reinitSpecializationsByWorkType($specSelect1, null, $container)
var $workTypeSelect = $container.find('.-project-work-type-select-field').first()
if (!_.isEmpty($workTypeSelect)) {
var workTypeId = Number($workTypeSelect.find('option:selected').first().val()) || 1
$workTypeSelect.on('change', function($evt) {
var $that = $(this)
var workTypeId = Number($that.val())
reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) {
updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects)
})
})
} else {
var $workTypeRadios = $container.find('.-project-work-type-radios-container').first().find('input[type=radio]')
if (!_.isEmpty($workTypeRadios)) {
var workTypeId = Number($workTypeRadios.filter(':checked').val()) || 1
$workTypeRadios.on('change', function($evt) {
var $that = $(this)
var workTypeId = Number($that.val())
reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) {
updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects)
})
})
} else {
var workTypeId = 1
}
}
reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec_) {
updateSpecializationWidgets(null, $container, $chosenSpecId, specSelects)
})
var chosenSpecId = $chosenSpecId.val() var chosenSpecId = $chosenSpecId.val()
@ -88,15 +141,8 @@ $('[data-tooltip]').tooltip({
}) })
function reinitSpecializationsByWorkType($specSelect1, workTypeId, $container) { function reinitSpecializationsByWorkType(specSelects, workTypeId) {
var $chosenSpecId = $container.find('.-chosen-spec-id').first() return $.get('/api/specializations/?parent__name=_root')
var $specSelect2 = $container.find('.-spec-select-level-2').first()
var $specSelect3 = $container.find('.-spec-select-level-3').first()
var $specSelect4 = $container.find('.-spec-select-level-4').first()
var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4]
$.get('/api/specializations/?parent__name=_root')
.then(function(res) { .then(function(res) {
var rootSpecs = res.results var rootSpecs = res.results
@ -109,13 +155,21 @@ $('[data-tooltip]').tooltip({
var url = format('/api/specializations/?lft__gte=%s&rght__lte=%s', rootSpec.lft, rootSpec.rght) var url = format('/api/specializations/?lft__gte=%s&rght__lte=%s', rootSpec.lft, rootSpec.rght)
} }
$specSelect1.select2(_.merge(specSelectOptions, {ajax: {url: url}})) specSelects[0].select2(_.merge(specSelectOptions, {ajax: {url: url}}))
updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) specSelects[1].select2(_.merge(specSelectOptions, {ajax: {url: null}}))
specSelects[2].select2(_.merge(specSelectOptions, {ajax: {url: null}}))
specSelects[3].select2(_.merge(specSelectOptions, {ajax: {url: null}}))
// TODO: Hardcoded:
specSelects[0].select2('container').closest('.col-lg-3').css('display', workTypeId === 2 ? 'none' : 'block')
return rootSpec
}) })
} }
window.reinitSpecializationsByWorkType = reinitSpecializationsByWorkType
function updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) { function updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) {
return getSpecializationTree(specId).then(function(specs) { return getSpecializationTree(specId).then(function(specs) {
@ -137,19 +191,21 @@ $('[data-tooltip]').tooltip({
$chosenSpecId.val(specId) $chosenSpecId.val(specId)
specSelects[1].select2('container').css('display', !specLevel1 || _.isEmpty(specLevel1.children) ? 'none' : 'block') specSelects[1].select2('enable', Boolean(specLevel1 && !_.isEmpty(specLevel1.children)))
specSelects[2].select2('container').css('display', !specLevel2 || _.isEmpty(specLevel2.children) ? 'none' : 'block') specSelects[2].select2('enable', Boolean(specLevel2 && !_.isEmpty(specLevel2.children)))
specSelects[3].select2('container').css('display', !specLevel3 || _.isEmpty(specLevel3.children) ? 'none' : 'block') specSelects[3].select2('enable', Boolean(specLevel3 && !_.isEmpty(specLevel3.children)))
specializationTreeHasLevels(specId).then(function(haveLevels) {
specSelects[1].select2('container').css('display', haveLevels.level2 ? 'block' : 'none')
specSelects[2].select2('container').css('display', haveLevels.level3 ? 'block' : 'none')
specSelects[3].select2('container').css('display', haveLevels.level4 ? 'block' : 'none')
})
}) })
} }
}())
window.updateSpecializationWidgets = updateSpecializationWidgets
//function repopulateSpecializations() {
//
//}
}())
@ -903,6 +959,50 @@ function getLocationTree(locId) {
function specializationTreeHasLevels(specId) {
if (specId == null) {
var haveLevels = {
level2: true,
level3: true,
level4: true,
}
return $.when(haveLevels)
} else {
return $.get(format('/api/specializations/%s/', specId)).then(function(spec) {
return $.get(format('/api/specializations/?level=1&lft__lte=%s&rght__gte=%s', spec.lft, spec.rght)).then(function(res) {
var specTreeRoot = res.results[0]
var url_ = format('/api/specializations/?lft__gt=%s&rght__lt=%s&level=%s', specTreeRoot.lft, specTreeRoot.rght)
return $.when(
$.get(format(url_, 2)).then(function(res) {return res}),
$.get(format(url_, 3)).then(function(res) {return res}),
$.get(format(url_, 4)).then(function(res) {return res})
)
.then(function(resLvl1, resLvl2, resLvl3) {
var haveLevels = {
level2: !_.isEmpty(resLvl1.results),
level3: !_.isEmpty(resLvl2.results),
level4: !_.isEmpty(resLvl3.results),
}
return haveLevels
})
})
})
}
}
// Utils ----------------------------------------------- // Utils -----------------------------------------------

@ -29,7 +29,7 @@ window.confirm = function (message, callback, caption) {
var SocketHandler = function () { var SocketHandler = function () {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var url = 'ws://' + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-22 14:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0042_portfolio_work_type'),
]
operations = [
migrations.AlterField(
model_name='portfolio',
name='work_type',
field=models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1),
),
migrations.AlterField(
model_name='project',
name='work_type',
field=models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1),
),
]

@ -258,19 +258,20 @@ class PortfolioSerializer(ModelSerializer):
fields = ( fields = (
# 'answers', # 'answers',
'budget',
'building_classification', 'building_classification',
'construction_type', 'construction_type',
'location',
'photos',
'specialization',
'user',
'budget',
'currency', 'currency',
'description', 'description',
'id', 'id',
'location',
'name', 'name',
'photos',
'specialization',
'term', 'term',
'term_type', 'term_type',
'user',
'worksell', 'worksell',
) )

@ -17,7 +17,7 @@
<p class="titleScore">Новый заказ</p> <p class="titleScore">Новый заказ</p>
</div> </div>
<form action="{% url 'projects:customer-project-create' %}" method="POST" enctype="multipart/form-data" novalidate> <form action="{% url 'projects:customer-project-create' %}" method="POST" enctype="multipart/form-data" novalidate class="-spec-work-type-combo-container">
{% csrf_token %} {% csrf_token %}
<input type="hidden" id="extraFields" name="extra_fields" value=""> <input type="hidden" id="extraFields" name="extra_fields" value="">
@ -59,7 +59,7 @@
</div> </div>
<p class="type-work">Тип работы <span data-tooltip data-placement="{% tooltip_placement pk=6 %}" title="{% tooltip pk=6 %}" class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <span id="{% random_ident %}" class="-validation-error" style="color: red">{{ form.work_type.errors.as_text }}</span></p> <p class="type-work">Тип работы <span data-tooltip data-placement="{% tooltip_placement pk=6 %}" title="{% tooltip pk=6 %}" class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <span id="{% random_ident %}" class="-validation-error" style="color: red">{{ form.work_type.errors.as_text }}</span></p>
<div class="mail-block type-work-inset -project-work-type-selection-container"> <div class="mail-block type-work-inset -project-work-type-radios-container">
{% for id, text in form.work_type.field.choices %} {% for id, text in form.work_type.field.choices %}
<div class="inset-mb"> <div class="inset-mb">
<label> <label>
@ -89,7 +89,7 @@
<div class="col-lg-3"></div> <div class="col-lg-3"></div>
<div class="col-lg-3"></div>--> <div class="col-lg-3"></div>-->
</div> </div>
<div class="polsF1 disTab -spec-select-container"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div> </div>
@ -343,39 +343,5 @@
if (hash) if (hash)
window.location.hash = hash window.location.hash = hash
}()) }())
// Load specialization choices by work type ---------------------------
;(function() {
var $specSelectContainer = $('.-spec-select-container').first()
var $specSelects = $specSelectContainer.find('.-spec-select')
var $chosenSpecId = $specSelectContainer.find('.-chosen-spec-id').first()
var $specSelect1 = $specSelectContainer.find('.-spec-select-level-1').first()
var $specSelect2 = $specSelectContainer.find('.-spec-select-level-2').first()
var $specSelect3 = $specSelectContainer.find('.-spec-select-level-3').first()
var $specSelect4 = $specSelectContainer.find('.-spec-select-level-4').first()
var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4]
var $radiosContainer = $('.-project-work-type-selection-container').first()
var $radios = $radiosContainer.find('input[type=radio][name={{ form.work_type.html_name }}]')
var workTypeId = Number($radios.filter(':checked').val()) || 1
reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer)
var chosenSpecId = $chosenSpecId.val()
if (chosenSpecId)
updateSpecializationWidgets(chosenSpecId, $specSelectContainer, $chosenSpecId, specSelects)
$radios.on('change', function($evt) {
var $that = $(this)
var workTypeId = Number($that.val())
reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer)
})
}())
</script> </script>
{% endblock %} {% endblock %}

@ -17,7 +17,7 @@
<p class="titleScore">Изменение проекта</p> <p class="titleScore">Изменение проекта</p>
</div> </div>
<form action="{% url 'projects:customer-project-edit' pk=pk %}" method="POST" enctype="multipart/form-data" novalidate> <form action="{% url 'projects:customer-project-edit' pk=pk %}" method="POST" enctype="multipart/form-data" novalidate class="-spec-work-type-combo-container">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}"> <input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}">
@ -69,7 +69,7 @@
</div> </div>
<p class="type-work">Тип работы <span id="{% random_ident %}" class="-validation-error" style="color: red">{{ form.work_type.errors.as_text }}</span></p> <p class="type-work">Тип работы <span id="{% random_ident %}" class="-validation-error" style="color: red">{{ form.work_type.errors.as_text }}</span></p>
<div class="mail-block type-work-inset -project-work-type-selection-container"> <div class="mail-block type-work-inset -project-work-type-radios-container">
{% for id, text in form.work_type.field.choices %} {% for id, text in form.work_type.field.choices %}
<div class="inset-mb"> <div class="inset-mb">
<label> <label>
@ -99,7 +99,7 @@
<div class="col-lg-3"></div> <div class="col-lg-3"></div>
<div class="col-lg-3"></div>--> <div class="col-lg-3"></div>-->
</div> </div>
<div class="polsF1 disTab -spec-select-container"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div> </div>
@ -360,41 +360,5 @@
if (hash) if (hash)
window.location.hash = hash window.location.hash = hash
}()) }())
// Load specialization choices by work type ---------------------------
;(function() {
var $specSelectContainer = $('.-spec-select-container').first()
var $specSelects = $specSelectContainer.find('.-spec-select')
var $chosenSpecId = $specSelectContainer.find('.-chosen-spec-id').first()
var $specSelect1 = $specSelectContainer.find('.-spec-select-level-1').first()
var $specSelect2 = $specSelectContainer.find('.-spec-select-level-2').first()
var $specSelect3 = $specSelectContainer.find('.-spec-select-level-3').first()
var $specSelect4 = $specSelectContainer.find('.-spec-select-level-4').first()
var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4]
var $radiosContainer = $('.-project-work-type-selection-container').first()
var $radios = $radiosContainer.find('input[type=radio][name={{ form.work_type.html_name }}]')
var workTypeId = Number($radios.filter(':checked').val()) || 1
reinitSpecializationsByWorkType($specSelects, workTypeId)
var chosenSpecId = $chosenSpecId.val()
if (chosenSpecId)
updateSpecializationWidgets(chosenSpecId, $specSelectContainer, $chosenSpecId, specSelects)
$radios.on('change', function($evt) {
console.log('Radio change')
var $that = $(this)
var workTypeId = $that.val()
reinitSpecializationsByWorkType($specSelects, workTypeId)
})
}())
</script> </script>
{% endblock %} {% endblock %}

@ -13,7 +13,7 @@
<form action="{% url 'projects:project-filter' %}" method="GET" novalidate> <form action="{% url 'projects:project-filter' %}" method="GET" novalidate>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="filter clearfix"> <div class="filter clearfix -spec-work-type-combo-container">
<div class="triangle1"></div> <div class="triangle1"></div>
@ -32,7 +32,7 @@
<div class="col-lg-9"></div> <div class="col-lg-9"></div>
</div> </div>
<div class="polsF1 disTab -spec-select-container"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div> </div>
@ -241,39 +241,3 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block js_block %}
<script>
// Load specialization choices by work type ---------------------------
;(function() {
var $specSelectContainer = $('.-spec-select-container').first()
var $specSelects = $specSelectContainer.find('.-spec-select')
var $chosenSpecId = $specSelectContainer.find('.-chosen-spec-id').first()
var $specSelect1 = $specSelectContainer.find('.-spec-select-level-1').first()
var $specSelect2 = $specSelectContainer.find('.-spec-select-level-2').first()
var $specSelect3 = $specSelectContainer.find('.-spec-select-level-3').first()
var $specSelect4 = $specSelectContainer.find('.-spec-select-level-4').first()
var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4]
var $workTypeSelect = $('.-project-work-type-select-field').first()
var workTypeId = Number($workTypeSelect.find('option:selected').first().val()) || 1
reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer)
var chosenSpecId = $chosenSpecId.val()
if (chosenSpecId)
updateSpecializationWidgets(chosenSpecId, $specSelectContainer, $chosenSpecId, specSelects)
$workTypeSelect.on('change', function($evt) {
var $that = $(this)
var workTypeId = Number($that.val())
reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer)
})
}())
</script>
{% endblock %}

@ -279,6 +279,7 @@ class ProjectFilterView(BaseMixin, View):
context = self.get_context_data(**_.merge({}, request.GET, kwargs)) context = self.get_context_data(**_.merge({}, request.GET, kwargs))
projects = Project.objects.filter(state='active') projects = Project.objects.filter(state='active')
manual_sort = None
if form.is_valid() and realty_form.is_valid(): if form.is_valid() and realty_form.is_valid():
ord = None ord = None
@ -333,8 +334,6 @@ class ProjectFilterView(BaseMixin, View):
elif last_order_by: elif last_order_by:
ord = last_order_by ord = last_order_by
manual_sort = None
if ord and ord == 'views': if ord and ord == 'views':
projects = natsort.natsorted(projects.all(), key=lambda p: p.hit_count.hits, reverse=reverse_order) projects = natsort.natsorted(projects.all(), key=lambda p: p.hit_count.hits, reverse=reverse_order)
manual_sort = True manual_sort = True

@ -29,12 +29,13 @@ class SpecializationSerializer(ModelSerializer):
fields = ( fields = (
'children', 'children',
'parent',
'projects',
'id', 'id',
'level', 'level',
'lft', 'lft',
'name', 'name',
'parent',
'projects',
'rght', 'rght',
'tree_id', 'tree_id',
) )

@ -86,7 +86,7 @@
if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) { if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var url = 'ws://' + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {

@ -193,7 +193,7 @@ class ContractorFilterForm(forms.Form):
work_type = forms.ChoiceField( work_type = forms.ChoiceField(
choices=tuple(itertools.chain((('',''),), Project.WORK_TYPES)), choices=tuple(itertools.chain((('',''),), Project.WORK_TYPES)),
widget=forms.Select(attrs={'class': 'selectpicker'}), widget=forms.Select(attrs={'class': 'selectpicker -project-work-type-select-field'}),
required=False, required=False,
) )

@ -18,14 +18,29 @@
<form action="{% url 'users:contractor-filter' %}" method="GET" novalidate> <form action="{% url 'users:contractor-filter' %}" method="GET" novalidate>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="filter clearfix"> <div class="filter clearfix -spec-work-type-combo-container">
<div class="triangle1"></div> <div class="triangle1"></div>
<div class="titleF1 disTab">
<div class="col-lg-3">Тип работы</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
{{ form.work_type }}
</div>
</div>
<div class="titleF1 disTab"> <div class="titleF1 disTab">
<div class="col-lg-3">Специализации</div> <div class="col-lg-3">Специализации</div>
</div> </div>
<div class="polsF1 disTab -spec-select-container"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div> </div>
@ -104,7 +119,6 @@
<div class="titleF1 disTab"> <div class="titleF1 disTab">
<div class="col-lg-3">Классификация здания</div> <div class="col-lg-3">Классификация здания</div>
<div class="col-lg-3">Тип работы</div>
<div class="col-lg-3">Вид строительства</div> <div class="col-lg-3">Вид строительства</div>
</div> </div>
@ -113,10 +127,6 @@
{{ form.building_classification }} {{ form.building_classification }}
</div> </div>
<div class="col-lg-3">
{{ form.work_type }}
</div>
<div class="col-lg-3"> <div class="col-lg-3">
{{ form.construction_type }} {{ form.construction_type }}
</div> </div>

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-22 14:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0016_worksell_work_type'),
]
operations = [
migrations.AlterField(
model_name='worksell',
name='work_type',
field=models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1),
),
]
Loading…
Cancel
Save