179 lines
7.0 KiB
HTML
179 lines
7.0 KiB
HTML
<!--
|
|
Copyright © 2023 Lee Yingtong Li (RunasSudo)
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
-->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>PBS medicine search</title>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css" integrity="sha256-4RctOgogjPAdwGbwq+rxfwAmSpZhWaafcZR9btzUk18=" crossorigin="anonymous">
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand-sm navbar-light bg-light d-print-none">
|
|
<div class="container">
|
|
<a class="navbar-brand" href=" ">PBS medicine search</a>
|
|
</div>
|
|
</nav>
|
|
<div class="container pt-4">
|
|
<div>
|
|
<input class="form-control" id="search-input" placeholder="Search…" autocomplete="off">
|
|
</div>
|
|
<div>
|
|
<table id="search-results" class="table mt-2">
|
|
<thead>
|
|
<tr>
|
|
<th class="col-1">Item code</th>
|
|
<th class="col-8">Drug</th>
|
|
<th class="col-1">Quantity</th>
|
|
<th class="col-1">Repeats</th>
|
|
<th class="col-1">Restriction</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<td colspan="5" class="text-center">Enter a search term above to show results</th>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<footer class="border-top pt-4 mt-4">
|
|
<p class="text-muted">Results sourced from the PBS database as at January 2023. This tool is made available in the hope that it will be useful, but <b>WITHOUT ANY WARRANTY</b>; without even the implied warranty of <b>MERCHANTABILITY</b> or <b>FITNESS FOR A PARTICULAR PURPOSE</b>. Information provided in this tool is intended for reference by medical professionals. Nothing in this tool is intended to constitute medical advice.</p>
|
|
</footer>
|
|
</div>
|
|
|
|
<!--<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>-->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
|
|
<script src="autocomplete.js"></script>
|
|
|
|
<script>
|
|
var pbsData = null;
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.addEventListener('load', function() {
|
|
pbsData = JSON.parse(xhr.responseText);
|
|
|
|
// Initialise search bar
|
|
|
|
const labels = [];
|
|
for (let row of pbsData) {
|
|
if (labels.indexOf(row['mp_pt']) < 0) {
|
|
labels.push(row['mp_pt']);
|
|
}
|
|
}
|
|
labels.sort();
|
|
|
|
const data = [];
|
|
for (let label of labels) {
|
|
data.push({'label': label});
|
|
}
|
|
|
|
const autocomplete = new Autocomplete(document.getElementById('search-input'), {
|
|
data: data,
|
|
maximumItems: 20,
|
|
threshold: 2,
|
|
onSelectItem: onClickSearchItem
|
|
});
|
|
});
|
|
xhr.open('GET', 'pbs.json');
|
|
xhr.send();
|
|
|
|
function onClickSearchItem(item) {
|
|
// Find matching PBS items
|
|
const items = [];
|
|
for (let row of pbsData) {
|
|
if (row['mp_pt'] === item['label']) {
|
|
items.push(row);
|
|
}
|
|
}
|
|
items.sort(comparePBSItems);
|
|
|
|
// Update table
|
|
const tbody = document.querySelector(' search-results tbody');
|
|
tbody.innerHTML = '';
|
|
for (let item of items) {
|
|
const tr = document.createElement('tr');
|
|
let td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['item_code'] + '" target="_blank">' + item['item_code'] + '</a>'; tr.appendChild(td);
|
|
td = document.createElement('td'); td.innerText = item['tpuu_or_mpp_pt']; tr.appendChild(td);
|
|
td = document.createElement('td'); td.innerText = item['mq']; tr.appendChild(td);
|
|
td = document.createElement('td'); td.innerText = item['repeats']; tr.appendChild(td);
|
|
|
|
if (item['restriction_flag'] === 'U') {
|
|
td = document.createElement('td'); tr.appendChild(td);
|
|
} else if (item['restriction_flag'] === 'R') {
|
|
td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['item_code'] + '" target="_blank">Restricted</a>'; tr.appendChild(td);
|
|
tr.classList.add('table-warning');
|
|
} else if (item['restriction_flag'] === 'A') {
|
|
if (item['streamlined_authorities']) {
|
|
td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['item_code'] + '" target="_blank">Streamlined</a>'; tr.appendChild(td);
|
|
tr.classList.add('table-warning');
|
|
} else {
|
|
td = document.createElement('td'); td.innerHTML = '<a href="https://www.pbs.gov.au/medicine/item/' + item['item_code'] + '" target="_blank">Authority</a>'; tr.appendChild(td);
|
|
tr.classList.add('table-danger');
|
|
}
|
|
} else {
|
|
td = document.createElement('td'); td.innerText = item['restriction_flag']; tr.appendChild(td);
|
|
}
|
|
|
|
tbody.appendChild(tr);
|
|
}
|
|
}
|
|
|
|
const regexIsNumber = /^[0-9]+$/.compile();
|
|
|
|
function comparePBSItems(item1, item2) {
|
|
// Sort tablets/capsules before other forms
|
|
|
|
if ((item1['tpuu_or_mpp_pt'].indexOf(' tablet, ') >= 0 || item1['tpuu_or_mpp_pt'].indexOf(' capsule, ') >= 0) && !(item2['tpuu_or_mpp_pt'].indexOf(' tablet, ') >= 0 || item2['tpuu_or_mpp_pt'].indexOf(' capsule, ') >= 0)) {
|
|
return -1;
|
|
}
|
|
if ((item2['tpuu_or_mpp_pt'].indexOf(' tablet, ') >= 0 || item2['tpuu_or_mpp_pt'].indexOf(' capsule, ') >= 0) && !(item1['tpuu_or_mpp_pt'].indexOf(' tablet, ') >= 0 || item1['tpuu_or_mpp_pt'].indexOf(' capsule, ') >= 0)) {
|
|
return 1;
|
|
}
|
|
|
|
// Compare tpuu_or_mpp_pt word-by-word accounting for numbers
|
|
|
|
const bits1 = item1['tpuu_or_mpp_pt'].split(' ');
|
|
const bits2 = item2['tpuu_or_mpp_pt'].split(' ');
|
|
|
|
for (let i = 0; i < bits1.length && i < bits2.length; i++) {
|
|
if (regexIsNumber.test(bits1[i]) && regexIsNumber.test(bits2[i])) {
|
|
// Numeric compare
|
|
const num1 = parseInt(bits1[i]);
|
|
const num2 = parseInt(bits2[i]);
|
|
|
|
if (num1 < num2) {
|
|
return -1;
|
|
}
|
|
if (num1 > num2) {
|
|
return 1;
|
|
}
|
|
} else {
|
|
// String compare
|
|
if (bits1[i] < bits2[i]) {
|
|
return -1;
|
|
}
|
|
if (bits1[i] > bits2[i]) {
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|