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:
2021-12-10 11:18:48 -06:00
parent 2f620eb417
commit c9fbdacede
6 changed files with 165 additions and 134 deletions

View File

@@ -20,7 +20,7 @@ class Positioning(models.Model):
('DH','DH')
]
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:
unique_together = ('player', 'event',)

View File

@@ -33,33 +33,30 @@
{% csrf_token %}
{{ formset.management_form }}
<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">
<h5>Lineup</h5>
<table class="table">
{% include 'lineups/player-table-header.html' %}
<tbody id="lineup">
{% for form in formset %}
{% if form.instance.order or form.instance.position == "P" %}
{% include 'lineups/player-table-row.html' with form=form available_display="none" order_display="table-cell" %}
{% endif %}
{% endfor %}
</tbody>
</table>
<input type="submit" value="Submit">
<div class="card my-1">
<div class="card-header"><h5>DH'd</h5></div>
<div class="card-body p-0">
{% include 'lineups/player-table.html' with table_id="dhd" formset=formset_dhd available_class="d-none" order_class="d-none"%}
</div>
</div>
<div class="card my-1">
<div class="card-header"><h5>Lineup</h5></div>
<div class="card-body p-0">
{% include 'lineups/player-table.html' with table_id="lineup" formset=formset_lineup available_class="d-none"%}
<div class="justify-content-md-end d-md-flex m-2"><input type="submit" value="Submit" class="btn btn-primary"></div>
</div>
</div>
</div>
<div class="col-md-6">
<h5>Players</h5>
<table class="table">
{% include 'lineups/player-table-header.html' %}
<tbody id="bench">
{% for form in formset|dictsortreversed:"availability.available"%}
{% if not form.instance.order and not form.instance.position == "P" %}
{% include 'lineups/player-table-row.html' with form=form available_display="table-cell" order_display="none" %}
{% endif %}
{% endfor %}
</tbody>
</table >
<div class="card my-1">
<div class="card-header"><h5>Bench</h5></div>
<div class="card-body p-0">
{% include 'lineups/player-table.html' with table_id="bench" formset=formset_bench order_class="d-none"%}
</div>
</div>
</div>
</div>
@@ -89,6 +86,16 @@
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(
document.getElementById('lineup'), {
animation: 150,
@@ -99,6 +106,7 @@
pull:true
},
onAdd: function (/**Event*/evt) {
// Add to Lineup
var itemEl = evt.item; // dragged HTMLElement
var player_id = itemEl.dataset.playerId
console.log(itemEl)
@@ -110,16 +118,10 @@
toggle_in_lineup(player_order_button)
player_order.parentElement.dataset.order = evt.newIndex
refresh_lineup_order()
player_available.parentElement.style.display="none"
player_order.style.display="table-cell"
evt.to; // target list
evt.from; // previous list
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
{#player_available.parentElement.style.display="none"#}
player_available.parentElement.classList.add('d-none')
{#player_order.style.display="table-cell"#}
player_order.classList.remove('d-none')
},
onUpdate: function (/**Event*/evt) {
console.log('update to lineup')
@@ -144,10 +146,12 @@
var form_element_order =itemEl.querySelector('[id$="order"]')
var player_order = itemEl.querySelector('[id^="player-order"]')
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
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
refresh_lineup_order()
}
@@ -167,7 +171,7 @@
player_row.dataset.order = 0
}
refresh_lineup_order()
}
}
</script>

View File

@@ -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>

View File

@@ -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 }}&nbsp;{{ form.instance.player.last_name }}&nbsp;
<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>

View 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 }}&nbsp;{{ form.instance.player.last_name }}&nbsp;
<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>

View File

@@ -5,6 +5,13 @@ from events.models import Event
from players.models import Player
from django.forms.models import model_to_dict
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.
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':'schedule'})
previous_event = Event.objects.get(id=event_id-1)
event = Event.objects.get(id=event_id)
next_event = Event.objects.get(id=event_id+1)
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
}
players = Player.objects.prefetch_related('availability_set', 'positioning_set')
# 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)]
players_without_positioning = [i for i in players if i not in players_with_positioning]
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)
for player in players:
Positioning.objects.get_or_create(player_id=player.id, event_id=event_id)
formset = PositioningFormSet(queryset=qset.order_by('order'))
pass
formset_starting = PositioningFormSet(
queryset=Positioning.objects.exclude(order__isnull=True).filter(event_id=event_id))
formset_bench = PositioningFormSet(
queryset=Positioning.objects.exclude(order__isnull=False).filter(event_id=event_id))
qs_starting_lineup = Positioning.objects.filter(event_id=event_id, order__isnull=False).order_by(
'order')
qs_bench = Positioning.objects.filter(event_id=event_id, order__isnull=True).prefetch_related(
'player__availability_set').order_by('player__last_name')
# 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:
if f.instance.player_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',
'events_tab':'active',
'previous_event':previous_event,
'event': event,
'previous_event': previous_event,
'next_event': next_event,
'players_info': players_info,
'formset': formset,
# 'players': players_d,
# 'positionings_players_initial':[player for player in players if player['positioning']],
'formset_starting':formset_starting,
'formset_bench':formset_bench
'formset_lineup':formset_lineup,
'formset_bench':formset_bench,
'formset_dhd': formset_dhd
})