#ARC-15 Add sortable ajax view

remotes/origin/setup
Mukhtar 10 years ago
parent eb496b28c4
commit 205abceb2b
  1. 46
      projects/templates/comparison.html
  2. 2
      projects/urls.py
  3. 50
      projects/views.py

@ -15,7 +15,7 @@
<div class="triangle1"></div> <div class="triangle1"></div>
<p>{{ object }}</p> <p>{{ object }}</p>
<table class="compTable" id="compTable"> <table class="compTable" id="compTable">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th>Кандидат</th> <th>Кандидат</th>
@ -26,13 +26,13 @@
<th>Безопасные сделки</th> <th>Безопасные сделки</th>
<th>Решение</th> <th>Решение</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for cand in object.candidates.all %} {% for cand in object.candidates.all %}
<tr style="cursor:pointer" class="items[]_{{ cand.pk }}" data-class="items[]_{{ cand.pk }}"> <tr style="cursor:move;" class="items[]_{{ cand.pk }}" data-class="items[]_{{ cand.pk }}">
<td>{{ forloop.counter }}</td> <td>{{ cand.position }}</td>
<td> <td>
{{ cand.answer.contractor.get_full_name }} {{ cand.answer.contractor.username }} {{ cand.answer.author.username }}
</td> </td>
<td>{{ cand.answer.budget }} <i class="fa fa-rub"></i></td> <td>{{ cand.answer.budget }} <i class="fa fa-rub"></i></td>
@ -69,8 +69,14 @@
<td> <td>
<div class="tableButtons disTab"> <div class="tableButtons disTab">
<div class="btnTab btnTab1"></div> <div class="btnTab btnTab1"></div>
<a href="/test">
<div class="btnTab btnTab2"></div> <div class="btnTab btnTab2"></div>
</a>
<a href="/delete">
<div class="btnTab btnTab3"></div> <div class="btnTab btnTab3"></div>
</a>
<div class="btnTab btnTab4"></div> <div class="btnTab btnTab4"></div>
</div> </div>
</td> </td>
@ -89,23 +95,41 @@
integrity="sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E=" crossorigin="anonymous"></script> integrity="sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E=" crossorigin="anonymous"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {
var fixHelper = function(e,ui) { var fixHelper = function (e, ui) {
ui.children().each(function(){ ui.children().each(function () {
$(this).width($(this).width()); $(this).width($(this).width());
}); });
return ui; return ui;
}; };
$("#compTable tbody").sortable({ $("#compTable tbody").sortable({
forcePlaceholderSize:true, forcePlaceholderSize: true,
forceHelperSize: true, forceHelperSize: true,
items: 'tr', items: 'tr',
update: function(){ update: function () {
var serial = $('#compTable tbody').sortable('serialize',{key:'items[]', attribute:'data-class'}); var serial = $('#compTable tbody').sortable('serialize', {key: 'items[]', attribute: 'data-class'});
console.log(serial); console.log(serial);
$.ajax({
url: '/projects/candidate/comparison/sort/',
method: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
},
data: serial,
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (jqXHR, e) {
console.log(jqXHR);
console.log(e);
}
});
}, },
helper: fixHelper, helper: fixHelper,
}).disableSelection();; }).disableSelection();
;
}); });
</script> </script>
{% endblock %} {% endblock %}

@ -3,6 +3,7 @@ from django.views.generic import TemplateView
from .views import ( from .views import (
add_candidate, add_candidate,
sort_candidates,
contractor_portfolio_create, contractor_portfolio_create,
ContractorPortfolioTrashView, ContractorPortfolioTrashView,
ContractorPortfolioUpdateView, ContractorPortfolioUpdateView,
@ -34,6 +35,7 @@ urlpatterns = [
urls.url(r'^portfolio/(?P<pk>\d+)/edit/$', ContractorPortfolioUpdateView.as_view(), name='contractor-portfolio-edit'), urls.url(r'^portfolio/(?P<pk>\d+)/edit/$', ContractorPortfolioUpdateView.as_view(), name='contractor-portfolio-edit'),
urls.url(r'^candidate/add/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', add_candidate, name='add-candidate'), urls.url(r'^candidate/add/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', add_candidate, name='add-candidate'),
urls.url(r'^candidate/comparison/sort/$', sort_candidates, name='comparison-sort'),
urls.url(r'^candidate/comparison/(?P<pk>\d+)/$', ProjectComparisonView.as_view(), name='comparison'), urls.url(r'^candidate/comparison/(?P<pk>\d+)/$', ProjectComparisonView.as_view(), name='comparison'),
urls.url(r'^offerorder/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', OfferOrderView.as_view(), name='offer-order'), urls.url(r'^offerorder/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', OfferOrderView.as_view(), name='offer-order'),

@ -11,11 +11,14 @@ from django.views.generic import ListView, DetailView, CreateView, View, UpdateV
from django.views.generic.base import ContextMixin from django.views.generic.base import ContextMixin
from pprint import pprint, pformat from pprint import pprint, pformat
import json import json
import pydash as _; _.map = _.map_; _.filter = _.filter_ import pydash as _;
_.map = _.map_;
_.filter = _.filter_
import re import re
from .mixins import LastAccessMixin from .mixins import LastAccessMixin
from .models import Project, ProjectFile, Portfolio, PortfolioPhoto,Candidate, Answer, AnswerFile, Realty, Order from .models import Project, ProjectFile, Portfolio, PortfolioPhoto, Candidate, Answer, AnswerFile, Realty, Order
from archilance.mixins import BaseMixin from archilance.mixins import BaseMixin
from users.models import User, Team from users.models import User, Team
from work_sell.models import Picture from work_sell.models import Picture
@ -57,8 +60,10 @@ class ProjectDetailWithContractorAnswerView(BaseMixin, View):
team = None team = None
answer = None answer = None
try: team = contractor.team try:
except Team.DoesNotExist: pass team = contractor.team
except Team.DoesNotExist:
pass
if team: if team:
answer = team.answers.first() answer = team.answers.first()
@ -69,7 +74,7 @@ class ProjectDetailWithContractorAnswerView(BaseMixin, View):
if got_answer: if got_answer:
context.update({'answer': answer}) context.update({'answer': answer})
else: else:
if request.GET.get('answer_as_team') == 'on': # TODO: Check for actual possibility to answer as a team if request.GET.get('answer_as_team') == 'on': # TODO: Check for actual possibility to answer as a team
context.update({'answer_as_team': True}) context.update({'answer_as_team': True})
form = self.form_class(request=request, answer_as_team=True) form = self.form_class(request=request, answer_as_team=True)
else: else:
@ -84,7 +89,7 @@ class ProjectDetailWithContractorAnswerView(BaseMixin, View):
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
answer_as_team = None answer_as_team = None
if request.POST.get('answer_as_team') == 'on': # TODO: Check for actual possibility to answer as a team if request.POST.get('answer_as_team') == 'on': # TODO: Check for actual possibility to answer as a team
answer_as_team = True answer_as_team = True
if answer_as_team: if answer_as_team:
@ -255,7 +260,8 @@ class CustomerProjectCreateView(BaseMixin, View):
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below form = self.form_class(request.POST,
request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
form.is_valid() form.is_valid()
realty = form.cleaned_data.get('realty') realty = form.cleaned_data.get('realty')
@ -284,7 +290,7 @@ class CustomerProjectCreateView(BaseMixin, View):
realty.save() realty.save()
realty_form.save_m2m() realty_form.save_m2m()
project.realty = realty # Connect a realty with a project project.realty = realty # Connect a realty with a project
project.save() project.save()
messages.info(request, 'Проект успешно создан') messages.info(request, 'Проект успешно создан')
@ -350,7 +356,8 @@ class CustomerProjectEditView(BaseMixin, View):
if form.is_valid() and realty_form.is_valid(): if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False) project = form.save(commit=False)
project.customer = request.user project.customer = request.user
project.files = form.cleaned_data.get('files') # TODO: Should we somehow get rid of this explicit assignment? project.files = form.cleaned_data.get(
'files') # TODO: Should we somehow get rid of this explicit assignment?
project.save() project.save()
form.save_m2m() form.save_m2m()
@ -366,7 +373,7 @@ class CustomerProjectEditView(BaseMixin, View):
realty.save() realty.save()
realty_form.save_m2m() realty_form.save_m2m()
project.realty = realty # Connect a realty with a project project.realty = realty # Connect a realty with a project
project.save() project.save()
messages.info(request, 'Проект успешно отредактирован') messages.info(request, 'Проект успешно отредактирован')
@ -393,7 +400,7 @@ class CustomerProjectEditView(BaseMixin, View):
class ContractorPortfolioTrashView(View): class ContractorPortfolioTrashView(View):
form_class = ContractorPortfolioTrashForm form_class = ContractorPortfolioTrashForm
def post(self,request, *args, **kwargs): def post(self, request, *args, **kwargs):
form = self.form_class(_.merge({}, request.POST, kwargs), request=request) form = self.form_class(_.merge({}, request.POST, kwargs), request=request)
if form.is_valid(): if form.is_valid():
portfolio = form.cleaned_data.get('pk') portfolio = form.cleaned_data.get('pk')
@ -493,7 +500,23 @@ def add_candidate(request, answer_id, project_id):
answer = Answer.objects.get(pk=answer_id) answer = Answer.objects.get(pk=answer_id)
project = Project.objects.get(pk=project_id) project = Project.objects.get(pk=project_id)
candidate = Candidate.objects.create(answer=answer, project=project) candidate = Candidate.objects.create(answer=answer, project=project)
return HttpResponseRedirect(reverse('projects:detail',args=[project_id])) return HttpResponseRedirect(reverse('projects:detail', args=[project_id]))
def sort_candidates(request):
if request.is_ajax():
items = request.POST.getlist('items[]')
i = 1
for item in items:
candidate = Candidate.objects.get(pk=item)
candidate.position = i
candidate.save()
i += 1
data = {
'success': 'ok',
}
return HttpResponse(json.dumps(data), content_type='application/json')
class OfferOrderView(View): class OfferOrderView(View):
@ -537,9 +560,10 @@ class ContractorPortfolioUpdateView(UpdateView):
from django.views.generic import DeleteView from django.views.generic import DeleteView
class PortfolioDelete(DeleteView): class PortfolioDelete(DeleteView):
model = Portfolio model = Portfolio
success_url = reverse_lazy('users:contractor-profile') success_url = reverse_lazy('users:contractor-profile')
# import code; code.interact(local=dict(globals(), **locals())) # import code; code.interact(local=dict(globals(), **locals()))

Loading…
Cancel
Save