mirror of
https://github.com/ACSPRI/queXS
synced 2024-04-02 12:12:16 +00:00
974 lines
25 KiB
JavaScript
974 lines
25 KiB
JavaScript
var DOM1;
|
|
$(document).ready(function()
|
|
{
|
|
DOM1 = (typeof document.getElementsByTagName!='undefined');
|
|
if (typeof LEMsetTabIndexes === 'function') { LEMsetTabIndexes(); }
|
|
if (typeof checkconditions!='undefined') checkconditions();
|
|
if (typeof template_onload!='undefined') template_onload();
|
|
prepareCellAdapters();
|
|
// document['onkeypress'] = checkEnter;
|
|
if (typeof(focus_element) != 'undefined')
|
|
{
|
|
$(focus_element).focus();
|
|
}
|
|
$(".question").find("select").each(function () {
|
|
hookEvent($(this).attr('id'),'mousewheel',noScroll);
|
|
});
|
|
|
|
// Keypad functions
|
|
var kp = $("input.num-keypad");
|
|
if(kp.length)
|
|
{
|
|
kp.keypad({
|
|
showAnim: 'fadeIn', keypadOnly: false,
|
|
onKeypress: function(key, value, inst) {
|
|
$(this).trigger('keyup');
|
|
}
|
|
});
|
|
}
|
|
kp = $(".text-keypad");
|
|
if(kp.length)
|
|
{
|
|
var spacer = $.keypad.HALF_SPACE;
|
|
for(var i = 0; i != 8; ++i) spacer += $.keypad.SPACE;
|
|
kp.keypad({
|
|
showAnim: 'fadeIn',
|
|
keypadOnly: false,
|
|
layout: [
|
|
spacer + $.keypad.CLEAR + $.keypad.CLOSE, $.keypad.SPACE,
|
|
'!@#$%^&*()_=' + $.keypad.HALF_SPACE + $.keypad.BACK,
|
|
$.keypad.HALF_SPACE + '`~[]{}<>\\|/' + $.keypad.SPACE + $.keypad.SPACE + '789',
|
|
'qwertyuiop\'"' + $.keypad.HALF_SPACE + $.keypad.SPACE + '456',
|
|
$.keypad.HALF_SPACE + 'asdfghjkl;:' + $.keypad.SPACE + $.keypad.SPACE + '123',
|
|
$.keypad.SPACE + 'zxcvbnm,.?' + $.keypad.SPACE + $.keypad.SPACE + $.keypad.HALF_SPACE + '-0+',
|
|
$.keypad.SHIFT + $.keypad.SPACE_BAR + $.keypad.ENTER],
|
|
onKeypress: function(key, value, inst) {
|
|
$(this).trigger('keyup');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Maxlength for textareas TODO limit to not CSS3 compatible browser
|
|
maxlengthtextarea();
|
|
|
|
// Maps
|
|
$(".location").each(function(index,element){
|
|
var question = $(element).attr('name');
|
|
var coordinates = $(element).val();
|
|
var latLng = coordinates.split(" ");
|
|
var question_id = question.substr(0,question.length-2);
|
|
if ($("#mapservice_"+question_id).val()==1){
|
|
// Google Maps
|
|
if (gmaps[''+question] == undefined) {
|
|
GMapsInitialize(question,latLng[0],latLng[1]);
|
|
}
|
|
}
|
|
else if ($("#mapservice_"+question_id).val()==2){
|
|
// Open Street Map
|
|
if (osmaps[''+question]==undefined) {
|
|
osmaps[''+question] = OSMapInitialize(question,latLng[0],latLng[1]);
|
|
}
|
|
}
|
|
});
|
|
$(".location").live('focusout',function(event){
|
|
var question = $(event.target).attr('name');
|
|
var name = question.substr(0,question.length - 2);
|
|
var coordinates = $(event.target).attr('value');
|
|
var xy = coordinates.split(" ");
|
|
var currentMap = gmaps[question];
|
|
var marker = gmaps['marker__'+question];
|
|
var markerLatLng = new google.maps.LatLng(xy[0],xy[1]);
|
|
geocodeAddress(name, markerLatLng);
|
|
marker.setPosition(markerLatLng);
|
|
currentMap.panTo(markerLatLng);
|
|
});
|
|
|
|
/*replacement for inline javascript for #index */
|
|
/*
|
|
$("#index").parents(".outerframe").addClass("withindex");
|
|
if ($("#index").size() && $("#index .row.current").size()){
|
|
var idx = $("#index");
|
|
var row = $("#index .row.current");
|
|
idx.scrollTop(row.position().top - idx.height() / 2 - row.height() / 2);
|
|
*/
|
|
});
|
|
|
|
function maxlengthtextarea(){
|
|
// Calling this function at document.ready : use maxlength attribute on textarea
|
|
// Can be replaced by inline javascript
|
|
$("textarea[maxlength]").change(function(){ // global solution
|
|
var maxlen=$(this).attr("maxlength");
|
|
if ($(this).val().length > maxlen) {
|
|
$(this).val($(this).val().substring(0, maxlen));
|
|
}
|
|
});
|
|
$("textarea[maxlength]").keyup(function(){ // For copy/paste (not for all browser)
|
|
var maxlen=$(this).attr("maxlength");
|
|
if ($(this).val().length > maxlen) {
|
|
$(this).val($(this).val().substring(0, maxlen));
|
|
}
|
|
});
|
|
$("textarea[maxlength]").keydown(function(event){ // No new key after maxlength
|
|
var maxlen=$(this).attr("maxlength");
|
|
var k =event.keyCode;
|
|
if (($(this).val().length >= maxlen) &&
|
|
!(k == null ||k==0||k==8||k==9||k==13||k==27||k==37||k==38||k==39||k==40||k==46)) {
|
|
// Don't accept new key except NULL,Backspace,Tab,Enter,Esc,arrows,Delete
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
// OSMap
|
|
gmaps = new Object;
|
|
osmaps = new Object;
|
|
zoom = [];
|
|
|
|
// OSMap functions
|
|
function OSMapInitialize(question,lat,lng){
|
|
|
|
map = new OpenLayers.Map("gmap_canvas_" + question);
|
|
map.addLayer(new OpenLayers.Layer.OSM());
|
|
var lonLat = new OpenLayers.LonLat(lat,lng)
|
|
.transform(
|
|
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
|
|
map.getProjectionObject() // to Spherical Mercator Projection
|
|
);
|
|
var zoom=11;
|
|
var markers = new OpenLayers.Layer.Markers( "Markers" );
|
|
map.addLayer(markers);
|
|
markers.addMarker(new OpenLayers.Marker(lonLat));
|
|
map.setCenter (lonLat, zoom);
|
|
return map;
|
|
|
|
}
|
|
|
|
//// Google Maps Functions (for API V3) ////
|
|
|
|
// Initialize map
|
|
function GMapsInitialize(question,lat,lng) {
|
|
|
|
var name = question.substr(0,question.length - 2);
|
|
var latlng = new google.maps.LatLng(lat, lng);
|
|
|
|
var mapOptions = {
|
|
zoom: zoom[name],
|
|
center: latlng,
|
|
mapTypeId: google.maps.MapTypeId.ROADMAP
|
|
};
|
|
|
|
var map = new google.maps.Map(document.getElementById("gmap_canvas_" + question), mapOptions);
|
|
gmaps[''+question] = map;
|
|
|
|
var marker = new google.maps.Marker({
|
|
position: latlng,
|
|
draggable:true,
|
|
map: map,
|
|
id: 'marker__'+question
|
|
});
|
|
gmaps['marker__'+question] = marker;
|
|
|
|
google.maps.event.addListener(map, 'rightclick', function(event) {
|
|
marker.setPosition(event.latLng);
|
|
map.panTo(event.latLng);
|
|
geocodeAddress(name, event.latLng);
|
|
$("#answer"+question).val(Math.round(event.latLng.lat()*10000)/10000 + " " + Math.round(event.latLng.lng()*10000)/10000);
|
|
});
|
|
|
|
google.maps.event.addListener(marker, 'dragend', function(event) {
|
|
//map.panTo(event.latLng);
|
|
geocodeAddress(name, event.latLng);
|
|
$("#answer"+question).val(Math.round(event.latLng.lat()*10000)/10000 + " " + Math.round(event.latLng.lng()*10000)/10000);
|
|
});
|
|
}
|
|
|
|
// Reset map when shown by conditions
|
|
function resetMap(qID) {
|
|
var question = $('#question'+qID+' input.location').attr('name');
|
|
var name = question.substr(0,question.length - 2);
|
|
var coordinates = $('#question'+qID+' input.location').attr('value');
|
|
var xy = coordinates.split(" ");
|
|
if(gmaps[question]) {
|
|
var currentMap = gmaps[question];
|
|
var marker = gmaps['marker__'+question];
|
|
var markerLatLng = new google.maps.LatLng(xy[0],xy[1]);
|
|
marker.setPosition(markerLatLng);
|
|
google.maps.event.trigger(currentMap, 'resize')
|
|
currentMap.setCenter(markerLatLng);
|
|
}
|
|
}
|
|
|
|
// Reverse geocoder
|
|
function geocodeAddress(name, pos) {
|
|
var geocoder = new google.maps.Geocoder();
|
|
|
|
var city = '';
|
|
var state = '';
|
|
var country = '';
|
|
var postal = '';
|
|
|
|
geocoder.geocode({
|
|
latLng: pos
|
|
}, function(results, status) {
|
|
if (status == google.maps.GeocoderStatus.OK && results[0]) {
|
|
$(results[0].address_components).each(function(i, val) {
|
|
if($.inArray('locality', val.types) > -1) {
|
|
city = val.short_name;
|
|
}
|
|
else if($.inArray('administrative_area_level_1', val.types) > -1) {
|
|
state = val.short_name;
|
|
}
|
|
else if($.inArray('country', val.types) > -1) {
|
|
country = val.short_name;
|
|
}
|
|
else if($.inArray('postal_code', val.types) > -1) {
|
|
postal = val.short_name;
|
|
}
|
|
});
|
|
|
|
var location = (results[0].geometry.location);
|
|
}
|
|
getInfoToStore(name, pos.lat(), pos.lng(), city, state, country, postal);
|
|
});
|
|
}
|
|
|
|
// Store address info
|
|
function getInfoToStore(name, lat, lng, city, state, country, postal){
|
|
|
|
var boycott = $("#boycott_"+name).val();
|
|
// 2 - city; 3 - state; 4 - country; 5 - postal
|
|
if (boycott.indexOf("2")!=-1)
|
|
city = '';
|
|
if (boycott.indexOf("3")!=-1)
|
|
state = '';
|
|
if (boycott.indexOf("4")!=-1)
|
|
country = '';
|
|
if (boycott.indexOf("5")!=-1)
|
|
postal = '';
|
|
|
|
$("#answer"+name).val(lat + ';' + lng + ';' + city + ';' + state + ';' + country + ';' + postal);
|
|
}
|
|
|
|
Array.prototype.push = function()
|
|
{
|
|
var n = this.length >>> 0;
|
|
for (var i = 0; i < arguments.length; i++)
|
|
{
|
|
this[n] = arguments[i];
|
|
n = n + 1 >>> 0;
|
|
}
|
|
this.length = n;
|
|
return n;
|
|
};
|
|
|
|
Array.prototype.pop = function() {
|
|
var n = this.length >>> 0, value;
|
|
if (n) {
|
|
value = this[--n];
|
|
delete this[n];
|
|
}
|
|
this.length = n;
|
|
return value;
|
|
};
|
|
|
|
|
|
//defined in group.php & question.php & survey.php, but a static function
|
|
function inArray(needle, haystack)
|
|
{
|
|
for (h in haystack)
|
|
{
|
|
if (haystack[h] == needle)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//defined in group.php & survey.php, but a static function
|
|
function match_regex(testedstring,str_regexp)
|
|
{
|
|
// Regular expression test
|
|
if (str_regexp == '' || testedstring == '') return false;
|
|
pattern = new RegExp(str_regexp);
|
|
return pattern.test(testedstring)
|
|
}
|
|
|
|
function cellAdapter(evt,src)
|
|
{
|
|
var eChild = null, eChildren = src.getElementsByTagName('INPUT');
|
|
var curCount = eChildren.length;
|
|
//This cell contains multiple controls, don't know which to set.
|
|
if (eChildren.length > 1)
|
|
{
|
|
//Some cells contain hidden fields
|
|
for (i = 0; i < eChildren.length; i++)
|
|
{
|
|
if ( ( eChildren[i].type == 'radio' || eChildren[i].type == 'checkbox' ) && eChild == null)
|
|
eChild = eChildren[i];
|
|
else if ( ( eChildren[i].type == 'radio' || eChildren[i].type == 'checkbox' ) && eChild != null)
|
|
{
|
|
//A cell with multiple radio buttons -- unhandled
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
else eChild = eChildren[0];
|
|
|
|
if (eChild && eChild.type == 'radio')
|
|
{
|
|
eChild.checked = true;
|
|
//Make sure the change propagates to the conditions handling mechanism
|
|
if(eChild.onclick) eChild.onclick(evt);
|
|
if(eChild.onchange) eChild.onchange(evt);
|
|
}
|
|
else if (eChild && eChild.type == 'checkbox')
|
|
{
|
|
eChild.checked = !eChild.checked;
|
|
//Make sure the change propagates to the conditions handling mechanism
|
|
if(eChild.onclick) eChild.onclick(evt);
|
|
if(eChild.onchange) eChild.onchange(evt);
|
|
}
|
|
}
|
|
|
|
function prepareCellAdapters()
|
|
{
|
|
if (!DOM1) return;
|
|
var formCtls = document.getElementsByTagName('INPUT');
|
|
var ptr = null;
|
|
var foundTD = false;
|
|
for (var i = 0; i < formCtls.length; i++)
|
|
{
|
|
ptr = formCtls[i];
|
|
if (ptr.type == 'radio' || ptr.type == 'checkbox')
|
|
{
|
|
foundTD = false;
|
|
while (ptr && !foundTD)
|
|
{
|
|
if(ptr.nodeName == 'TD')
|
|
{
|
|
foundTD = true;
|
|
ptr.onclick =
|
|
function(evt){
|
|
return cellAdapter(evt,this);
|
|
};
|
|
continue;
|
|
}
|
|
ptr = ptr.parentNode;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkEnter(e){ //e is event object passed from function invocation
|
|
var evt = e || event;
|
|
|
|
var whi = 0;
|
|
|
|
var counter = 1;
|
|
|
|
|
|
whi = evt.which;
|
|
//alert(evt.which);
|
|
|
|
if (whi >= 49 && whi <= 57) //keys 1-9 select appropriate box
|
|
{
|
|
y = document.getElementsByTagName('input');
|
|
for (var i = 0; i < y.length; i++)
|
|
{
|
|
a = y[i];
|
|
if (a.type == 'checkbox' || a.type == 'radio')
|
|
{
|
|
if (counter == (whi - 48))
|
|
{
|
|
if (a.checked && a.type == 'checkbox')
|
|
{
|
|
a.checked = '';
|
|
}
|
|
else
|
|
{
|
|
a.checked = 'checked';
|
|
}
|
|
}
|
|
counter++;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (whi == 13)
|
|
{
|
|
document.forms[0].submit();
|
|
return false;
|
|
}
|
|
|
|
return document.defaultAction;
|
|
|
|
}
|
|
|
|
function addHiddenField(theform,thename,thevalue)
|
|
{
|
|
var myel = document.createElement('input');
|
|
myel.type = 'hidden';
|
|
myel.name = thename;
|
|
theform.appendChild(myel);
|
|
myel.value = thevalue;
|
|
}
|
|
|
|
function cancelBubbleThis(eventObject)
|
|
{
|
|
if (!eventObject) var eventObject = window.event;
|
|
eventObject.cancelBubble = true;
|
|
if (eventObject && eventObject.stopPropagation) {
|
|
eventObject.stopPropagation();
|
|
}
|
|
}
|
|
|
|
function cancelEvent(e)
|
|
{
|
|
e = e ? e : window.event;
|
|
if(e.stopPropagation)
|
|
e.stopPropagation();
|
|
if(e.preventDefault)
|
|
e.preventDefault();
|
|
e.cancelBubble = true;
|
|
e.cancel = true;
|
|
e.returnValue = false;
|
|
return false;
|
|
}
|
|
|
|
function hookEvent(element, eventName, callback)
|
|
{
|
|
if(typeof(element) == "string")
|
|
element = document.getElementById(element);
|
|
if(element == null)
|
|
return;
|
|
if(element.addEventListener)
|
|
{
|
|
if(eventName == 'mousewheel')
|
|
element.addEventListener('DOMMouseScroll', callback, false);
|
|
element.addEventListener(eventName, callback, false);
|
|
}
|
|
else if(element.attachEvent)
|
|
element.attachEvent("on" + eventName, callback);
|
|
}
|
|
|
|
function noScroll(e)
|
|
{
|
|
e = e ? e : window.event;
|
|
cancelEvent(e);
|
|
}
|
|
|
|
|
|
function getkey(e)
|
|
{
|
|
if (window.event) return window.event.keyCode;
|
|
else if (e) return e.which; else return null;
|
|
}
|
|
|
|
function goodchars(e, goods)
|
|
{
|
|
var key, keychar;
|
|
key = getkey(e);
|
|
if (key == null) return true;
|
|
|
|
// get character
|
|
keychar = String.fromCharCode(key);
|
|
keychar = keychar.toLowerCase();
|
|
goods = goods.toLowerCase();
|
|
|
|
// check goodkeys
|
|
if (goods.indexOf(keychar) != -1)
|
|
return true;
|
|
|
|
// control keys
|
|
if ( key==null || key==0 || key==8 || key==9 || key==27 || key==13 )
|
|
return true;
|
|
|
|
// else return false
|
|
return false;
|
|
}
|
|
|
|
function show_hide_group(group_id)
|
|
{
|
|
var questionCount;
|
|
|
|
// First let's show the group description, otherwise, all its childs would have the hidden status
|
|
$("#group-" + group_id).show();
|
|
// If all questions in this group are conditionnal
|
|
// Count visible questions in this group
|
|
questionCount=$("div#group-" + group_id).find("div[id^='question']:visible").size();
|
|
|
|
if( questionCount == 0 )
|
|
{
|
|
$("#group-" + group_id).hide();
|
|
}
|
|
}
|
|
|
|
function navigator_countdown_btn()
|
|
{
|
|
return $('#movenextbtn, #moveprevbtn, #movesubmitbtn');
|
|
}
|
|
|
|
function navigator_countdown_end()
|
|
{
|
|
navigator_countdown_btn().each(function(i, e)
|
|
{
|
|
e.value = $(e).data('text');
|
|
$(e).attr('disabled', '');
|
|
});
|
|
$(window).data('countdown', null);
|
|
}
|
|
|
|
function navigator_countdown_int()
|
|
{
|
|
var n = $(window).data('countdown');
|
|
if(n)
|
|
{
|
|
navigator_countdown_btn().each(function(i, e)
|
|
{
|
|
e.value = $(e).data('text');
|
|
|
|
// just count-down for delays longer than 1 second
|
|
if(n > 1) e.value += " (" + n + ")";
|
|
});
|
|
|
|
$(window).data('countdown', --n);
|
|
}
|
|
window.setTimeout((n > 0? navigator_countdown_int: navigator_countdown_end), 1000);
|
|
}
|
|
|
|
function navigator_countdown(n)
|
|
{
|
|
$(document).ready(function()
|
|
{
|
|
$(window).data('countdown', n);
|
|
|
|
navigator_countdown_btn().each(function(i, e)
|
|
{
|
|
$(e).data('text', e.value);
|
|
});
|
|
|
|
navigator_countdown_int();
|
|
});
|
|
}
|
|
|
|
function std_onsubmit_handler()
|
|
{
|
|
// disable double-posts in all forms
|
|
$('#moveprevbtn, #movenextbtn, #movesubmitbtn').attr('disabled', 'disabled');
|
|
return true;
|
|
}
|
|
|
|
// round function from phpjs.org
|
|
function round (value, precision, mode) {
|
|
// http://kevin.vanzonneveld.net
|
|
var m, f, isHalf, sgn; // helper variables
|
|
precision |= 0; // making sure precision is integer
|
|
m = Math.pow(10, precision);
|
|
value *= m;
|
|
sgn = (value > 0) | -(value < 0); // sign of the number
|
|
isHalf = value % 1 === 0.5 * sgn;
|
|
f = Math.floor(value);
|
|
|
|
if (isHalf) {
|
|
switch (mode) {
|
|
case 'PHP_ROUND_HALF_DOWN':
|
|
value = f + (sgn < 0); // rounds .5 toward zero
|
|
break;
|
|
case 'PHP_ROUND_HALF_EVEN':
|
|
value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
|
|
break;
|
|
case 'PHP_ROUND_HALF_ODD':
|
|
value = f + !(f % 2); // rounds .5 towards the next odd integer
|
|
break;
|
|
default:
|
|
value = f + (sgn > 0); // rounds .5 away from zero
|
|
}
|
|
}
|
|
|
|
return (isHalf ? value : Math.round(value)) / m;
|
|
}
|
|
|
|
// ==========================================================
|
|
// totals
|
|
|
|
function multi_set(ids,_radix)
|
|
{
|
|
//quick ie check
|
|
var ie=(navigator.userAgent.indexOf("MSIE")>=0)?true:false;
|
|
//match for grand
|
|
var _match_grand = new RegExp('grand');
|
|
//match for total
|
|
var _match_total = new RegExp('total');
|
|
var radix = _radix; // comma, period, X (for not using numbers only)
|
|
var numRegex = new RegExp('[^-' + radix + '0-9]','g');
|
|
//main function (obj)
|
|
//id = wrapper id
|
|
function multi_total(id)
|
|
{
|
|
if(!document.getElementById(id)){return;};
|
|
//alert('multi total called value ' + id);
|
|
//generic vars
|
|
//grand total 0 = none, 1 = horo, 2 = vert set if grand found
|
|
var _grand = 0;
|
|
//multi array holder
|
|
var _bits = new Array();
|
|
|
|
//var _obj = document.getElementById(id);
|
|
//grab the tr's
|
|
var _obj = document.getElementById(id);//.getElementsByTagName('table');
|
|
|
|
//alert(_obj.length);
|
|
var _tr = _obj.getElementsByTagName('tr');
|
|
//counter used in top level of _bits array
|
|
var _counter = 0;
|
|
//generic for vars
|
|
var _i = 0;
|
|
var _l = _tr.length;
|
|
for(_i=0; _i<_l; _i++)
|
|
{
|
|
//check we really have inputs to deal with
|
|
if(_tr[_i].getElementsByTagName('input'))
|
|
{
|
|
var _td = _tr[_i].getElementsByTagName('td');
|
|
//start building some nice arrays
|
|
_bits.push(new Array());
|
|
//clear the vert var set when total found in tr
|
|
var vert =false;
|
|
if(_tr[_i].className && _tr[_i].className.match(_match_total,'ig'))
|
|
{
|
|
//will need to set it up vertical
|
|
vert = true;
|
|
};
|
|
//generic for vars for second level _bits[_i]
|
|
var _a=0;
|
|
var _al = _td.length;
|
|
//alert(_al + ' ' + _i);
|
|
if(_al > 0)
|
|
{
|
|
// //counter for inner array
|
|
var _tcounter=0;
|
|
for(_a=0; _a < _al; _a++)
|
|
{
|
|
//only bother if we have inputs
|
|
if(_td[_a].getElementsByTagName('input'))
|
|
{
|
|
//grab the first text input
|
|
var _tdin = first_text(_td[_a].getElementsByTagName('input'));
|
|
//check we got a text input
|
|
if(_tdin)
|
|
{
|
|
//add it to the array @ counter
|
|
_bits[_counter].push(_tdin);
|
|
//set key board actions
|
|
_tdin.onkeyup = calc;
|
|
//check for total and grand total
|
|
if(_td[_a].className && _td[_a].className.match(_match_total,'ig'))
|
|
{
|
|
//clear the key events with false returns
|
|
_tdin.onkeydown = dummy;
|
|
_tdin.onkeyup = dummy;
|
|
//need to check for grand
|
|
if(_td[_a].className.match(_match_grand,'ig'))
|
|
{
|
|
//set up a grand total
|
|
if(vert && _bits[_counter].length > 1)
|
|
{
|
|
_grand=1;
|
|
//run calc across last row
|
|
calc_horo(_bits.length - 1);
|
|
}
|
|
else
|
|
{
|
|
_grand=2;
|
|
_bits[_counter][_bits[0].length - 1]=_bits[_counter][0];
|
|
//run calc on last col
|
|
calc_vert(_bits[0].length - 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//set up horo
|
|
horo_set_up(_counter);
|
|
};
|
|
|
|
};
|
|
if(vert && _grand == 0)
|
|
{
|
|
//deal with vert calc and clear the keyboard action
|
|
_tdin.onkeydown = dummy;
|
|
_tdin.onkeyup = dummy;
|
|
vert_set_up(_tcounter);
|
|
|
|
};
|
|
_tcounter++;
|
|
};
|
|
};
|
|
|
|
};
|
|
//check we got some thing that time
|
|
if(_bits[_counter].length == 0)
|
|
{
|
|
_bits.pop();
|
|
}
|
|
else
|
|
{
|
|
_counter++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//remove blanks
|
|
_bits.pop();
|
|
}
|
|
|
|
};
|
|
};
|
|
//returns the first text input or false
|
|
function first_text(arr)
|
|
{
|
|
var i=0;
|
|
var l=arr.length;
|
|
for(i=0; i<l; i++)
|
|
{
|
|
if(arr[i].getAttribute('type') && arr[i].getAttribute('type') == 'text')
|
|
{
|
|
return(arr[i]);
|
|
}
|
|
}
|
|
return(false);
|
|
}
|
|
//sets up the horizontal calc
|
|
function horo_set_up(id)
|
|
{
|
|
//make all in the row update the final
|
|
//alert('set horo called for row ' + id);
|
|
|
|
var i=0;
|
|
var l=_bits[id].length;
|
|
var qt=0;
|
|
for(i=0; i<l; i++)
|
|
{
|
|
var addaclass=!_bits[id][i].getAttribute(ie ? 'className' : 'class') ? '' : _bits[id][i].getAttribute(ie ? 'className' : 'class') + ' ';
|
|
_bits[id][i].setAttribute((ie ? 'className' : 'class'), addaclass + 'horo_' + id);
|
|
_bits[id][i].onkeyup = calc;
|
|
if(i == (l - 1))
|
|
{
|
|
_bits[id][i].value = round(qt,12)
|
|
}
|
|
else if(_bits[id][i].value)
|
|
{
|
|
_aval=_bits[id][i].value;
|
|
if (radix===',') {
|
|
_aval = _aval.split(',').join('.');
|
|
_bits[id][i].value = _aval.split('.').join(',');
|
|
}
|
|
if (_aval == parseFloat(_aval)) {
|
|
qt += +_aval;
|
|
}
|
|
};
|
|
};
|
|
|
|
}
|
|
//sets up the vertical calc
|
|
function vert_set_up(id)
|
|
{
|
|
//alert('set vert called for col ' + id + ' ' + _bits.join('-'));
|
|
id *= 1;
|
|
var i=0;
|
|
var l=_bits.length;
|
|
var qt = 0;
|
|
for(i=0; i<l; i++)
|
|
{
|
|
var addaclass=!_bits[i][id].getAttribute(ie ? 'className' : 'class') ? '' : _bits[i][id].getAttribute(ie ? 'className' : 'class') + ' ';
|
|
_bits[i][id].setAttribute((ie ? 'className' : 'class'), addaclass + 'vert_' + id);
|
|
_bits[i][id].onkeyup = calc;
|
|
if(i == (l - 1))
|
|
{
|
|
_bits[i][id].value = round(qt,12);
|
|
}
|
|
else if(_bits[i][id].value)
|
|
{
|
|
_aval=_bits[i][id].value;
|
|
if (radix===',') {
|
|
_aval = _aval.split(',').join('.');
|
|
_bits[i][id].value = _aval.split('.').join(',');
|
|
}
|
|
if (_aval == parseFloat(_aval)) {
|
|
qt += +_aval;
|
|
}
|
|
};
|
|
};
|
|
};
|
|
//calculates a row or col or both
|
|
//runs the grand totals if required
|
|
function calc(e)
|
|
{
|
|
//alert('calc called ');
|
|
e=(e)?e:event;
|
|
var el=e.target||e.srcElement;
|
|
var _id=el.getAttribute(ie ? 'className' : 'class');
|
|
|
|
// eliminate bad numbers
|
|
_aval=new String(el.value);
|
|
if (radix!=='X') {
|
|
_aval=_aval.replace(numRegex,'');
|
|
}
|
|
if (radix===',') {
|
|
_aval = _aval.split(',').join('.');
|
|
}
|
|
if (radix!=='X' && _aval != '-' && _aval != '.' && _aval != '-.' && _aval != parseFloat(_aval)) {
|
|
_aval = "";
|
|
}
|
|
if (radix===',') {
|
|
el.value = _aval.split('.').join(',');
|
|
}
|
|
else if (radix!=='X') {
|
|
el.value = _aval;
|
|
}
|
|
|
|
//vert_[id] horo_[id] in class trigger vert or horo calc on row[id]
|
|
if(_id.match('vert_','ig'))
|
|
{
|
|
var vid = get_an_id(_id,'vert_');
|
|
calc_vert(vid);
|
|
};
|
|
if(_id.match('horo_','ig'))
|
|
{
|
|
var hid = get_an_id(_id,'horo_');
|
|
calc_horo(hid);
|
|
};
|
|
//check for grand total
|
|
switch(_grand)
|
|
{
|
|
case 1:
|
|
//run calc across last row
|
|
calc_horo(_bits.length - 1);
|
|
break;
|
|
case 2:
|
|
//run calc on last col
|
|
calc_vert(_bits[0].length - 1);
|
|
break;
|
|
}
|
|
checkconditions($(el).val(), $(el).attr('name'), $(el).attr('type'));
|
|
return(true);
|
|
};
|
|
//retuns the id from end of string like 'vert_[id] horo_[id] other class'
|
|
//_id = string
|
|
//_break = string to break @
|
|
function get_an_id(_id,_break)
|
|
{
|
|
var id = _id.split(_break);
|
|
id[1] = id[1].split(' ');
|
|
return(id[1][0] * 1);
|
|
};
|
|
//run vert calc on col[vid]
|
|
function calc_vert(vid)
|
|
{
|
|
var i=0;
|
|
var l=_bits.length;
|
|
var qt = 0;
|
|
//get or set the last ones id
|
|
for(i=0; i<l; i++)
|
|
{
|
|
if(i == (l - 1))
|
|
{
|
|
//check if sum is a number
|
|
if(isNaN(qt))
|
|
{
|
|
_bits[i][vid].value = "Not a number";
|
|
}
|
|
else
|
|
{
|
|
_bits[i][vid].value = round(qt,12);
|
|
}
|
|
}
|
|
else if(_bits[i][vid].value)
|
|
{
|
|
_aval=_bits[i][vid].value;
|
|
if (radix===',') {
|
|
_aval = _aval.split(',').join('.');
|
|
}
|
|
if (_aval == parseFloat(_aval)) {
|
|
qt += +_aval;
|
|
}
|
|
};
|
|
};
|
|
|
|
};
|
|
//run horo calc on row[hid]
|
|
function calc_horo(hid)
|
|
{
|
|
var i=0;
|
|
var l=_bits[hid].length;
|
|
var qt=0;
|
|
for(i=0; i<l; i++)
|
|
{
|
|
if(i == (l - 1))
|
|
{
|
|
if (isNaN(qt))
|
|
{
|
|
_bits[hid][i].value = "Not a number"
|
|
}
|
|
else
|
|
{
|
|
_bits[hid][i].value = round(qt,12);
|
|
}
|
|
}
|
|
else if(_bits[hid][i].value)
|
|
{
|
|
_aval=_bits[hid][i].value;
|
|
if (radix===',') {
|
|
_aval = _aval.split(',').join('.');
|
|
}
|
|
if (_aval == parseFloat(_aval)) {
|
|
qt += +_aval;
|
|
}
|
|
};
|
|
};
|
|
};
|
|
//clear key input
|
|
function dummy(e)
|
|
{
|
|
return(false);
|
|
};
|
|
};
|
|
//set up the dom
|
|
//alert('multi called called value ' + ids);
|
|
ids = ids.split(',');
|
|
//generic for vars
|
|
var ii = 0;
|
|
var ll=ids.length;
|
|
//object place holder
|
|
var _collection=new Array();
|
|
|
|
for(ii=0; ii<ll; ii++)
|
|
{
|
|
//run main function per id
|
|
_collection.push(new multi_total(ids[ii]));
|
|
}
|
|
}
|
|
|
|
//Special function for array dual scale in drop down layout to check conditions
|
|
function array_dual_dd_checkconditions(value, name, type, rank, condfunction)
|
|
{
|
|
if (value == '') {
|
|
//If value is set to empty, reset both drop downs and check conditions
|
|
if (rank == 0) { dualname = name.replace(/#0/g,"#1"); }
|
|
else if (rank == 1) { dualname = name.replace(/#1/g,"#0"); }
|
|
document.getElementsByName(dualname)[0].value=value;
|
|
condfunction(value, dualname, type);
|
|
}
|
|
condfunction(value, name, type);
|
|
}
|
|
|
|
// Maxlength for textareas
|
|
function textLimit(field, maxlen) {
|
|
if (document.getElementById(field).value.length > maxlen) {
|
|
document.getElementById(field).value = document.getElementById(field).value.substring(0, maxlen);
|
|
}
|
|
}
|