« MediaWiki:Gadget-dosage-calculator.js » : différence entre les versions
(Fixed height doubon) |
(Starting surface calculator) |
||
Ligne 153 : | Ligne 153 : | ||
}, | }, | ||
]; | ]; | ||
function getCookie(name) { | |||
const value = `; ${document.cookie}`; | |||
const parts = value.split(`; ${name}=`); | |||
if (parts.length === 2) return parts.pop().split(';').shift(); | |||
} | |||
/* | /* | ||
Ligne 373 : | Ligne 379 : | ||
DosageDialog.prototype.getActionProcess = function ( action ) { | DosageDialog.prototype.getActionProcess = function ( action ) { | ||
var weight_input_number = parseFloat( | var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0; | ||
var weightUnit = | var weightUnit = this.unitRadioInput.value; | ||
var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue()); | var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue()); | ||
Ligne 392 : | Ligne 398 : | ||
return DosageDialog.super.prototype.getActionProcess.call( this, action ); | return DosageDialog.super.prototype.getActionProcess.call( this, action ); | ||
}; | }; | ||
Ligne 405 : | Ligne 405 : | ||
// When working with a stack layout, you can use: | // When working with a stack layout, you can use: | ||
// return this.panels.getCurrentItem().$element.outerHeight( true ); | // return this.panels.getCurrentItem().$element.outerHeight( true ); | ||
if (this.dosageResultMessage.isVisible()) { | if (this.dosageResultMessage.isVisible()) { | ||
return this.panel.$element.outerHeight( true ); | return this.panel.$element.outerHeight( true ); | ||
Ligne 441 : | Ligne 440 : | ||
}); | }); | ||
}; | }; | ||
// TO DO: | // TO DO: | ||
Ligne 448 : | Ligne 445 : | ||
// FIX CSS FOR ICONS | // FIX CSS FOR ICONS | ||
// ADD COLORS TO BROSELOW | // ADD COLORS TO BROSELOW | ||
/ | /* | ||
@param string drug (ex: 'Amoxiciline') | |||
/ | @param float dose_per_m2 (ex: 90, 7.5) | ||
@param string dose_unit (ex: 'mg, 'mcg') | |||
@param string roa (ex: 'PO', 'IR', 'IV') | |||
@param string frequency (ex: 'BID', 'q 12h') | |||
@param float max_daily_dose (default: 0) (ex: 3000, 30) | |||
@param string prn (default: '') (ex: 'prn', 'prn No/Vo') | |||
@param float duration (default: 0) (ex: 7, 14) | |||
@param float duration_unit (default: '') (ex: 'jours', 'semaines') | |||
Example Call: drugSurfaceDosageCalculator('Médicament', 40, 'mg', 'IV', 'q 12h', 300, '', 7, 'jours'); | |||
*/ | |||
// | drugSurfaceDosageCalculator = function(drug, dose_per_m2, dose_unit, roa, frequency, max_daily_dose = 0, prn = '', duration = 0, duration_unit = '') | ||
// | { | ||
//width: inherit; | // Lazy load the following librairies | ||
$.when( mw.loader.using( [ 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-windows' ] )).then( function() { | |||
// Subclass DosageSurfaceDialog. | |||
function DosageSurfaceDialog( config ) { | |||
DosageSurfaceDialog.super.call( this, config ); | |||
} | |||
OO.inheritClass( DosageSurfaceDialog, OO.ui.ProcessDialog ); | |||
// Specify a name for .addWindows() | |||
DosageSurfaceDialog.static.name = 'dosageSurfaceDialog'; | |||
// Specify a static title and actions. | |||
DosageSurfaceDialog.static.title = 'Calculateur de dose'; | |||
DosageSurfaceDialog.static.actions = [ | |||
{ | |||
action: 'accept', | |||
label: 'Fermer', | |||
flags: 'primary' | |||
} | |||
]; | |||
// Initialize main panel widgets and set up event handlers. | |||
DosageSurfaceDialog.prototype.initialize = function () { | |||
DosageSurfaceDialog.super.prototype.initialize.call( this ); | |||
this.panel = new OO.ui.PanelLayout( { | |||
padded: true, | |||
expanded: false | |||
} ); | |||
// Initialize Weight Horizontal Layout | |||
this.weightHorizontalLayout = new OO.ui.HorizontalLayout( { | |||
} ); | |||
// Initialize Weight Input Field Set | |||
this.weightInputFieldset = new OO.ui.FieldsetLayout(); | |||
// Initialize Weight Input | |||
this.weightInput = new OO.ui.NumberInputWidget({ | |||
min: 0, | |||
max: 500, | |||
step: 0.001, | |||
buttonStep: 1, | |||
placeholder: 'Poids', | |||
icon: 'userAvatar' | |||
}); | |||
// Set Weight Input Field | |||
this.weightInputField = new OO.ui.FieldLayout( this.weightInput, { | |||
label: 'Poids', | |||
align: 'left', | |||
} ); | |||
// Add Weight Input Field to Weight Input Field Set | |||
this.weightInputFieldset.addItems( [ this.weightInputField ] ); | |||
// Initialize Weight Unit Radio Input | |||
this.weightUnitRadioInput = new OO.ui.RadioSelectInputWidget( { | |||
options: [ | |||
{ data: 'kg', label: 'Kg' }, | |||
{ data: 'lbs', label: 'Lbs'} | |||
] | |||
} ); | |||
// Set Elements to Horizontal Layout | |||
this.weightHorizontalLayout.addItems([this.weightInputFieldset, this.weightUnitRadioInput]); | |||
// Initialize Height Horizontal Layout | |||
this.heightHorizontalLayout = new OO.ui.HorizontalLayout( { | |||
} ); | |||
// Initialize Height Input Field Set | |||
this.heightInputFieldset = new OO.ui.FieldsetLayout(); | |||
// Initialize Weight Input | |||
this.heightInput = new OO.ui.NumberInputWidget({ | |||
min: 0, | |||
max: 3, | |||
step: 0.0001, | |||
buttonStep: 0.1, | |||
placeholder: 'Poids', | |||
icon: 'userAvatar' | |||
}); | |||
// Set Height Input Field | |||
this.heightInputField = new OO.ui.FieldLayout( this.heightInput, { | |||
label: 'Taille', | |||
align: 'left', | |||
} ); | |||
// Add Weight Input Field to Weight Input Field Set | |||
this.heightInputFieldset.addItems( [ this.heightInputField ] ); | |||
// Initialize Height Unit Radio Input | |||
this.heightUnitRadioInput = new OO.ui.RadioSelectInputWidget( { | |||
options: [ | |||
{ data: 'm', label: 'm' }, | |||
{ data: 'pi + po', label: 'pi + po'} | |||
] | |||
} ); | |||
// Set Elements to Horizontal Layout | |||
this.heightHorizontalLayout.addItems([this.heightInputFieldset, this.heightUnitRadioInput]); | |||
// Initialize Spacer Label | |||
this.spacerLabel = new OO.ui.LabelWidget( { | |||
label: ' ', | |||
classes: [ 'mw-headline'], | |||
} ); | |||
// Initialize Dosage Result Message | |||
this.dosageResultMessage = new OO.ui.MessageWidget( { | |||
type: 'success', | |||
icon: 'labFlask', | |||
label: '' | |||
} ); | |||
// Intialize Copy Paste Button | |||
this.copyPasteButton = new OO.ui.ButtonWidget( { | |||
label: 'Copier-coller', | |||
icon: 'copy' | |||
} ); | |||
// Add Copy-Paste Button to Dosage Result Message | |||
this.dosageResultMessage.$element.append( this.copyPasteButton.$element ); | |||
// Changing CSS | |||
this.weightInputFieldset.$element[0].setAttribute('style', 'width: 75%; margin-bottom: -0.4em;'); | |||
this.weightInputField.$element[0].firstChild.firstChild.setAttribute('style', 'width: inherit;'); | |||
this.weightInputField.$element[0].firstChild.lastChild.setAttribute('style', 'width: inherit;'); | |||
this.heightInputFieldset.$element[0].setAttribute('style', 'width: 75%; margin-bottom: -0.4em;'); | |||
this.heightInputField.$element[0].firstChild.firstChild.setAttribute('style', 'width: inherit;'); | |||
this.heightInputField.$element[0].firstChild.lastChild.setAttribute('style', 'width: inherit;'); | |||
this.dosageResultMessage.$label[0].setAttribute('style', "display:inline-block;"); | |||
this.dosageResultMessage.$element[0].lastChild.setAttribute('style', "float:right;"); | |||
this.dosageResultMessage.$element[0].lastChild.firstChild.setAttribute("style", "display: inline;"); | |||
// Add Weight Horizontal Input, Height Horizontal Input and Dosage Result Label to Panel | |||
this.panel.$element.append( this.weightHorizontalLayout.$element ); | |||
this.panel.$element.append( this.heightHorizontalLayout.$element ); | |||
this.panel.$element.append( this.spacerLabel.$element ); | |||
this.panel.$element.append( this.dosageResultMessage.$element ); | |||
// Toggle Dosage Result Message visibility | |||
this.dosageResultMessage.toggle(); | |||
// Add Panel to Body | |||
this.$body.append( this.panel.$element ); | |||
// Add Event Handler to Weight Input, Height Input, Weight Unit Radio Input and Height Unit Radio Input | |||
this.weightInput.connect( this, { 'change': 'onWeightInputChange' } ); | |||
//this.heightInput.connect( this, { 'change': 'onHeightInputChange' } ); | |||
this.weightUnitRadioInput.connect( this, { 'change': 'onWeightUnitRadioInputChange' } ); | |||
//this.heightUnitRadioInput.connect( this, { 'change': 'onHeightUnitRadioInputChange' } ); | |||
this.copyPasteButton.connect( this, { 'click': 'onCopyPasterButtonClick' } ); | |||
}; | |||
// Specify any additional functionality required by the window (disable opening an empty URL, in this case) | |||
function updateDosageSurfaceResult(dosageDialog){ | |||
// TODO: COMPLETE FORMULA HERE | |||
// Get weight input | |||
var weight_input_number = parseFloat(dosageDialog.weightInput.value); | |||
if (!Number.isNaN(weight_input_number) && weight_input_number > 0) { | |||
var multiplier; | |||
if (dosageDialog.unitRadioInput.value === 'kg'){ | |||
multiplier = 1.0; | |||
} else { | |||
multiplier = 0.453592; | |||
} | |||
var daily_dose = Math.round(multiplier * dose_per_kg * weight_input_number / frequency_to_division[frequency]); | |||
var dose; | |||
if (max_daily_dose !== 0) { | |||
dose = Math.round((Math.min(max_daily_dose, daily_dose)) / frequency_to_division[frequency]); | |||
} else { | |||
dose = Math.round(daily_dose / frequency_to_division[frequency]); | |||
} | |||
// Update Result Message | |||
var dosageResultMessageString = drug + ' ' + dose.toString() + ' ' + dose_unit + ' ' + roa + ' ' + frequency + ' ' + prn + ((prn) ? ' ' : '' ) + ((duration) ? '×' + ' ' + duration.toString() + ' ' + duration_unit : ''); | |||
dosageDialog.dosageResultMessage.setLabel(dosageResultMessageString); | |||
if (!dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle(); | |||
} else { | |||
// Update Result Message | |||
dosageDialog.dosageResultMessage.setLabel(''); | |||
if (dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle(); | |||
} | |||
} | |||
DosageSurfaceDialog.prototype.onWeightInputChange = function ( value ) { | |||
updateDosageSurfaceResult(this); | |||
}; | |||
DosageSurfaceDialog.prototype.onWeightUnitRadioInputChange = function ( value ) { | |||
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0; | |||
if (this.unitRadioInput.value === 'kg') { | |||
this.weightInput.setValue(Math.round(10 * weight_input_number * 0.453592) / 10); | |||
} else { | |||
this.weightInput.setValue(Math.round(10 * weight_input_number * 2.20462) / 10); | |||
} | |||
}; | |||
DosageSurfaceDialog.prototype.onCopyPasterButtonClick = function ( value ) { | |||
// Copy the text inside the text field | |||
navigator.clipboard.writeText(this.dosageResultMessage.label); | |||
}; | |||
// Use the getActionProcess() method to specify a process to handle the | |||
// actions (for the 'save' action, in this example). | |||
DosageSurfaceDialog.prototype.getActionProcess = function ( action ) { | |||
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0; | |||
var weightUnit = this.weightUnitRadioInput.value; | |||
var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue()); | |||
document.cookie = "wikimedica-dosage-weight=" + weight_input_number + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/"; | |||
document.cookie = "wikimedica-dosage-weight-unit=" + weightUnit + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/"; | |||
document.cookie = "wikimedica-dosage-broselow-weight=" + broselow_weight + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/"; | |||
var dialog = this; | |||
if ( action ) { | |||
return new OO.ui.Process( function () { | |||
dialog.close( { | |||
action: action | |||
} ); | |||
} ); | |||
} | |||
// Fallback to parent handler. | |||
return DosageSurfaceDialog.super.prototype.getActionProcess.call( this, action ); | |||
}; | |||
// Specify the dialog height (or don't to use the automatically generated height). | |||
DosageSurfaceDialog.prototype.getBodyHeight = function () { | |||
// Note that "expanded: false" must be set in the panel's configuration for this to work. | |||
// When working with a stack layout, you can use: | |||
// return this.panels.getCurrentItem().$element.outerHeight( true ); | |||
console.log("HERE") | |||
console.log(this.dosageResultMessage.isVisible()); | |||
if (this.dosageResultMessage.isVisible()) { | |||
return this.panel.$element.outerHeight( true ); | |||
} else { | |||
return this.panel.$element.outerHeight( true ) + 60; | |||
} | |||
}; | |||
// Create and append the window manager. | |||
var windowManager = new OO.ui.WindowManager(); | |||
$( document.body ).append( windowManager.$element ); | |||
// Create a new dialog window. | |||
var dosageDialog = new DosageSurfaceDialog({ | |||
}); | |||
// Add windows to window manager using the addWindows() method. | |||
windowManager.addWindows( [ dosageDialog ] ); | |||
// Get cookie parameters | |||
var weight_input_number = parseFloat(getCookie('wikimedica-dosage-weight')); | |||
var weightUnit = getCookie('wikimedica-dosage-weight-unit'); | |||
var broselow_weight = parseFloat(getCookie('wikimedica-dosage-broselow-weight')); | |||
// Initialize parameters according to cookies | |||
dosageDialog.dropdownBroselowInput.setValue(broselow_weight); | |||
dosageDialog.weightUnitRadioInput.setValue(weightUnit); | |||
dosageDialog.weightInput.setValue(weight_input_number); | |||
// Open the window. | |||
windowManager.openWindow( dosageDialog ); | |||
}); | |||
}; |
Version du 13 janvier 2023 à 22:46
/* This modal dialog displays a tool for drug dosage calculations. */
console.log("Loading dosage calculator ...");
// Static variables
let frequency_to_division = {'DIE': 1, 'BID': 2, 'TID': 3, 'QID': 4, 'q 2h': 12, 'q 3h': 8, 'q 4h': 6, 'q 5h': 4.8, 'q 6h': 4, 'q 8h': 3, 'q 10h': 2.4, 'q 12h': 2, 'q 24h': 1};
let broselow_to_weight_kg = {'Rose': 6, 'Rouge': 8, 'Mauve': 10, 'Jaune': 13, 'Blanc': 16, 'Bleu': 21, 'Orange': 26, 'Vert': 33};
let broselow_to_weight_kg_min = {'Rose': 6, 'Rouge': 8, 'Mauve': 10, 'Jaune': 12, 'Blanc': 15, 'Bleu': 19, 'Orange': 24, 'Vert': 30};
let broselow_to_weight_kg_max = {'Rose': 7, 'Rouge': 9, 'Mauve': 11, 'Jaune': 14, 'Blanc': 18, 'Bleu': 23, 'Orange': 29, 'Vert': 36};
let broselow_to_weight_lbs = {'Rose': 14, 'Rouge': 18, 'Mauve': 23, 'Jaune': 28, 'Blanc': 36, 'Bleu': 46, 'Orange': 58, 'Vert': 77};
let broselow_to_weight_lbs_min = {'Rose': 13, 'Rouge': 17, 'Mauve': 22, 'Jaune': 26, 'Blanc': 33, 'Bleu': 42, 'Orange': 53, 'Vert': 66};
let broselow_to_weight_lbs_max = {'Rose': 15, 'Rouge': 20, 'Mauve': 24, 'Jaune': 30, 'Blanc': 40, 'Bleu': 50, 'Orange': 64, 'Vert': 80};
let broselow_dropdown_options_kg = [
{
icon: 'map',
data: 0,
label: 'Échelle de Broselow'
},
{
optgroup: '6-7 kg, 3-5 mois'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Rose'],
label: 'Rose'
},
{
optgroup: '8-9 kg, 6-11 mois'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Rouge'],
label: 'Rouge'
},
{
optgroup: '10-11 kg, 12-24 mois'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Mauve'],
label: 'Mauve'
},
{
optgroup: '12-14 kg, 2 ans mois'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Jaune'],
label: 'Jaune'
},
{
optgroup: '15-18 kg, 3-4 ans'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Blanc'],
label: 'Blanc'
},
{
optgroup: '19-23 kg, 5-6 ans'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Bleu'],
label: 'Bleu'
},
{
optgroup: '24-29 kg, 7-9 ans'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Orange'],
label: 'Orange'
},
{
optgroup: '30-36 kg, 10-11 ans'
},
{
icon: 'stop',
data: broselow_to_weight_kg['Vert'],
label: 'Vert'
},
];
let broselow_dropdown_options_lbs = [
{
icon: 'map',
data: "0",
label: 'Échelle de Broselow'
},
{
optgroup: '13-15 lbs, 3-5 mois'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Rose'],
label: 'Rose'
},
{
optgroup: '17-20 lbs, 6-11 mois'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Rouge'],
label: 'Rouge'
},
{
optgroup: '22-24 lbs, 12-24 mois'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Mauve'],
label: 'Mauve'
},
{
optgroup: '26-30 lbs, 2 ans mois'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Jaune'],
label: 'Jaune'
},
{
optgroup: '33-40 lbs, 3-4 ans'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Blanc'],
label: 'Blanc'
},
{
optgroup: '42-50 lbs, 5-6 ans'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Bleu'],
label: 'Bleu'
},
{
optgroup: '53-64 lbs, 7-9 ans'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Orange'],
label: 'Orange'
},
{
optgroup: '66-80 lbs, 10-11 ans'
},
{
icon: 'stop',
data: broselow_to_weight_lbs['Vert'],
label: 'Vert'
},
];
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
/*
@param string drug (ex: 'Amoxiciline')
@param float dose_per_kg (ex: 90, 7.5)
@param string dose_unit (ex: 'mg, 'mcg')
@param string roa (ex: 'PO', 'IR', 'IV')
@param string frequency (ex: 'BID', 'q 12h')
@param float max_daily_dose (default: 0) (ex: 3000, 30)
@param string prn (default: '') (ex: 'prn', 'prn No/Vo')
@param float duration (default: 0) (ex: 7, 14)
@param float duration_unit (default: '') (ex: 'jours', 'semaines')
Example Call: drugKgDosageCalculator('Amoxiciline', 90, 'mg', 'PO', 'BID', 3000, '', 7, 'jours');
*/
drugKgDosageCalculator = function(drug, dose_per_kg, dose_unit, roa, frequency, max_daily_dose = 0, prn = '', duration = 0, duration_unit = '')
{
// Lazy load the following librairies
$.when( mw.loader.using( [ 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-windows' ] )).then( function() {
// Subclass DosageDialog.
function DosageDialog( config ) {
DosageDialog.super.call( this, config );
}
OO.inheritClass( DosageDialog, OO.ui.ProcessDialog );
// Specify a name for .addWindows()
DosageDialog.static.name = 'dosageDialog';
// Specify a static title and actions.
DosageDialog.static.title = 'Calculateur de dose';
DosageDialog.static.actions = [
{
action: 'accept',
label: 'Fermer',
flags: 'primary'
}
];
// Initialize main panel widgets and set up event handlers.
DosageDialog.prototype.initialize = function () {
DosageDialog.super.prototype.initialize.call( this );
this.panel = new OO.ui.PanelLayout( {
padded: true,
expanded: false
} );
// Initialize Horizontal Layout
this.horizontalLayout = new OO.ui.HorizontalLayout( {
} );
// Initialize Weight Input Field Set
this.weightInputFieldset = new OO.ui.FieldsetLayout();
// Initialize Weight Input
this.weightInput = new OO.ui.NumberInputWidget({
min: 0,
max: 500,
step: 0.001,
buttonStep: 1,
placeholder: 'Poids',
icon: 'userAvatar'
});
// Set Weight Input Field
this.weightInputField = new OO.ui.FieldLayout( this.weightInput, {
label: drug + ' ' + dose_per_kg.toString() + ' ' + dose_unit + '/kg/j',
align: 'left',
} );
// Add Weight Input Field to Weight Input Field Set
this.weightInputFieldset.addItems( [ this.weightInputField ] );
// Initialize Unit Radio Input
this.unitRadioInput = new OO.ui.RadioSelectInputWidget( {
options: [
{ data: 'kg', label: 'Kg' },
{ data: 'lbs', label: 'Lbs'}
]
} );
// Set Elements to Horizontal Layout
this.horizontalLayout.addItems([this.weightInputFieldset, this.unitRadioInput]);
// Initialize Dropdown Broselow Input
this.dropdownBroselowInput = new OO.ui.DropdownInputWidget( {
options: broselow_dropdown_options_kg,
value: ''
} );
// Intialize changing flag
this.changing = false;
// Initialize Spacer Label
this.spacerLabel = new OO.ui.LabelWidget( {
label: ' ',
classes: [ 'mw-headline'],
} );
// Initialize Dosage Result Message
this.dosageResultMessage = new OO.ui.MessageWidget( {
type: 'success',
icon: 'labFlask',
label: ''
} );
// Intialize Copy Paste Button
this.copyPasteButton = new OO.ui.ButtonWidget( {
label: 'Copier-coller',
icon: 'copy'
} );
// Add Copy-Paste Button to Dosage Result Message
this.dosageResultMessage.$element.append( this.copyPasteButton.$element );
// Changing CSS
this.weightInputFieldset.$element[0].setAttribute('style', 'width: 75%; margin-bottom: -0.4em;');
this.weightInputField.$element[0].firstChild.firstChild.setAttribute('style', 'width: inherit;');
this.weightInputField.$element[0].firstChild.lastChild.setAttribute('style', 'width: inherit;');
this.dosageResultMessage.$label[0].setAttribute('style', "display:inline-block;");
this.dosageResultMessage.$element[0].lastChild.setAttribute('style', "float:right;");
this.dosageResultMessage.$element[0].lastChild.firstChild.setAttribute("style", "display: inline;");
// Add Horizontal Input, Dropdown Broselow Input and Dosage Result Label to Panel
this.panel.$element.append( this.horizontalLayout.$element );
this.panel.$element.append( this.dropdownBroselowInput.$element );
this.panel.$element.append( this.spacerLabel.$element );
this.panel.$element.append( this.dosageResultMessage.$element );
// Toggle Dosage Result Message visibility
this.dosageResultMessage.toggle();
// Add Panel to Body
this.$body.append( this.panel.$element );
// Add Event Handler to Weight Input, Unit Radio Input and Dropdown Broselow
this.weightInput.connect( this, { 'change': 'onWeightInputChange' } );
this.unitRadioInput.connect( this, { 'change': 'onUnitRadioInputChange' } );
this.dropdownBroselowInput.connect( this, { 'change': 'onDropdownBroselowInputChange' } );
this.copyPasteButton.connect( this, { 'click': 'onCopyPasterButtonClick' } );
};
// Specify any additional functionality required by the window (disable opening an empty URL, in this case)
function updateDosageResult(dosageDialog){
// Get weight input
var weight_input_number = parseFloat(dosageDialog.weightInput.value);
if (!Number.isNaN(weight_input_number) && weight_input_number > 0) {
var multiplier;
if (dosageDialog.unitRadioInput.value === 'kg'){
multiplier = 1.0;
} else {
multiplier = 0.453592;
}
var daily_dose = Math.round(multiplier * dose_per_kg * weight_input_number / frequency_to_division[frequency]);
var dose;
if (max_daily_dose !== 0) {
dose = Math.round((Math.min(max_daily_dose, daily_dose)) / frequency_to_division[frequency]);
} else {
dose = Math.round(daily_dose / frequency_to_division[frequency]);
}
// Update Broselow
var broselow_color, broselow_weight;
if (dosageDialog.unitRadioInput.value === 'kg') {
broselow_color = Object.keys(broselow_to_weight_kg).find(color => broselow_to_weight_kg_min[color] <= weight_input_number && broselow_to_weight_kg_max[color] >= weight_input_number);
broselow_weight = broselow_to_weight_kg[broselow_color] ? broselow_to_weight_kg[broselow_color]: 0;
} else {
broselow_color = Object.keys(broselow_to_weight_lbs).find(color => broselow_to_weight_lbs_min[color] <= weight_input_number && broselow_to_weight_lbs_max[color] >= weight_input_number);
broselow_weight = broselow_to_weight_lbs[broselow_color] ? broselow_to_weight_lbs[broselow_color]: 0;
}
dosageDialog.changing = true;
dosageDialog.dropdownBroselowInput.setValue(broselow_weight);
dosageDialog.changing = false;
// Update Result Message
var dosageResultMessageString = drug + ' ' + dose.toString() + ' ' + dose_unit + ' ' + roa + ' ' + frequency + ' ' + prn + ((prn) ? ' ' : '' ) + ((duration) ? '×' + ' ' + duration.toString() + ' ' + duration_unit : '');
dosageDialog.dosageResultMessage.setLabel(dosageResultMessageString);
if (!dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle();
} else {
// Update Broselow
dosageDialog.dropdownBroselowInput.setValue(0);
// Update Result Message
dosageDialog.dosageResultMessage.setLabel('');
if (dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle();
}
}
DosageDialog.prototype.onWeightInputChange = function ( value ) {
updateDosageResult(this);
};
DosageDialog.prototype.onUnitRadioInputChange = function ( value ) {
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0;
if (this.unitRadioInput.value === 'kg') {
this.dropdownBroselowInput.setOptions(broselow_dropdown_options_kg);
this.weightInput.setValue(Math.round(10 * weight_input_number * 0.453592) / 10);
} else {
this.dropdownBroselowInput.setOptions(broselow_dropdown_options_lbs);
this.weightInput.setValue(Math.round(10 * weight_input_number * 2.20462) / 10);
}
};
DosageDialog.prototype.onDropdownBroselowInputChange = function ( value ) {
var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue());
if (dosageDialog.changing === true) {
dosageDialog.changing = false;
} else {
this.weightInput.setValue(broselow_weight);
}
};
DosageDialog.prototype.onCopyPasterButtonClick = function ( value ) {
// Copy the text inside the text field
navigator.clipboard.writeText(this.dosageResultMessage.label);
};
// Use the getActionProcess() method to specify a process to handle the
// actions (for the 'save' action, in this example).
DosageDialog.prototype.getActionProcess = function ( action ) {
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0;
var weightUnit = this.unitRadioInput.value;
var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue());
document.cookie = "wikimedica-dosage-weight=" + weight_input_number + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
document.cookie = "wikimedica-dosage-weight-unit=" + weightUnit + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
document.cookie = "wikimedica-dosage-broselow-weight=" + broselow_weight + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
var dialog = this;
if ( action ) {
return new OO.ui.Process( function () {
dialog.close( {
action: action
} );
} );
}
// Fallback to parent handler.
return DosageDialog.super.prototype.getActionProcess.call( this, action );
};
// Specify the dialog height (or don't to use the automatically generated height).
DosageDialog.prototype.getBodyHeight = function () {
// Note that "expanded: false" must be set in the panel's configuration for this to work.
// When working with a stack layout, you can use:
// return this.panels.getCurrentItem().$element.outerHeight( true );
if (this.dosageResultMessage.isVisible()) {
return this.panel.$element.outerHeight( true );
} else {
return this.panel.$element.outerHeight( true ) + 60;
}
};
// Create and append the window manager.
var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
// Create a new dialog window.
var dosageDialog = new DosageDialog({
});
// Add windows to window manager using the addWindows() method.
windowManager.addWindows( [ dosageDialog ] );
// Get cookie parameters
var weight_input_number = parseFloat(getCookie('wikimedica-dosage-weight'));
var weightUnit = getCookie('wikimedica-dosage-weight-unit');
var broselow_weight = parseFloat(getCookie('wikimedica-dosage-broselow-weight'));
// Initialize parameters according to cookies
dosageDialog.dropdownBroselowInput.setValue(broselow_weight);
dosageDialog.unitRadioInput.setValue(weightUnit);
dosageDialog.weightInput.setValue(weight_input_number);
// Open the window.
windowManager.openWindow( dosageDialog );
});
};
// TO DO:
// FIX CSS FOR ICONS
// ADD COLORS TO BROSELOW
/*
@param string drug (ex: 'Amoxiciline')
@param float dose_per_m2 (ex: 90, 7.5)
@param string dose_unit (ex: 'mg, 'mcg')
@param string roa (ex: 'PO', 'IR', 'IV')
@param string frequency (ex: 'BID', 'q 12h')
@param float max_daily_dose (default: 0) (ex: 3000, 30)
@param string prn (default: '') (ex: 'prn', 'prn No/Vo')
@param float duration (default: 0) (ex: 7, 14)
@param float duration_unit (default: '') (ex: 'jours', 'semaines')
Example Call: drugSurfaceDosageCalculator('Médicament', 40, 'mg', 'IV', 'q 12h', 300, '', 7, 'jours');
*/
drugSurfaceDosageCalculator = function(drug, dose_per_m2, dose_unit, roa, frequency, max_daily_dose = 0, prn = '', duration = 0, duration_unit = '')
{
// Lazy load the following librairies
$.when( mw.loader.using( [ 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-windows' ] )).then( function() {
// Subclass DosageSurfaceDialog.
function DosageSurfaceDialog( config ) {
DosageSurfaceDialog.super.call( this, config );
}
OO.inheritClass( DosageSurfaceDialog, OO.ui.ProcessDialog );
// Specify a name for .addWindows()
DosageSurfaceDialog.static.name = 'dosageSurfaceDialog';
// Specify a static title and actions.
DosageSurfaceDialog.static.title = 'Calculateur de dose';
DosageSurfaceDialog.static.actions = [
{
action: 'accept',
label: 'Fermer',
flags: 'primary'
}
];
// Initialize main panel widgets and set up event handlers.
DosageSurfaceDialog.prototype.initialize = function () {
DosageSurfaceDialog.super.prototype.initialize.call( this );
this.panel = new OO.ui.PanelLayout( {
padded: true,
expanded: false
} );
// Initialize Weight Horizontal Layout
this.weightHorizontalLayout = new OO.ui.HorizontalLayout( {
} );
// Initialize Weight Input Field Set
this.weightInputFieldset = new OO.ui.FieldsetLayout();
// Initialize Weight Input
this.weightInput = new OO.ui.NumberInputWidget({
min: 0,
max: 500,
step: 0.001,
buttonStep: 1,
placeholder: 'Poids',
icon: 'userAvatar'
});
// Set Weight Input Field
this.weightInputField = new OO.ui.FieldLayout( this.weightInput, {
label: 'Poids',
align: 'left',
} );
// Add Weight Input Field to Weight Input Field Set
this.weightInputFieldset.addItems( [ this.weightInputField ] );
// Initialize Weight Unit Radio Input
this.weightUnitRadioInput = new OO.ui.RadioSelectInputWidget( {
options: [
{ data: 'kg', label: 'Kg' },
{ data: 'lbs', label: 'Lbs'}
]
} );
// Set Elements to Horizontal Layout
this.weightHorizontalLayout.addItems([this.weightInputFieldset, this.weightUnitRadioInput]);
// Initialize Height Horizontal Layout
this.heightHorizontalLayout = new OO.ui.HorizontalLayout( {
} );
// Initialize Height Input Field Set
this.heightInputFieldset = new OO.ui.FieldsetLayout();
// Initialize Weight Input
this.heightInput = new OO.ui.NumberInputWidget({
min: 0,
max: 3,
step: 0.0001,
buttonStep: 0.1,
placeholder: 'Poids',
icon: 'userAvatar'
});
// Set Height Input Field
this.heightInputField = new OO.ui.FieldLayout( this.heightInput, {
label: 'Taille',
align: 'left',
} );
// Add Weight Input Field to Weight Input Field Set
this.heightInputFieldset.addItems( [ this.heightInputField ] );
// Initialize Height Unit Radio Input
this.heightUnitRadioInput = new OO.ui.RadioSelectInputWidget( {
options: [
{ data: 'm', label: 'm' },
{ data: 'pi + po', label: 'pi + po'}
]
} );
// Set Elements to Horizontal Layout
this.heightHorizontalLayout.addItems([this.heightInputFieldset, this.heightUnitRadioInput]);
// Initialize Spacer Label
this.spacerLabel = new OO.ui.LabelWidget( {
label: ' ',
classes: [ 'mw-headline'],
} );
// Initialize Dosage Result Message
this.dosageResultMessage = new OO.ui.MessageWidget( {
type: 'success',
icon: 'labFlask',
label: ''
} );
// Intialize Copy Paste Button
this.copyPasteButton = new OO.ui.ButtonWidget( {
label: 'Copier-coller',
icon: 'copy'
} );
// Add Copy-Paste Button to Dosage Result Message
this.dosageResultMessage.$element.append( this.copyPasteButton.$element );
// Changing CSS
this.weightInputFieldset.$element[0].setAttribute('style', 'width: 75%; margin-bottom: -0.4em;');
this.weightInputField.$element[0].firstChild.firstChild.setAttribute('style', 'width: inherit;');
this.weightInputField.$element[0].firstChild.lastChild.setAttribute('style', 'width: inherit;');
this.heightInputFieldset.$element[0].setAttribute('style', 'width: 75%; margin-bottom: -0.4em;');
this.heightInputField.$element[0].firstChild.firstChild.setAttribute('style', 'width: inherit;');
this.heightInputField.$element[0].firstChild.lastChild.setAttribute('style', 'width: inherit;');
this.dosageResultMessage.$label[0].setAttribute('style', "display:inline-block;");
this.dosageResultMessage.$element[0].lastChild.setAttribute('style', "float:right;");
this.dosageResultMessage.$element[0].lastChild.firstChild.setAttribute("style", "display: inline;");
// Add Weight Horizontal Input, Height Horizontal Input and Dosage Result Label to Panel
this.panel.$element.append( this.weightHorizontalLayout.$element );
this.panel.$element.append( this.heightHorizontalLayout.$element );
this.panel.$element.append( this.spacerLabel.$element );
this.panel.$element.append( this.dosageResultMessage.$element );
// Toggle Dosage Result Message visibility
this.dosageResultMessage.toggle();
// Add Panel to Body
this.$body.append( this.panel.$element );
// Add Event Handler to Weight Input, Height Input, Weight Unit Radio Input and Height Unit Radio Input
this.weightInput.connect( this, { 'change': 'onWeightInputChange' } );
//this.heightInput.connect( this, { 'change': 'onHeightInputChange' } );
this.weightUnitRadioInput.connect( this, { 'change': 'onWeightUnitRadioInputChange' } );
//this.heightUnitRadioInput.connect( this, { 'change': 'onHeightUnitRadioInputChange' } );
this.copyPasteButton.connect( this, { 'click': 'onCopyPasterButtonClick' } );
};
// Specify any additional functionality required by the window (disable opening an empty URL, in this case)
function updateDosageSurfaceResult(dosageDialog){
// TODO: COMPLETE FORMULA HERE
// Get weight input
var weight_input_number = parseFloat(dosageDialog.weightInput.value);
if (!Number.isNaN(weight_input_number) && weight_input_number > 0) {
var multiplier;
if (dosageDialog.unitRadioInput.value === 'kg'){
multiplier = 1.0;
} else {
multiplier = 0.453592;
}
var daily_dose = Math.round(multiplier * dose_per_kg * weight_input_number / frequency_to_division[frequency]);
var dose;
if (max_daily_dose !== 0) {
dose = Math.round((Math.min(max_daily_dose, daily_dose)) / frequency_to_division[frequency]);
} else {
dose = Math.round(daily_dose / frequency_to_division[frequency]);
}
// Update Result Message
var dosageResultMessageString = drug + ' ' + dose.toString() + ' ' + dose_unit + ' ' + roa + ' ' + frequency + ' ' + prn + ((prn) ? ' ' : '' ) + ((duration) ? '×' + ' ' + duration.toString() + ' ' + duration_unit : '');
dosageDialog.dosageResultMessage.setLabel(dosageResultMessageString);
if (!dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle();
} else {
// Update Result Message
dosageDialog.dosageResultMessage.setLabel('');
if (dosageDialog.dosageResultMessage.isVisible()) dosageDialog.dosageResultMessage.toggle();
}
}
DosageSurfaceDialog.prototype.onWeightInputChange = function ( value ) {
updateDosageSurfaceResult(this);
};
DosageSurfaceDialog.prototype.onWeightUnitRadioInputChange = function ( value ) {
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0;
if (this.unitRadioInput.value === 'kg') {
this.weightInput.setValue(Math.round(10 * weight_input_number * 0.453592) / 10);
} else {
this.weightInput.setValue(Math.round(10 * weight_input_number * 2.20462) / 10);
}
};
DosageSurfaceDialog.prototype.onCopyPasterButtonClick = function ( value ) {
// Copy the text inside the text field
navigator.clipboard.writeText(this.dosageResultMessage.label);
};
// Use the getActionProcess() method to specify a process to handle the
// actions (for the 'save' action, in this example).
DosageSurfaceDialog.prototype.getActionProcess = function ( action ) {
var weight_input_number = parseFloat(this.weightInput.value) ? parseFloat(this.weightInput.value) : 0;
var weightUnit = this.weightUnitRadioInput.value;
var broselow_weight = parseFloat(this.dropdownBroselowInput.getValue());
document.cookie = "wikimedica-dosage-weight=" + weight_input_number + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
document.cookie = "wikimedica-dosage-weight-unit=" + weightUnit + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
document.cookie = "wikimedica-dosage-broselow-weight=" + broselow_weight + "; expires=Thu, 18 Dec 2030 12:00:00 UTC; path=/";
var dialog = this;
if ( action ) {
return new OO.ui.Process( function () {
dialog.close( {
action: action
} );
} );
}
// Fallback to parent handler.
return DosageSurfaceDialog.super.prototype.getActionProcess.call( this, action );
};
// Specify the dialog height (or don't to use the automatically generated height).
DosageSurfaceDialog.prototype.getBodyHeight = function () {
// Note that "expanded: false" must be set in the panel's configuration for this to work.
// When working with a stack layout, you can use:
// return this.panels.getCurrentItem().$element.outerHeight( true );
console.log("HERE")
console.log(this.dosageResultMessage.isVisible());
if (this.dosageResultMessage.isVisible()) {
return this.panel.$element.outerHeight( true );
} else {
return this.panel.$element.outerHeight( true ) + 60;
}
};
// Create and append the window manager.
var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
// Create a new dialog window.
var dosageDialog = new DosageSurfaceDialog({
});
// Add windows to window manager using the addWindows() method.
windowManager.addWindows( [ dosageDialog ] );
// Get cookie parameters
var weight_input_number = parseFloat(getCookie('wikimedica-dosage-weight'));
var weightUnit = getCookie('wikimedica-dosage-weight-unit');
var broselow_weight = parseFloat(getCookie('wikimedica-dosage-broselow-weight'));
// Initialize parameters according to cookies
dosageDialog.dropdownBroselowInput.setValue(broselow_weight);
dosageDialog.weightUnitRadioInput.setValue(weightUnit);
dosageDialog.weightInput.setValue(weight_input_number);
// Open the window.
windowManager.openWindow( dosageDialog );
});
};