consolidated player-table
to consolidate, had to move the filtering to the context instead of the template (probably the right way to do it anyway) also switched from using display to using class to hide cells (also probably the more right/consistent way to do this)
This commit is contained in:
@@ -20,7 +20,7 @@ class Positioning(models.Model):
|
|||||||
('DH','DH')
|
('DH','DH')
|
||||||
]
|
]
|
||||||
position = models.CharField(choices=positions, default=None, max_length=2, null=True, blank=True)
|
position = models.CharField(choices=positions, default=None, max_length=2, null=True, blank=True)
|
||||||
order = models.PositiveSmallIntegerField(default=0, null=True)
|
order = models.PositiveSmallIntegerField(default=None, null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('player', 'event',)
|
unique_together = ('player', 'event',)
|
||||||
|
|||||||
@@ -33,33 +33,30 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ formset.management_form }}
|
{{ formset.management_form }}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
{# <input type="submit" value="Submit" class="btn btn-sm btn-success mx-3 my-0 my-0">#}
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h5>Lineup</h5>
|
<div class="card my-1">
|
||||||
<table class="table">
|
<div class="card-header"><h5>DH'd</h5></div>
|
||||||
{% include 'lineups/player-table-header.html' %}
|
<div class="card-body p-0">
|
||||||
<tbody id="lineup">
|
{% include 'lineups/player-table.html' with table_id="dhd" formset=formset_dhd available_class="d-none" order_class="d-none"%}
|
||||||
{% for form in formset %}
|
</div>
|
||||||
{% if form.instance.order or form.instance.position == "P" %}
|
</div>
|
||||||
{% include 'lineups/player-table-row.html' with form=form available_display="none" order_display="table-cell" %}
|
<div class="card my-1">
|
||||||
{% endif %}
|
<div class="card-header"><h5>Lineup</h5></div>
|
||||||
{% endfor %}
|
<div class="card-body p-0">
|
||||||
</tbody>
|
{% include 'lineups/player-table.html' with table_id="lineup" formset=formset_lineup available_class="d-none"%}
|
||||||
</table>
|
<div class="justify-content-md-end d-md-flex m-2"><input type="submit" value="Submit" class="btn btn-primary"></div>
|
||||||
<input type="submit" value="Submit">
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h5>Players</h5>
|
<div class="card my-1">
|
||||||
<table class="table">
|
<div class="card-header"><h5>Bench</h5></div>
|
||||||
{% include 'lineups/player-table-header.html' %}
|
<div class="card-body p-0">
|
||||||
<tbody id="bench">
|
{% include 'lineups/player-table.html' with table_id="bench" formset=formset_bench order_class="d-none"%}
|
||||||
{% for form in formset|dictsortreversed:"availability.available"%}
|
</div>
|
||||||
{% if not form.instance.order and not form.instance.position == "P" %}
|
</div>
|
||||||
{% include 'lineups/player-table-row.html' with form=form available_display="table-cell" order_display="none" %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table >
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -89,6 +86,16 @@
|
|||||||
form_element_order.value = parseInt(player_rows[i].dataset.order)
|
form_element_order.value = parseInt(player_rows[i].dataset.order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var lineup = new Sortable.create(
|
||||||
|
document.getElementById('dhd'), {
|
||||||
|
animation: 150,
|
||||||
|
ghostClass: "ghost",
|
||||||
|
{#handle: ".bars-move",#}
|
||||||
|
group: {
|
||||||
|
put: true,
|
||||||
|
pull: true
|
||||||
|
}
|
||||||
|
})
|
||||||
var lineup = new Sortable.create(
|
var lineup = new Sortable.create(
|
||||||
document.getElementById('lineup'), {
|
document.getElementById('lineup'), {
|
||||||
animation: 150,
|
animation: 150,
|
||||||
@@ -99,6 +106,7 @@
|
|||||||
pull:true
|
pull:true
|
||||||
},
|
},
|
||||||
onAdd: function (/**Event*/evt) {
|
onAdd: function (/**Event*/evt) {
|
||||||
|
// Add to Lineup
|
||||||
var itemEl = evt.item; // dragged HTMLElement
|
var itemEl = evt.item; // dragged HTMLElement
|
||||||
var player_id = itemEl.dataset.playerId
|
var player_id = itemEl.dataset.playerId
|
||||||
console.log(itemEl)
|
console.log(itemEl)
|
||||||
@@ -110,16 +118,10 @@
|
|||||||
toggle_in_lineup(player_order_button)
|
toggle_in_lineup(player_order_button)
|
||||||
player_order.parentElement.dataset.order = evt.newIndex
|
player_order.parentElement.dataset.order = evt.newIndex
|
||||||
refresh_lineup_order()
|
refresh_lineup_order()
|
||||||
player_available.parentElement.style.display="none"
|
{#player_available.parentElement.style.display="none"#}
|
||||||
player_order.style.display="table-cell"
|
player_available.parentElement.classList.add('d-none')
|
||||||
evt.to; // target list
|
{#player_order.style.display="table-cell"#}
|
||||||
evt.from; // previous list
|
player_order.classList.remove('d-none')
|
||||||
evt.oldIndex; // element's old index within old parent
|
|
||||||
evt.newIndex; // element's new index within new parent
|
|
||||||
evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
|
|
||||||
evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
|
|
||||||
evt.clone // the clone element
|
|
||||||
evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
|
|
||||||
},
|
},
|
||||||
onUpdate: function (/**Event*/evt) {
|
onUpdate: function (/**Event*/evt) {
|
||||||
console.log('update to lineup')
|
console.log('update to lineup')
|
||||||
@@ -144,10 +146,12 @@
|
|||||||
var form_element_order =itemEl.querySelector('[id$="order"]')
|
var form_element_order =itemEl.querySelector('[id$="order"]')
|
||||||
var player_order = itemEl.querySelector('[id^="player-order"]')
|
var player_order = itemEl.querySelector('[id^="player-order"]')
|
||||||
var player_available =itemEl.querySelector('[id^="player-available"]')
|
var player_available =itemEl.querySelector('[id^="player-available"]')
|
||||||
player_available.parentElement.style.display="table-cell"
|
{#player_available.parentElement.style.display="table-cell"#}
|
||||||
|
player_available.parentElement.classList.remove('d-none')
|
||||||
form_element_order.value = 0
|
form_element_order.value = 0
|
||||||
player_order.innerHTML = 1
|
player_order.innerHTML = 1
|
||||||
player_order.style.display="none"
|
{#player_order.style.display="none"#}
|
||||||
|
player_order.classList.add('d-none')
|
||||||
var player_id = itemEl.dataset.playerId
|
var player_id = itemEl.dataset.playerId
|
||||||
refresh_lineup_order()
|
refresh_lineup_order()
|
||||||
}
|
}
|
||||||
@@ -167,7 +171,7 @@
|
|||||||
player_row.dataset.order = 0
|
player_row.dataset.order = 0
|
||||||
}
|
}
|
||||||
refresh_lineup_order()
|
refresh_lineup_order()
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" style="display: none"></th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
<th scope="col">Name</th>
|
|
||||||
<th scope="col">Pos</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<tr data-player-id="{{ form.instance.player.id }}"
|
|
||||||
data-position="{{ form.instance.position }}"
|
|
||||||
data-order="{{ form.instance.order }}">
|
|
||||||
{{ form.id.as_hidden }}
|
|
||||||
{{ form.event.as_hidden }}
|
|
||||||
{{ form.order.as_hidden }}
|
|
||||||
{{ form.player.as_hidden }}
|
|
||||||
<td id="player-availability-{{ form.instance.player.id }}"
|
|
||||||
style="display:{{ available_display }};"
|
|
||||||
>
|
|
||||||
{% if form.availability.available == 2 %}
|
|
||||||
<img class="bg-success p-2 rounded-circle"
|
|
||||||
width="5"
|
|
||||||
height="5"
|
|
||||||
id="player-available-{{ form.instance.player.id }}"
|
|
||||||
>
|
|
||||||
<span class="visually-hidden">Yes</span>
|
|
||||||
{% elif form.availability.available == 1%}
|
|
||||||
<img class="bg-info p-2 rounded-circle"
|
|
||||||
width="5"
|
|
||||||
height="5"
|
|
||||||
id="player-available-{{ form.instance.player.id }}"
|
|
||||||
>
|
|
||||||
<span class="visually-hidden">Maybe</span>
|
|
||||||
{% elif form.availability.available == 0%}
|
|
||||||
<img class="bg-danger p-2 rounded-circle"
|
|
||||||
width="5" height="5"
|
|
||||||
id="player-available-{{ form.instance.player.id }}"
|
|
||||||
>
|
|
||||||
<span class="visually-hidden">No</span>
|
|
||||||
{% elif form.availability.available == -1%}
|
|
||||||
<img class="bg-secondary p-2 rounded-circle"
|
|
||||||
width="5"
|
|
||||||
height="5"
|
|
||||||
id="player-available-{{ form.instance.player.id }}"
|
|
||||||
>
|
|
||||||
<span class="visually-hidden">Unknown</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<th scope="row"
|
|
||||||
id="player-order-{{ form.instance.player.id }}"
|
|
||||||
style="display:{{ order_display }};">
|
|
||||||
{% if form.order.value %}
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-light"
|
|
||||||
id="player-order-button-{{ form.instance.player.id }}"
|
|
||||||
onclick="toggle_in_lineup(this)"
|
|
||||||
>
|
|
||||||
{{ form.order.value }}
|
|
||||||
</button>
|
|
||||||
{% elif form.order.value == 0 %}
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-dark"
|
|
||||||
id="player-order-button-{{ form.instance.player.id }}"
|
|
||||||
onclick="toggle_in_lineup(this)"
|
|
||||||
>
|
|
||||||
D
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ form.instance.player.first_name }} {{ form.instance.player.last_name }}
|
|
||||||
<small class="text-muted fw-light">#{{ form.instance.player.jersey_number }}</small><br>
|
|
||||||
<code><small>{{ form.statline }}</small></code>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
{{ form.position }}
|
|
||||||
</td>
|
|
||||||
{# <td>{{ form.instance.position }}</td>#}
|
|
||||||
</tr>
|
|
||||||
86
lineups/templates/lineups/player-table.html
Normal file
86
lineups/templates/lineups/player-table.html
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr class="border border-light">
|
||||||
|
{# <th scope="col" style="display: none"></th>#}
|
||||||
|
{# <th scope="col" class="border border-light"></th>#}
|
||||||
|
{# <th scope="col">Name</th>#}
|
||||||
|
{# <th scope="col">Pos</th>#}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id={{ table_id }}>
|
||||||
|
{% for form in formset %}
|
||||||
|
<tr data-player-id="{{ form.instance.player.id }}"
|
||||||
|
data-position="{{ form.instance.position }}"
|
||||||
|
data-order="{{ form.instance.order }}">
|
||||||
|
{{ form.id.as_hidden }}
|
||||||
|
{{ form.event.as_hidden }}
|
||||||
|
{{ form.order.as_hidden }}
|
||||||
|
{{ form.player.as_hidden }}
|
||||||
|
{{ form.teamsnap_id.as_hidden }}
|
||||||
|
<td id="player-availability-{{ form.instance.player.id }}"
|
||||||
|
class="{{ available_class }}"
|
||||||
|
>
|
||||||
|
{% if form.availability.available == 1 %}
|
||||||
|
<button class="btn btn-light bg-info p-1"
|
||||||
|
id="player-available-{{ form.instance.player.id }}"
|
||||||
|
>
|
||||||
|
<span style="visibility: hidden">2</span>
|
||||||
|
<span class="visually-hidden">Maybe</span>
|
||||||
|
</button>
|
||||||
|
{% elif form.availability.available == 2%}
|
||||||
|
<button class="btn btn-light bg-success p-1"
|
||||||
|
id="player-available-{{ form.instance.player.id }}"
|
||||||
|
>
|
||||||
|
<span style="visibility: hidden">1</span>
|
||||||
|
</button>
|
||||||
|
<span class="visually-hidden">Yes</span>
|
||||||
|
{% elif form.availability.available == 0%}
|
||||||
|
<button class="btn btn-light bg-danger p-1"
|
||||||
|
id="player-available-{{ form.instance.player.id }}"
|
||||||
|
>
|
||||||
|
<span style="visibility: hidden">0</span>
|
||||||
|
</button>
|
||||||
|
<span class="visually-hidden">No</span>
|
||||||
|
{% else %}
|
||||||
|
<button class="btn btn-light bg-secondary p-1"
|
||||||
|
id="player-available-{{ form.instance.player.id }}"
|
||||||
|
>
|
||||||
|
<span style="visibility: hidden">X</span>
|
||||||
|
</button>
|
||||||
|
<span class="visually-hidden">Unknown</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<th scope="row"
|
||||||
|
id="player-order-{{ form.instance.player.id }}"
|
||||||
|
class="{{ order_class }}">
|
||||||
|
{% if form.order.value %}
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-light p-1"
|
||||||
|
id="player-order-button-{{ form.instance.player.id }}"
|
||||||
|
onclick="toggle_in_lineup(this)"
|
||||||
|
>
|
||||||
|
{{ form.order.value }}
|
||||||
|
</button>
|
||||||
|
{% elif form.order.value == 0 %}
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-dark p-1"s
|
||||||
|
id="player-order-button-{{ form.instance.player.id }}"
|
||||||
|
onclick="toggle_in_lineup(this)"
|
||||||
|
>
|
||||||
|
D
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ form.instance.player.first_name }} {{ form.instance.player.last_name }}
|
||||||
|
<small class="text-muted fw-light">#{{ form.instance.player.jersey_number }}</small>
|
||||||
|
{# <br><code><small>{{ form.statline }}</small></code>#}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
{{ form.position }}
|
||||||
|
</td>
|
||||||
|
{# <td>{{ form.instance.position }}</td>#}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
@@ -5,6 +5,13 @@ from events.models import Event
|
|||||||
from players.models import Player
|
from players.models import Player
|
||||||
from django.forms.models import model_to_dict
|
from django.forms.models import model_to_dict
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.db.models import Case, When
|
||||||
|
|
||||||
|
def queryset_from_ids(Model, id_list):
|
||||||
|
#https://stackoverflow.com/questions/4916851/django-get-a-queryset-from-array-of-ids-in-specific-order
|
||||||
|
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(id_list)])
|
||||||
|
queryset = Model.objects.filter(pk__in=id_list).order_by(preserved)
|
||||||
|
return queryset
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
def edit(request, event_id):
|
def edit(request, event_id):
|
||||||
@@ -31,6 +38,7 @@ def edit(request, event_id):
|
|||||||
return render(request, 'success.html', {'call_back':'edit lineup','id':event_id, 'errors':[error for error in formset.errors if error]}, status=200)
|
return render(request, 'success.html', {'call_back':'edit lineup','id':event_id, 'errors':[error for error in formset.errors if error]}, status=200)
|
||||||
# return render(request, 'success.html', {'call_back':'schedule'})
|
# return render(request, 'success.html', {'call_back':'schedule'})
|
||||||
previous_event = Event.objects.get(id=event_id-1)
|
previous_event = Event.objects.get(id=event_id-1)
|
||||||
|
|
||||||
event = Event.objects.get(id=event_id)
|
event = Event.objects.get(id=event_id)
|
||||||
next_event = Event.objects.get(id=event_id+1)
|
next_event = Event.objects.get(id=event_id+1)
|
||||||
players = Player.objects.all().prefetch_related('availability_set', 'statline_set', 'positioning_set')
|
players = Player.objects.all().prefetch_related('availability_set', 'statline_set', 'positioning_set')
|
||||||
@@ -41,36 +49,47 @@ def edit(request, event_id):
|
|||||||
}
|
}
|
||||||
for player in players
|
for player in players
|
||||||
}
|
}
|
||||||
|
players = Player.objects.prefetch_related('availability_set', 'positioning_set')
|
||||||
# players_d.sort(key=lambda d: (-d['availability'].available, d['last_name']))
|
# players_d.sort(key=lambda d: (-d['availability'].available, d['last_name']))
|
||||||
|
|
||||||
players_with_positioning = [i.player for i in Positioning.objects.filter(event_id=event_id)]
|
for player in players:
|
||||||
players_without_positioning = [i for i in players if i not in players_with_positioning]
|
Positioning.objects.get_or_create(player_id=player.id, event_id=event_id)
|
||||||
Positioning.objects.bulk_create([Positioning(event_id=event_id, player=player) for player in players_without_positioning])
|
|
||||||
qset = Positioning.objects.filter(event_id=event_id)
|
|
||||||
|
|
||||||
formset = PositioningFormSet(queryset=qset.order_by('order'))
|
qs_starting_lineup = Positioning.objects.filter(event_id=event_id, order__isnull=False).order_by(
|
||||||
pass
|
'order')
|
||||||
formset_starting = PositioningFormSet(
|
qs_bench = Positioning.objects.filter(event_id=event_id, order__isnull=True).prefetch_related(
|
||||||
queryset=Positioning.objects.exclude(order__isnull=True).filter(event_id=event_id))
|
'player__availability_set').order_by('player__last_name')
|
||||||
formset_bench = PositioningFormSet(
|
|
||||||
queryset=Positioning.objects.exclude(order__isnull=False).filter(event_id=event_id))
|
# This is all a compromise to get the sorting just the way I wanted. THERE'S GOT TO BE A BETTER WAY
|
||||||
|
ids_starting_lineup = [item.id for item in qs_starting_lineup]
|
||||||
|
ids_bench_available = [item.id for item in qs_bench
|
||||||
|
if item.player.availability_set.get(event_id=event_id).available == 2]
|
||||||
|
ids_bench_maybe = [item.id for item in qs_bench
|
||||||
|
if item.player.availability_set.get(event_id=event_id).available == 1]
|
||||||
|
ids_bench_no = [item.id for item in qs_bench
|
||||||
|
if item.player.availability_set.get(event_id=event_id).available == 0]
|
||||||
|
ids_bench_unknown = [item.id for item in qs_bench
|
||||||
|
if item.player.availability_set.get(event_id=event_id).available == -1]
|
||||||
|
qset = queryset_from_ids(Positioning,
|
||||||
|
ids_starting_lineup + ids_bench_available + ids_bench_maybe + ids_bench_no + ids_bench_unknown)
|
||||||
|
|
||||||
|
formset = PositioningFormSet(queryset=qset)
|
||||||
|
|
||||||
for f in formset:
|
for f in formset:
|
||||||
if f.instance.player_id:
|
if f.instance.player_id:
|
||||||
f.availability = f.instance.player.availability_set.get(event_id=event_id)
|
f.availability = f.instance.player.availability_set.get(event_id=event_id)
|
||||||
f.statline = f.instance.player.statline_set.get()
|
# f.statline = f.instance.player.statline_set.get()
|
||||||
|
|
||||||
|
|
||||||
|
formset_lineup = [f for f in formset if f.instance.order]
|
||||||
|
formset_dhd = [f for f in formset if not f.instance.order and f.instance.position]
|
||||||
|
formset_bench = [f for f in formset if f not in formset_lineup and f not in formset_dhd]
|
||||||
|
|
||||||
return render(request, 'lineups/lineup.html', {'title': 'Lineup',
|
return render(request, 'lineups/lineup.html', {'title': 'Lineup',
|
||||||
'events_tab':'active',
|
|
||||||
'previous_event':previous_event,
|
|
||||||
'event': event,
|
'event': event,
|
||||||
|
'previous_event': previous_event,
|
||||||
'next_event': next_event,
|
'next_event': next_event,
|
||||||
'players_info': players_info,
|
|
||||||
'formset': formset,
|
'formset': formset,
|
||||||
# 'players': players_d,
|
'formset_lineup':formset_lineup,
|
||||||
# 'positionings_players_initial':[player for player in players if player['positioning']],
|
'formset_bench':formset_bench,
|
||||||
'formset_starting':formset_starting,
|
'formset_dhd': formset_dhd
|
||||||
'formset_bench':formset_bench
|
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user