Added sorting for teams and members
This commit is contained in:
parent
2483bbbf5c
commit
8fdb4a624c
@ -9,15 +9,49 @@
|
|||||||
<a href="{% url 'index' %}" class="btn btn-primary px-4">Back</a>
|
<a href="{% url 'index' %}" class="btn btn-primary px-4">Back</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container my-4 p-4 pb-0 bg-body-secondary rounded">
|
<div class="container my-4 p-4 pb-0 bg-body rounded">
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col-md-6 col-xl-8">
|
<div class="col-md-6 col-xl-8">
|
||||||
<h3>Teams & Members</h3>
|
<h3>Teams & Members</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-4">
|
<div class="col-md-6 col-xl-4">
|
||||||
<div class="input-group mb-4 mb-md-0">
|
<div class="input-group mb-4 mb-md-0 dropdown">
|
||||||
<input type="search" class="form-control" placeholder="Search Members" id="search">
|
<button type="button" data-bs-toggle="dropdown" class="btn btn-outline-secondary border-secondary-subtle">
|
||||||
<button type="button" class="btn border bg-body-tertiary" id="searchButton"><i class="bi bi-search"></i></button>
|
<i class="bi bi-sort-up"></i>
|
||||||
|
</button>
|
||||||
|
<input type="search" class="form-control border-secondary-subtle shadow-none" placeholder="Search Members" id="search">
|
||||||
|
<button type="button" class="btn btn-outline-secondary border-secondary-subtle rounded-end" id="searchButton"><i class="bi bi-search"></i></button>
|
||||||
|
<form id="sortForm">
|
||||||
|
<ul class="dropdown-menu w-100 py-3 text-body-secondary" onclick="event.stopPropagation()">
|
||||||
|
<li class="px-4">
|
||||||
|
<h3 class="h6 mb-3">Sort teams by</h3>
|
||||||
|
<div>
|
||||||
|
<div class="d-inline-block form-check">
|
||||||
|
<input type="radio" class="form-check-input" checked value="team_number" name="sortTeams" id="sortTeamsName">
|
||||||
|
<label for="sortTeamsName" class="form-check-label">Team Number</label>
|
||||||
|
</div>
|
||||||
|
<div class="d-inline-block form-check ms-4">
|
||||||
|
<input type="radio" class="form-check-input" value="section_letter" name="sortTeams" id="sortTeamsSection">
|
||||||
|
<label for="sortTeamsSection" class="form-check-label">Section Letter</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-divider my-3"></li>
|
||||||
|
<li class="px-4">
|
||||||
|
<h3 class="h6 mb-3">Sort members by</h3>
|
||||||
|
<div>
|
||||||
|
<div class="d-inline-block form-check">
|
||||||
|
<input type="radio" class="form-check-input" value="first_name" name="sortMembers" id="sortMembersName">
|
||||||
|
<label for="sortMembersName" class="form-check-label">Member Name</label>
|
||||||
|
</div>
|
||||||
|
<div class="d-inline-block form-check ms-4">
|
||||||
|
<input type="radio" class="form-check-input" checked value="peg_number" name="sortMembers" id="sortMembersPeg">
|
||||||
|
<label for="sortMembersPeg" class="form-check-label">Peg Number</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -39,7 +73,7 @@
|
|||||||
<!-- Edit Modal -->
|
<!-- Edit Modal -->
|
||||||
<div class="modal fade" id="editMemberModal" tabindex="-1">
|
<div class="modal fade" id="editMemberModal" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content border-0 bg-body-secondary">
|
<div class="modal-content border-0">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="modal-title fs-5" id="editMemberName">Member Name Here</h3>
|
<h3 class="modal-title fs-5" id="editMemberName">Member Name Here</h3>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
|
||||||
@ -47,21 +81,21 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form id="editMemberForm">
|
<form id="editMemberForm">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="editMemberFirstName" class="form-label">Forename</label>
|
<label for="editMemberFirstName" class="form-label">Forename</label>
|
||||||
<input type="text" name="editMemberFirstName" id="editMemberFirstName" class="form-control mb-2" required minlength="1" maxlength="30">
|
<input type="text" name="editMemberFirstName" id="editMemberFirstName" class="form-control" required minlength="1" maxlength="30">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="editMemberLastName" class="form-label">Surname</label>
|
<label for="editMemberLastName" class="form-label">Surname</label>
|
||||||
<input type="text" name="editMemberLastName" id="editMemberLastName" class="form-control mb-2" required minlength="1" maxlength="30">
|
<input type="text" name="editMemberLastName" id="editMemberLastName" class="form-control" required minlength="1" maxlength="30">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="editMemberTeam" class="form-label">Team</label>
|
<label for="editMemberTeam" class="form-label">Team</label>
|
||||||
<select name="editMemberTeam" id="editMemberTeam" class="form-select mb-2" required></select>
|
<select name="editMemberTeam" id="editMemberTeam" class="form-select" required></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="editMemberPeg" class="form-label">Peg Number</label>
|
<label for="editMemberPeg" class="form-label">Peg Number</label>
|
||||||
<input type="number" name="editMemberPeg" id="editMemberPeg" class="form-control" required min="1" max="9999">
|
<input type="number" name="editMemberPeg" id="editMemberPeg" class="form-control" min="1" max="9999">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -44,7 +44,10 @@ def get_teams(request):
|
|||||||
return
|
return
|
||||||
|
|
||||||
search = request.POST.get("search")
|
search = request.POST.get("search")
|
||||||
teams = Team.objects.order_by("team_number").all()
|
sort_teams = request.POST.get("sortTeams") or "team_number"
|
||||||
|
sort_members = request.POST.get("sortMembers") or "peg_number"
|
||||||
|
|
||||||
|
teams = Team.objects.order_by(sort_teams).all()
|
||||||
|
|
||||||
# Filter out teams that don't contain members being searched for
|
# Filter out teams that don't contain members being searched for
|
||||||
if search:
|
if search:
|
||||||
@ -74,11 +77,14 @@ def get_teams(request):
|
|||||||
"team": team.team_number,
|
"team": team.team_number,
|
||||||
"peg": member.peg_number
|
"peg": member.peg_number
|
||||||
}
|
}
|
||||||
for member in team.members.order_by("peg_number").all()
|
for member in team.members.order_by(sort_members).all()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
response_data["teams"].append(team_data)
|
response_data["teams"].append(team_data)
|
||||||
|
|
||||||
|
response_data["sortTeams"] = sort_teams
|
||||||
|
response_data["sortMembers"] = sort_members
|
||||||
|
|
||||||
return JsonResponse(response_data)
|
return JsonResponse(response_data)
|
||||||
|
|
||||||
def update_member(request):
|
def update_member(request):
|
||||||
|
@ -21,19 +21,41 @@ $(document).ready(() => {
|
|||||||
teamsLoading(true);
|
teamsLoading(true);
|
||||||
|
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
fetchAndLoadTeams($("#search").val());
|
fetchAndLoadTeams(...getFilters());
|
||||||
}, 500)
|
}, 500)
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#searchButton").on("click", () => {
|
$("#searchButton").on("click", () => {
|
||||||
fetchAndLoadTeams($("#search").val());
|
fetchAndLoadTeams(...getFilters());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit member form validation
|
$("#sortForm input").on("click", () => {
|
||||||
|
fetchAndLoadTeams(...getFilters());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Edit member form validation options
|
||||||
$("#editMemberForm").validate({
|
$("#editMemberForm").validate({
|
||||||
errorClass: "text-danger mb-2"
|
errorClass: "text-danger mb-2"
|
||||||
|
})
|
||||||
|
|
||||||
|
// Prevent dropdowns from closing when clicking inside
|
||||||
|
$('.dropdown-menu').on('hide.bs.dropdown', function (e) {
|
||||||
|
var target = $(e.clickEvent.target);
|
||||||
|
if(target.hasClass("keepopen") || target.parents(".keepopen").length){
|
||||||
|
return false; // returning false should stop the dropdown from hiding.
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
function getFilters() {
|
||||||
|
return [
|
||||||
|
$("#search").val(),
|
||||||
|
$("input[name='sortTeams']:checked", "#sortForm").val(),
|
||||||
|
$("input[name='sortMembers']:checked", "#sortForm").val()
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns bool if the string is empty or only contains whitespace
|
* Returns bool if the string is empty or only contains whitespace
|
||||||
@ -55,7 +77,7 @@ function loadTeams(teams, highlightText="") {
|
|||||||
$("#teamsContainer").append(
|
$("#teamsContainer").append(
|
||||||
`<div class='col-12 col-md-6 col-xl-4 mb-4'>
|
`<div class='col-12 col-md-6 col-xl-4 mb-4'>
|
||||||
<div
|
<div
|
||||||
class='team p-4 bg-body-tertiary rounded h-100 fluid-hover-zoom shadow-sm shadow-on-hover'
|
class='team p-4 bg-body-secondary bg-gradient rounded h-100 fluid-hover-zoom shadow-sm shadow-on-hover'
|
||||||
data-number='${team.team_number}'>
|
data-number='${team.team_number}'>
|
||||||
<h4>
|
<h4>
|
||||||
<span class='fs-6'>TEAM</span>
|
<span class='fs-6'>TEAM</span>
|
||||||
@ -76,7 +98,7 @@ function loadTeams(teams, highlightText="") {
|
|||||||
const fullname = member.first + " " + member.last;
|
const fullname = member.first + " " + member.last;
|
||||||
|
|
||||||
$("#teamsContainer").find(".team-members").last().append(
|
$("#teamsContainer").find(".team-members").last().append(
|
||||||
`<li class='bg-body-secondary mb-3 rounded w-100'>
|
`<li class='bg-body-tertiary mb-3 rounded w-100'>
|
||||||
<div
|
<div
|
||||||
type='button'
|
type='button'
|
||||||
class='team-member px-3 py-2 d-flex'
|
class='team-member px-3 py-2 d-flex'
|
||||||
@ -113,13 +135,15 @@ function loadTeams(teams, highlightText="") {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchAndLoadTeams(search="") {
|
function fetchAndLoadTeams(search="", sortTeams="", sortMembers="") {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: getTeamsUrl,
|
url: getTeamsUrl,
|
||||||
type: "post",
|
type: "post",
|
||||||
data: {
|
data: {
|
||||||
"csrfmiddlewaretoken": csrfMiddlewareToken,
|
"csrfmiddlewaretoken": csrfMiddlewareToken,
|
||||||
"search": !isEmptyOrSpaces(search) ? search : null
|
"search": !isEmptyOrSpaces(search) ? search : null, // might not be necessary? TODO: re-evaluate
|
||||||
|
"sortTeams": sortTeams ? sortTeams : null,
|
||||||
|
"sortMembers": sortMembers ? sortMembers : null
|
||||||
},
|
},
|
||||||
error: (xhr, textStatus, errorThrown) => { alert(errorThrown); },
|
error: (xhr, textStatus, errorThrown) => { alert(errorThrown); },
|
||||||
success: (result) => {
|
success: (result) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user