Obstetric pain timer
What do you spend time on when your lady has obstetric pain?
When my wife was pregnant and about to conceive, we looked for a good Obstetric pain timer. We checked out some apps and some web pages, but none of them really showed us what we wanted and in a way that was usable in a mobile phone. So, I did what every parent to be does in this situation. I started to write some code. =)
Obstetric pain timer (English)
Värktimer (Svenska)
jQuery to pure javascript and an issue with the Edge browser
When I wrote the timer I used jQuery but on my blog I want all my code to be pure javascript, so I rewrote the code. And here you can see the difference between jQuery code and pure javascript.
There is one other thing I noticed though. Foolishly enough I tested the code in the Edge browser, where it failed completely, even though it worked fine in chrome. All the numbers from the timer return as NaN. I ran a lot of tests and searched the Internet for an answer and finally i found this old post that gave me some insights to what might cause the problem. The toLocaleTimeString() returns a string with some non-ascii characters in it, thanks for those Microsoft. When I later tried to use parseInt on the string it failed. I just had to create a RegEx that removed the invisible characters and then it worked in the Edge browser as well. If you encounter this problem, look for the removeNonAscii function in my code.
background: #ff9999;
}
</style>
- <script src="js/jquery-1.3.2.min.js"></script>
<script>
- $(document).ready(function() {
+ // Manage classes in html elements
+ function hasClass(ele,cls) {
+ return !!ele.className.match(new RegExp('(s|^)'+cls+'(s|$)'));
+ }
+
+ function addClass(ele,cls) {
+ if (!hasClass(ele,cls)) { ele.className += " " + cls; }
+ }
+
+ function removeClass(ele,cls) {
+ if (hasClass(ele,cls)) {
+ var reg = new RegExp('(s|^)'+cls+'(s|$)');
+ ele.className=ele.className.replace(reg,' ');
+ }
+ }
+ function insertAfter(newNode, referenceNode) {
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+ }
+ // In IE 11 and Edge the toLocaleTimeString() function adds some non-ascii characters that makes it imposible to do parseInt on the string later
+ function removeNonAscii(str) {
+ var regx = new RegExp("[^u0000-u007F]", "g");
+ return str.replace(regx, '');
+ }
+ document.addEventListener("DOMContentLoaded", function() {
// Init time
var starttime, endtime, duration, frequency, s, e, laststart, l, d, f, ad, af;
var highlightEndOfLabour, highlightStartOfLabour, numberOfdataForAvg;
+ var clock = document.getElementById('clock');
+ var button = document.getElementById('button');
highlightEndOfLabour = 10; // Hur många sekunder innan värken är beräknad att sluta skall klockan byta till grön färg
highlightStartOfLabour = 30; // Hur många sekunder innan värken är beräknad att börja skall klockan byta till röd färg
numberOfdataForAvg = 3; // Hur många av de senaste verkarna skall användas vid beräkning av medeltid på värkar
...
}
function setTime() {
+ var left = document.getElementById('left');
var dt = new Date();
- $('#clock').html(dt.toLocaleTimeString());
- curr = $('#clock').html();
+ // removeNoneAscii is neede in IE11 and Edge browser, otherwise we can not do parseInt on the string later
+ clock.innerHTML = removeNonAscii(dt.toLocaleTimeString());
+ curr = clock.innerHTML;
c = curr.split(':');
c = parseInt(c[0], 10)*60*60 + parseInt(c[1], 10)*60 + parseInt(c[2], 10);
- if ($('#button').attr('class') === 'active') {
+ if (hasClass(button, 'active')) {
tmp = (ad-(c-s));
if (tmp < 0) {
- $('#left').css({color:'#cc0000'});
+ left.style.color = '#cc0000';
tmp = '-' + secToTime(-tmp);
} else {
- $('#left').css({color:'#000000'});
- tmp = secToTime(tmp);
+ if (left !== null) {
+ left.style.color = '#000000';
+ }
+ tmp = secToTime(tmp);
}
- $('#left').html(tmp);
+ if (left !== null) {
+ left.innerHTML = tmp;
+ }
if ((c-s) > (ad-(highlightEndOfLabour+1))) {
- $('#clock').css({color:'#00cc00'});
+ clock.style.color = '#00cc00';
}
} else {
af = parseInt(af, 10);
...
tmp = (af-(c-s))
if (!isNaN(tmp)) {
if (tmp < 0) {
- $('#left').css({color:'#cc0000'});
+ left.style.color = '#cc0000';
tmp = '-' + secToTime(-tmp);
} else {
- $('#left').css({color:'#000000'});
+ left.style.color = '#000000';
tmp = secToTime(tmp);
}
- $('#left').html(tmp);
+ left.innerHTML = tmp;
} else {
- $('#left').html('-');
+ if (left !== null) {
+ left.innerHTML = '-';
+ }
}
if ((c-s) > (af-(highlightStartOfLabour+1))) {
- $('#clock').css({color:'#cc0000'});
+ clock.style.color = '#cc0000';
}
}
...
}
updateTime();
laststart = '';
- $('#button').click(function() {
- if ($('#button').attr('class') === 'active') {
- $('#clock').css({color:'#000000'});
- $('#button').attr('class', 'inactive');
- $('#button').html('Klicka när värken börjar');
- endtime = $('#clock').html();
+ button.addEventListener("click",function() {
+ if (hasClass(button, 'active')) {
+ clock.style.color = '#000000';
+ removeClass(button, 'active');
+ addClass(button, 'inactive');
+ button.innerHTML = 'Klicka när värken börjar';
+ endtime = clock.innerHTML;
// Beräkna tiden i sekunder
e = endtime.split(':');
e = parseInt(e[0], 10)*60*60 + parseInt(e[1], 10)*60 + parseInt(e[2], 10);
...
frequency = '-';
}
// Updatera tabellen
- $('<tr class="rows" d="'+d+'" f="'+f+'"><td>' + starttime + '</td><td>' + endtime + '</td><td>' + duration + '</td><td>' + frequency + '</td></tr>').insertAfter('#titles');
+ var titles = document.getElementById('titles');
+ var newNode = document.createElement('tr');
+ addClass(newNode, 'rows');
+ newNode.setAttribute('d', d);
+ newNode.setAttribute('f', f);
+ //newNode = '<tr class="rows" d="'+d+'" f="'+f+'"><td>' + starttime + '</td><td>' + endtime + '</td><td>' + duration + '</td><td>' + frequency + '</td></tr>';
+ newNode.innerHTML = '<td>' + starttime + '</td><td>' + endtime + '</td><td>' + duration + '</td><td>' + frequency + '</td>';
+ insertAfter(newNode, titles);
laststart = starttime;
// Recalculate avarage
...
dTot = 0;
fCnt = 0;
dCnt = 0;
- $('.rows').each(function() {
+ var rows = document.getElementsByClassName('rows');
+ //rows.each(function() {
+ var i = 0;
+ while (i < rows.length) {
if (cnt > numberOfdataForAvg) {
return false;
}
- if (parseInt($(this).attr('f'), 10) > 0) {
- fTot = fTot + parseInt($(this).attr('f'), 10);
+ if (parseInt(rows[i].getAttribute('f'), 10) > 0) {
+ fTot = fTot + parseInt(rows[i].getAttribute('f'), 10);
fCnt++;
}
- dTot = dTot + parseInt($(this).attr('d'), 10);
+ dTot = dTot + parseInt(rows[i].getAttribute('d'), 10);
dCnt++;
cnt++;
- });
+ i++;
+ }
+ //});
//console.log('Res: f ' + Math.round(fTot/fCnt) + ', d ' + Math.round(dTot/dCnt));
af = parseInt(Math.round(fTot/fCnt), 10);
avgF = secToTime(af);
if (fTot > 0) {} else { avgF = '-'; }
ad = Math.round(dTot/dCnt);
avgD = secToTime(ad);
- $('#avg').html('Genomsnitt längd: ' + avgD + '<br> Genomsnitt frekvens: ' + avgF + '<br><b>Tid kvar: <span id="left"></span></b>');
+ var avg = document.getElementById('avg');
+ avg.innerHTML = 'Genomsnitt längd: ' + avgD + '<br> Genomsnitt frekvens: ' + avgF + '<br><b>Tid kvar: <span id="left"></span></b>';
} else {
- $('#clock').css({color:'#000000'});
- $('#button').attr('class', 'active');
- $('#button').html('Klicka när värken slutar');
- starttime = $('#clock').html();
+ clock.style.color = '#000000';
+ removeClass(button, 'inactive');
+ addClass(button, 'active');
+ button.innerHTML = 'Klicka när värken slutar';
+ starttime = clock.innerHTML;
s = starttime.split(':');
//console.log(starttime + ' ' + s[0]+s[1]+s[2]);
s = parseInt(s[0], 10)*60*60 + parseInt(s[1], 10)*60 + parseInt(s[2], 10);
}
});
- });
+ },false);
</script>
</head>
<body>
- javascript, jquery, edge, tolocaletimestring, software