Skip to content

Instantly share code, notes, and snippets.

@bradkrane
Last active May 2, 2024 17:59
Show Gist options
  • Save bradkrane/36fa3a549e94c208418b4a76ce751ba7 to your computer and use it in GitHub Desktop.
Save bradkrane/36fa3a549e94c208418b4a76ce751ba7 to your computer and use it in GitHub Desktop.
Estimates Remaining Quantity/Time of Doses using Weight
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Doses Remaining Estimator</title>
</head>
<body>
<h2>Doses Remaining Estimator</h2>
<form>
<label for="emptyWeight">Bottle weight (g):</label>
<input type="number" id="emptyWeight" required><br><br>
<label for="capWeight">Cap weight (g):</label>
<input type="number" id="capWeight"><br><br>
<label for="includeCap">Include Cap weight:</label>
<input type="checkbox" id="includeCap"><br><br>
<label for="doseWeight">Avg. Weight of Dose (g):</label>
<input type="number" id="doseWeight" required step="any"><br><br>
<label for="dosesPerDay">Avg. dose/d (N.n):</label>
<input type="number" id="dosesPerDay"><br><br>
<label for="currentWeight">Current Weight of Bottle with Doses (and optionally with cap) (g):</label>
<input type="number" id="currentWeight" required><br><br>
<button type="button" onclick="calculateAndUpdate()">Calculate Estimates</button>
</form>
<br>
<h3>Estimated Doses Remaining: <span id="dosesRemaining">0</span></h3>
<h3>Estimated Days Remaining: <span id="daysRemaining">0</span></h3>
<script>
function calculateAndUpdate() {
const emptyWeight = parseFloat(document.getElementById('emptyWeight').value) || 0;
const capWeight = parseFloat(document.getElementById('capWeight').value) || 0;
const doseWeight = parseFloat(document.getElementById('doseWeight').value);
let currentWeight = parseFloat(document.getElementById('currentWeight').value) || 0;
const includeCap = document.getElementById('includeCap').checked;
const dosesPerDay = parseFloat(document.getElementById('dosesPerDay').value);
// Always update URL with current state
const params = new URLSearchParams({
emptyWeight: emptyWeight,
capWeight: capWeight || '',
doseWeight: doseWeight || '',
includeCap: includeCap,
dosesPerDay: dosesPerDay || '',
currentWeight: currentWeight,
});
// weight or other key params needed my not be specified yet so bail on calc
if((!doseWeight && !dosesPerDay) || !currentWeight) return;
if(includeCap) currentWeight -= capWeight;
const weightOfDoses = currentWeight - emptyWeight;
let numberOfDoses = null;
if(doseWeight) {
numberOfDoses = Math.round(weightOfDoses / doseWeight)
document.getElementById('dosesRemaining').textContent = numberOfDoses;
}
if(dosesPerDay && numberOfDoses)
document.getElementById('daysRemaining').textContent = Math.floor(Math.floor(numberOfDoses / dosesPerDay));
window.history.replaceState({}, '', `${location.pathname}?${params}`);
}
function populateFieldsFromURL() {
const params = new URLSearchParams(window.location.search);
document.querySelectorAll('input').forEach(input => {
const paramValue = params.get(input.id);
if (input.type === 'checkbox')
input.checked = paramValue === 'true';
else if (input.type === 'number')
input.value = paramValue ? parseFloat(paramValue) : '';
else
input.value = paramValue || '';
})
calculateAndUpdate();
}
// if press 'enter' on input run calc
document.querySelectorAll('input').forEach(input => {
input.addEventListener('keypress', function(event) {
if (event.key === "Enter") {
event.preventDefault();
calculateAndUpdate();
}
});
});
function autoFocusFirstEmptyInput() {
const inputs = document.querySelectorAll('input[type="number"], input[type="text"]');
for (let input of inputs) {
if (input.value === '') {
input.focus();
return;
}
}
}
window.onload = function() {
populateFieldsFromURL();
autoFocusFirstEmptyInput();
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment