Created
August 28, 2018 05:07
-
-
Save jnothman/f2cae6c8a957a0c98e71240bfefb9832 to your computer and use it in GitHub Desktop.
Stoichiometry widget for LabArchives
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Stoichiometry Widget implemented by Joel Nothman at the Sydney Informatics Hub | |
Copyright (c) 2018, The University of Sydney | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright | |
notice, this list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright | |
notice, this list of conditions and the following disclaimer in the | |
documentation and/or other materials provided with the distribution. | |
3. All advertising materials mentioning features or use of this software | |
must display the following acknowledgement: | |
This product includes software developed by the University of Sydney. | |
4. Neither the name of the University of Sydney nor the | |
names of its contributors may be used to endorse or promote products | |
derived from this software without specific prior written permission. | |
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY | |
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | |
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
my_widget_script = | |
{ | |
init:function (mode, json_data) { | |
//this method is called when the form is being constructed | |
// parameters | |
// mode = if it equals 'view' than it should not be editable | |
// if it equals 'edit' then it will be used for entry | |
// if it equals 'view_dev' same as view, does some additional checks that may slow things down in production | |
// if it equals 'edit_dev' same as edit, does some additional checks that may slow things down in production | |
// json_data will contain the data to populate the form with, it will be in the form of the data | |
// returned from a call to to_json or empty if this is a new form. | |
//By default it calls the parent_class's init. | |
//TO DO write code specific to your form | |
this.parent_class.init(mode, json_data); | |
if (mode.indexOf('view') > -1) { | |
var isEmpty = function(tr) { | |
var inputs = $('input', tr); | |
for (var i = 0; i < inputs.length; i++) { | |
if ($(inputs[i]).val()) { | |
return false; | |
} | |
} | |
return true; | |
} | |
$('#the_form tbody tr').each(function() { | |
if (isEmpty(this)) { | |
$(this).remove(); | |
} | |
}) | |
return; | |
} | |
var nFixed = 2; | |
$('#the_form input[name^=amount]').on('keyup change', function() { | |
var tr = $(this).closest('tr'); | |
var equiv = $('input[name^=equivalents]', tr); | |
if (equiv.length != 1) | |
throw ('Found the incorrect number of equiv inputs: ' + equiv.length) | |
equiv = equiv.first(); | |
var moles1 = $('#the_form input[name=moles1_formula]'); | |
var fw = $('input[name^=fw]', tr); | |
if ($(this).val() && fw.val() && moles1.val()) | |
equiv.val(($(this).val() / fw.val() / moles1.val()).toFixed(nFixed)) | |
}); | |
$('#the_form input[name^=fw]').on('keyup change', function() { | |
var tr = $(this).closest('tr'); | |
var amount = $('input[name^=amount]', tr); | |
var fw = $('input[name^=fw]', tr); | |
var moles = $('input[name^=moles]', tr); | |
var equiv = $('input[name^=equivalents]', tr); | |
if (moles.val() && fw.val()) { | |
amount.val((moles.val() * fw.val()).toFixed(nFixed)) | |
} | |
}); | |
$('#the_form input[name^=fw]').on('change', function() { | |
var tr = $(this).closest('tr'); | |
var amount = $('input[name^=amount]', tr); | |
var equiv = $('input[name^=equivalents]', tr); | |
if (!equiv.val()) { | |
amount.change(); | |
} | |
}); | |
$('#the_form input[name^=equivalents]').on('keyup change', function() { | |
var tr = $(this).closest('tr'); | |
var amount = $('input[name^=amount]', tr); | |
var fw = $('input[name^=fw]', tr); | |
var moles = $('input[name^=moles]', tr); | |
var moles1 = $('#the_form input[name=moles1_formula]'); | |
var equiv = $('input[name^=equivalents]', tr); | |
if (equiv.val() && fw.val() && moles1.val()) { | |
moles.val((moles1.val() * equiv.val()).toFixed(nFixed)); | |
fw.change(); | |
} | |
}); | |
}, | |
to_json:function () { | |
//should return a json string containing the data entered into the form by the user | |
//whatever is return from the method is persisted in LabArchives. must not be binary data. | |
//called when the user hits the save button, when adding or editing an entry | |
//TO DO write code specific to your form | |
return this.parent_class.to_json(); | |
}, | |
from_json:function (json_data) { | |
//populates the form with json_data | |
//TO DO write code specific to your form | |
this.parent_class.from_json(json_data); | |
}, | |
test_data:function () { | |
//during development this method is called to populate your form while in preview mode | |
//TO DO write code specific to your form | |
return this.parent_class.test_data(); | |
}, | |
is_valid:function (b_suppress_message) { | |
//called when the user hits the save button, to allow for form validation. | |
//returns an array of dom elements that are not valid - default is those elements marked as mandatory | |
// that have no data in them. | |
//You can modify this method, to highlight bad form elements etc... | |
//LA calls this method with b_suppress_message and relies on your code to communicate issues to the user | |
//Returning an empty array [] or NULL equals no error | |
//TO DO write code specific to your form | |
return this.parent_class.is_valid(b_suppress_message); | |
}, | |
is_edited:function () { | |
//should return true if the form has been edited since it was loaded or since reset_edited was called | |
return this.parent_class.is_edited(); | |
}, | |
reset_edited:function () { | |
//typically called have a save | |
//TO DO write code specific to your form | |
return this.parent_class.reset_edited(); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<table border="0" cellpadding="1" cellspacing="1" height="100" style="font-family: Times;" width="930"> | |
<thead> | |
<tr> | |
<th scope="col" style="width: 35px;"><strong>Substance</strong></th> | |
<th scope="col" style="width: 8px;"><strong>Amount<br /> | |
(mg)</strong></th> | |
<th scope="col" style="width: 8px;"><strong>FW<br /> | |
(g/mol)</strong></th> | |
<th scope="col" style="width: 8px;"><strong>Moles<br /> | |
(mmol)</strong></th> | |
<th scope="col" style="width: 5px;"><strong>Equiv.</strong></th> | |
<th scope="col" style="width: 8px;"><strong>Volume<br /> | |
(uL)</strong></th> | |
<th scope="col" style="width: 5px;"><strong>Density<br /> | |
(g/mL)</strong></th> | |
<th scope="col" style="width: 35px;"><strong>Comments</strong></th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance1" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount1_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw1_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles1_formula" size="8" type="text" value="(#{amount1_number}/#{fw1_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents1_number" size="5" type="text" value="1" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume1_formula" size="8" type="text" value="(#{amount1_number}/#{density1_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density1_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments1" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance2" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount2_number" size="8" type="text" value="" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw2_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles2_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents2_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents2_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume2_formula" size="8" type="text" value="(#{amount2_number}/#{density2_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density2_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments2" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance3" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount3_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw3_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles3_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents3_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents3_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume3_formula" size="8" type="text" value="(#{amount3_number}/#{density3_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density3_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments3" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance4" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount4_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw4_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles4_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents4_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents4_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume4_formula" size="8" type="text" value="(#{amount4_number}/#{density4_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density4_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments4" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance5" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount5_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw5_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles5_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents5_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents5_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume5_formula" size="8" type="text" value="(#{amount5_number}/#{density5_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density5_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments5" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance6" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount6_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw6_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles6_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents6_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents6_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume6_formula" size="8" type="text" value="(#{amount6_number}/#{density6_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density6_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments6" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance7" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount7_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw7_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles7_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents7_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents7_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume7_formula" size="8" type="text" value="(#{amount7_number}/#{density7_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density7_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments7" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance8" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount8_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw8_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles8_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents8_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents8_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume8_formula" size="8" type="text" value="(#{amount8_number}/#{density8_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density8_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments8" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance9" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount9_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw9_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles9_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents9_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents9_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume9_formula" size="8" type="text" value="(#{amount9_number}/#{density9_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density9_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments9" size="35" type="text" /></th> | |
</tr> | |
<tr> | |
<th scope="col" style="text-align: left; width: 35px;"><input name="substance10" size="35" type="text" /></th> | |
<td scope="col" style="text-align: right; width: 8px;"><input name="amount10_number" size="8" type="text" /></td> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="fw10_number" size="8" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="moles10_formula" size="8" type="text" value="(#{moles1_formula}*#{equivalents10_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="equivalents10_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right; width: 8px;"><input name="volume10_formula" size="8" type="text" value="(#{amount10_number}/#{density10_number}).toFixed(2)" /></th> | |
<th scope="col" style="text-align: right; width: 5px;"><input name="density10_number" size="5" type="text" /></th> | |
<th scope="col" style="text-align: right;"><input name="comments10" size="35" type="text" /></th> | |
</tr> | |
</tbody> | |
</table> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Migrating to https://github.com/Sydney-Informatics-Hub/labarchives-stoichiometry-widget