From d6bd39e8879fac2bc06cb1f64390d2a03eb0c195 Mon Sep 17 00:00:00 2001 From: CMDR furrycat Date: Mon, 18 Jan 2016 08:53:35 -0500 Subject: [PATCH] Optionally races can be ordered. --- lib/entry.php | 21 +++++++++++++++++++-- lib/race.php | 7 ++++++- propel/schema.xml | 5 +++++ race.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/lib/entry.php b/lib/entry.php index 75fae9e..c2a135a 100644 --- a/lib/entry.php +++ b/lib/entry.php @@ -85,6 +85,23 @@ return true; } + function sort_legs($a, $b) { + list($a_flags, $a_station_id, $a_system_id, $a_order) = $a; + list($b_flags, $b_station_id, $b_system_id, $b_order) = $b; + /* Start and finish lines. */ + if ($a_flags > $b_flags) return -1; + if ($a_flags < $b_flags) return 1; + /* Explicit order. */ + if ($a_order > $b_order) return 1; + if ($a_order < $b_order) return -1; + /* Fall back to system and station ID order. */ + if ($a_system_id < $b_system_id) return -1; + if ($a_system_id > $b_system_id) return 1; + if ($a_station_id < $b_station_id) return -1; + if ($a_station_id > $b_station_id) return 1; + return 0; + } + function add_entry($race_id, $ship_id, $entry) { $q = new CourseQuery; $q->joinWith("Course.Station"); @@ -108,9 +125,9 @@ $flags = 0; if ($leg->getStartLine()) $flags |= Course::StartFlag(); if ($leg->getFinishLine()) $flags |= Course::FinishFlag(); - $legs[$station_name] = array($flags, $station->getId(), $system_id); + $legs[$station_name] = array($flags, $station->getId(), $system_id, $leg->getStationOrder()); } - arsort($legs); + uasort($legs, sort_legs); $system_ids = array_unique($system_ids); $rq = new RaikogramQuery; $rq->filterBySystem1($system_ids); diff --git a/lib/race.php b/lib/race.php index cd629f3..877e3e8 100644 --- a/lib/race.php +++ b/lib/race.php @@ -204,6 +204,8 @@ $leg->setStationId($station_id); if ($v & Course::StartFlag()) $leg->setStartLine(true); if ($v & Course::FinishFlag()) $leg->setFinishLine(true); + $station_order = $posted["${k}order"]; + if ($station_order) $leg->setStationOrder($station_order); $leg->save(); } @@ -240,7 +242,10 @@ option("station$station_id", Course::WaypointFlag() | Course::StartFlag(), "start line"); option("station$station_id", Course::WaypointFlag() | Course::FinishFlag(), "finish line"); option("station$station_id", Course::WaypointFlag() | Course::StartFlag() | Course::FinishFlag(), "start/finish line"); - echo "\n"; + echo ""; + echo " order: "; + input("station${station_id}order"); + echo "\n"; echo "\n"; } echo "\n"; diff --git a/propel/schema.xml b/propel/schema.xml index 510b77c..76dedba 100644 --- a/propel/schema.xml +++ b/propel/schema.xml @@ -109,6 +109,7 @@ + @@ -121,6 +122,10 @@ + + + + diff --git a/race.js b/race.js index a6eaf4f..4ec19d6 100644 --- a/race.js +++ b/race.js @@ -42,13 +42,28 @@ function toggle_classification(event) { /* Check start and finish lines are set. */ function validate() { + var stations = 0; var flags = 0; for (input of document.getElementsByClassName('station')) { - flags |= input.value & mandatory_flags; + var value = parseInt(input.value); + var flag = value & mandatory_flags; + if (value && ! flag) stations++; + flags |= flag; + } + + var valid = (flags == mandatory_flags); + if (valid) { + /* Either all stations must be ordered or none. */ + var ordered = 0; + for (input of document.getElementsByTagName('input')) { + if (! input.name.match(/^station\d+order$/)) continue; + if (input.value) ordered++; + } + if (ordered > 0 && ordered < stations) valid = false; } var submits = document.getElementsByName('add_race'); - if (submits.length) submits[0].disabled = ! (flags == mandatory_flags); + if (submits.length) submits[0].disabled = ! valid; } /* Action of a waypoint was changed. */ @@ -57,6 +72,25 @@ function changed_waypoint(event) { if (input == event.target) continue; input.value &= ~(event.target.value & mandatory_flags); } + if (event.target.value & mandatory_flags) { + /* Clear order. */ + var input = document.getElementById(event.target.name + 'order'); + if (input) input.value = ''; + } + + validate(); +} + +/* Order of a waypoint was changed. */ +function changed_order(event) { + var order = parseInt(event.target.value); + if (order) { + for (input of document.getElementsByTagName('input')) { + if (input == event.target) continue; + if (! input.name.match(/^station\d+order$/)) continue; + if (parseInt(input.value) == order) input.value = ''; + } + } validate(); } @@ -72,6 +106,17 @@ function loaded() { input.addEventListener('change', changed_waypoint, true); input.addEventListener('focusout', changed_waypoint, true); } + for (input of document.getElementsByTagName('input')) { + var m = input.name.match(/^station\d+order$/); + if (! m) continue; + input.autocomplete = 'off'; + input.type = 'text'; + input.pattern = '^[1-9]+[0-9]*$'; + input.size = input.maxLength = 3; + input.id = input.name; + input.addEventListener('change', changed_order, true); + input.addEventListener('focusout', changed_order, true); + } validate(); } } -- 2.7.4