function validationMessages() { validationMessages.vocab = {}; validationMessages.vocab['name'] = ''; validationMessages.vocab['rooms'] = ''; for (var key in validationMessages.vocab) { validationMessages.vocab[key] = $("label[for=" + key + "]").html(); validationMessages.vocab[key] = '"' + validationMessages.vocab[key].replace(/:$/, '') + '" '; validationMessages.vocab[key] += 'is a mandatory field, please supply a value.'; var field = document.getElementById(key); if (field.setCustomValidity && field.willValidate) { $(field).bind('validate', function(e) { e.target.setCustomValidity(""); if (!e.target.validity.valid) { e.target.setCustomValidity(validationMessages.vocab[$(e.target).attr('id')]); } }); $(field).filter('select, [type="checkbox"]').bind('change', function(e) { $(this).trigger('validate'); }); $(field).not('select, [type="checkbox"]').bind('input', function(e) { $(this).trigger('validate'); }); $(field).trigger('validate'); } } } function validate(form) { var testInput = document.createElement("input"); var testSelect = document.createElement("select"); var validForm = true; if (!("pattern" in testInput) || !("required" in testInput)) { form.find('input').not('[type="checkbox"]').each(function() { var id = $(this).attr('id'); if (validationMessages.vocab[id]) { if (/(^$)|(^\s+$)/.test($(this).val())) { alert(validationMessages.vocab[id]); validForm = false; return false; } } }); if (!validForm) { return false; } } if (!("required" in testInput)) { form.find('input').filter('[type="checkbox"]').each(function() { var id = $(this).attr('id'); if (validationMessages.vocab[id]) { if (!$(this).is(':checked')) { alert(validationMessages.vocab[id]); validForm = false; return false; } } }); if (!validForm) { return false; } } form.find('textarea').each(function() { var id = $(this).attr('id'); if (validationMessages.vocab[id]) { if (/(^$)|(^\s+$)/.test($(this).val())) { alert(validationMessages.vocab[id]); validForm = false; return false; } } }); if (!validForm) { return false; } if (!("required" in testSelect)) { form.find('select').each(function() { var id = $(this).attr('id'); if (validationMessages.vocab[id]) { if ($(this).val() == '') { alert(validationMessages.vocab[id]); validForm = false; return false; } } }); if (!validForm) { return false; } } var formEl = form.get(0); var dateDiff = getDateDifference(formEl); if (dateDiff < 0) { alert("Error: the start day cannot be after the end day."); return false; } if (!("min" in testInput) || !(("step" in testInput))) { if ((form.find('input:radio[name=rep_type]:checked').val() == 6) && (form.find('#rep_num_weeks').val() < 2)) { alert("You have not entered a\nuseful n-weekly value."); return false; } } form.find('input[type=submit]').attr('disabled', 'disabled'); return true; } function getFormValue(formInput) { var value; if (formInput.attr('name').indexOf('[]') == -1) { if (formInput.filter(':checkbox').length > 0) { value = formInput.is(':checked') ? '1' : ''; } else if (formInput.filter(':radio').length > 0) { value = formInput.filter(':checked').val(); } else { value = formInput.val(); } } else { value = []; formInput.each(function(index) { if ((formInput.filter(':checkbox').length == 0) || $(this).is(':checked')) { var thisValue = $(this).val(); if ($.isArray(thisValue)) { $.merge(value, thisValue); } else { value.push($(this).val()); } } }); } return value; } function checkConflicts(optional) { if (checkConflicts.nOutstanding === undefined) { checkConflicts.nOutstanding = 0; } if (optional && checkConflicts.nOutstanding) { return; } var timeout = 200; window.setTimeout(function() { var params = {'ajax': 1}; var form = $('form#main'); if ((form.length == 0) || form.data('submit')) { return; } var relevantFields = form.find('[name]').not(':disabled, [type="submit"], [type="button"], [type="image"]'); relevantFields.each(function() { var fieldName = $(this).attr('name'); if (params[fieldName] === undefined) { params[fieldName] = getFormValue(relevantFields.filter('[name=' + fieldName.replace('[', '\\[').replace(']', '\\]') + ']')); } }); $.each(params, function(i, val) { if ((typeof(val) == 'object') && ((val === null) || (val.length == 0))) { delete params[i]; } }); checkConflicts.nOutstanding++; $.post('edit_entry_handler.php', params, function(result) { checkConflicts.nOutstanding--; var conflictDiv = $('#conflict_check'); var scheduleDetails = $('#schedule_details'); var policyDetails = $('#policy_details'); var checkMark = "\u2714"; var cross = "\u2718"; var titleText, detailsHTML; if (result.conflicts.length == 0) { conflictDiv.text(checkMark).attr('class', 'good'); titleText = 'No scheduling conflicts'; detailsHTML = titleText; } else { conflictDiv.text(cross).attr('class', 'bad'); detailsHTML = "

"; titleText = 'The new booking will conflict with the following entries' + ": \n\n"; detailsHTML += titleText + "<\/p>"; var conflictsList = getErrorList(result.conflicts); detailsHTML += conflictsList.html; titleText += conflictsList.text; } conflictDiv.attr('title', titleText); scheduleDetails.html(detailsHTML); var policyDiv = $('#policy_check'); if (result.rules_broken.length == 0) { policyDiv.text(checkMark).attr('class', 'good'); titleText = 'No policy conflicts'; detailsHTML = titleText; } else { policyDiv.text(cross).attr('class', 'bad'); detailsHTML = "

"; titleText = 'The new booking will conflict with the following policies' + ": \n\n"; detailsHTML += titleText + "<\/p>"; var rulesList = getErrorList(result.rules_broken); detailsHTML += rulesList.html; titleText += rulesList.text; } policyDiv.attr('title', titleText); policyDetails.html(detailsHTML); }, 'json'); }, timeout); } var nStartOptions = []; var nEndOptions = []; var startOptions = []; var endOptions = []; var vocab = []; var prevStartValue; function durFormat(r) { r = r.toFixed(2); r = parseFloat(r); r = r.toLocaleString(); if ((r.indexOf('.') >= 0) || (r.indexOf(',') >= 0)) { while (r.substr(r.length -1) == '0') { r = r.substr(0, r.length - 1); } if ((r.substr(r.length -1) == '.') || (r.substr(r.length -1) == ',')) { r = r.substr(0, r.length - 1); } } return r; } function getDuration(from, to, days) { var duration, durUnits; var text = ''; var enablePeriods = areas[currentArea]['enable_periods']; durUnits = (enablePeriods) ? 'periods' : 'minutes'; duration = to - from; duration = Math.floor((to - from) / 60); if (duration < 0) { days--; if (enablePeriods) { duration += nEndOptions[currentArea]; } else { duration += 24*60; } } if (enablePeriods) { duration++; } else { if (duration >= 60) { durUnits = "hours"; duration = durFormat(duration/60); } } if (days != 0) { text += days + ' '; text += (days == 1) ? vocab['days']['singular'] : vocab['days']['plural']; if (duration != 0) { text += ', '; } } if (duration != 0) { text += duration + ' '; text +=(duration == 1) ? vocab[durUnits]['singular'] : vocab[durUnits]['plural']; } return text; } function getDateDifference(form) { var diff; var startDay = parseInt(form.start_datepicker_alt_day.value, 10); var startMonth = parseInt(form.start_datepicker_alt_month.value, 10); var startYear = parseInt(form.start_datepicker_alt_year.value, 10); var startDate = new Date(startYear, startMonth - 1, startDay, 12); var endDay = parseInt(form.end_datepicker_alt_day.value, 10); var endMonth = parseInt(form.end_datepicker_alt_month.value, 10); var endYear = parseInt(form.end_datepicker_alt_year.value, 10); var endDate = new Date(endYear, endMonth - 1, endDay, 12); diff = (endDate - startDate)/(24 * 60 * 60 * 1000); diff = Math.round(diff); return diff; } function adjustSlotSelectors(form, oldArea, oldAreaStartValue, oldAreaEndValue) { if (!form) { return; } var area = currentArea; var enablePeriods = areas[area]['enable_periods']; var maxDurationEnabled = areas[area]['max_duration_enabled']; var maxDurationSecs = areas[area]['max_duration_secs']; var maxDurationPeriods = areas[area]['max_duration_periods']; var maxDurationQty = areas[area]['max_duration_qty']; var maxDurationUnits = areas[area]['max_duration_units']; var isSelected, i, j, option, duration, defaultDuration, maxDuration; var nbsp = '\u00A0'; var errorText = 'Start day after end day'; var text = errorText; var startId = "start_seconds" + area; var startSelect = form[startId]; var startKeepDisabled = ($('#' + startId).attr('class') == 'keep_disabled'); var endId = "end_seconds" + area; var endSelect = form[endId]; var endKeepDisabled = ($('#' + endId).attr('class') == 'keep_disabled'); var allDayId = "all_day" + area; var allDay = form[allDayId]; var allDayKeepDisabled = $('#' + allDayId).hasClass('keep_disabled'); var startIndex, startValue, endIndex, endValue; if (allDay && allDay.checked) { startValue = startOptions[area][0]['value'] endValue = endOptions[area][nEndOptions[area] - 1]['value']; if (oldArea != null) { startSelect.disabled = true; endSelect.disabled = true; } } else if ((oldArea != null) && (oldAreaStartValue != null) && (oldAreaStartValue != null)) { if (areas[oldArea]['enable_periods'] == areas[area]['enable_periods']) { option = startOptions[area]; for (i = nStartOptions[area] - 1; i >= 0; i--) { if ((i == 0) || (option[i]['value'] <= oldAreaStartValue)) { startValue = option[i]['value']; break; } } option = endOptions[area]; for (i = 0; i < nEndOptions[area]; i++) { if ((i == nEndOptions[area] - 1) || (option[i]['value'] >= oldAreaEndValue)) { endValue = option[i]['value']; break; } } } else { startValue = startOptions[area][0]['value']; if (enablePeriods) { endValue = startValue; } else { if ((areas[area]['default_duration'] == null) || (areas[area]['default_duration'] == 0)) { defaultDuration = 60 * 60; } else { defaultDuration = areas[area]['default_duration']; } endValue = startValue + defaultDuration; endValue = Math.min(endValue, endOptions[area][nEndOptions[area] - 1]['value']); } } } else { startIndex = startSelect.selectedIndex; startValue = parseInt(startSelect.options[startIndex].value, 10); endIndex = endSelect.selectedIndex; endValue = parseInt(endSelect.options[endIndex].value, 10); if (prevStartValue) { endValue = endValue + (startValue - prevStartValue); endValue = Math.min(endValue, endOptions[area][nEndOptions[area] - 1]['value']); } } prevStartValue = startValue; var dateDifference = getDateDifference(form); if (!allDay || !allDay.checked) { var newState = (dateDifference < 0); startSelect.disabled = newState || startKeepDisabled; endSelect.disabled = newState || endKeepDisabled; if (allDay) { allDay.disabled = newState || allDayKeepDisabled; } } while (startSelect.options.length > 0) { startSelect.remove(0); } for (i = 0; i < nStartOptions[area]; i++) { isSelected = (startOptions[area][i]['value'] == startValue); if (dateDifference >= 0) { text = startOptions[area][i]['text']; } startSelect.options[i] = new Option(text, startOptions[area][i]['value'], false, isSelected); } while (endSelect.options.length > 0) { endSelect.remove(0); } $('#end_time_error').text(''); j = 0; for (i = 0; i < nEndOptions[area]; i++) { if (maxDurationEnabled) { duration = endOptions[area][i]['value'] - startValue; if (enablePeriods) { duration = duration/60 + 1; duration += dateDifference * 2; } else { duration += dateDifference * 60 * 60 *24; } maxDuration = (enablePeriods) ? maxDurationPeriods : maxDurationSecs; if (duration > maxDuration) { if (i == 0) { endSelect.options[j] = new Option(nbsp, endOptions[area][i]['value'], false, isSelected); var errorMessage = 'The maximum duration of a booking is' + nbsp; if (enablePeriods) { errorMessage += maxDurationPeriods + nbsp; errorMessage += (maxDurationPeriods > 1) ? 'periods' : ''; } else { errorMessage += maxDurationQty + nbsp + maxDurationUnits; } $('#end_time_error').text(errorMessage); } else { break; } } } if ((endOptions[area][i]['value'] > startValue) || ((endOptions[area][i]['value'] == startValue) && enablePeriods) || (dateDifference != 0)) { isSelected = (endOptions[area][i]['value'] == endValue); if (dateDifference >= 0) { text = endOptions[area][i]['text'] + nbsp + nbsp + '(' + getDuration(startValue, endOptions[area][i]['value'], dateDifference) + ')'; } endSelect.options[j] = new Option(text, endOptions[area][i]['value'], false, isSelected); j++; } } var startId = "#start_seconds" + area; var endId = "#end_seconds" + area; $(startId).css({width: "auto"}); $(endId).css({width: "auto"}); var startWidth = $(startId).width(); var endWidth = $(endId).width(); var maxWidth = Math.max(startWidth, endWidth) + 2; $(startId).width(maxWidth); $(endId).width(maxWidth); } var oldInitEditEntry = init; init = function() { oldInitEditEntry.apply(this); var form = document.getElementById('main'); if (form) { if (form.name && (form.name.value.length == 0)) { form.name.focus(); } vocab['periods'] = []; vocab['periods']['singular'] = 'period'; vocab['periods']['plural'] = 'periods'; vocab['minutes'] = []; vocab['minutes']['singular'] = 'minute'; vocab['minutes']['plural'] = 'minutes'; vocab['hours'] = []; vocab['hours']['singular'] = 'hour'; vocab['hours']['plural'] = 'hours'; vocab['days'] = []; vocab['days']['singular'] = 'day'; vocab['days']['plural'] = 'days'; var i, j, area, startSelect, endSelect, allDay; for (i in areas) { area = i; startSelect = form["start_seconds" + area]; endSelect = form["end_seconds" + area]; startOptions[area] = []; nStartOptions[area] = startSelect.options.length; for (j=0; j < nStartOptions[area]; j++) { startOptions[area][j] = []; startOptions[area][j]['text'] = startSelect.options[j].text; startOptions[area][j]['value'] = parseInt(startSelect.options[j].value, 10); } endOptions[area] = []; nEndOptions[area] = endSelect.options.length; for (j=0; j < nEndOptions[area]; j++) { endOptions[area][j] = []; endOptions[area][j]['text'] = endSelect.options[j].text; endOptions[area][j]['value'] = parseInt(endSelect.options[j].value, 10); } } adjustSlotSelectors(form); startSelect = form["start_seconds" + currentArea]; endSelect = form["end_seconds" + currentArea]; allDay = form["all_day" + currentArea]; if (allDay && !allDay.disabled && (parseInt(startSelect.options[startSelect.selectedIndex].value, 10) == startOptions[currentArea][0]['value']) && (parseInt(endSelect.options[endSelect.selectedIndex].value, 10) == endOptions[currentArea][nEndOptions[currentArea] - 1]['value'])) { allDay.checked = true; startSelect.disabled = true; endSelect.disabled = true; old_start = startSelect.options[startSelect.selectedIndex].value; old_end = endSelect.options[endSelect.selectedIndex].value; } } if (typeof validationMessages === 'function') { validationMessages(); } $('form#main').find('[type="submit"], [type="button"], [type="image"]').click(function() { var trigger = $(this).attr('name'); $(this).closest('form').data('submit', trigger); }); $('form#main').bind('submit', function(e) { if ($(this).data('submit') == 'save_button') { var result = validate($(this)); if (!result) { $(this).removeData('submit'); } return result; } return true; }); var formFields = $('form#main [name]').not(':disabled, [type="submit"], [type="button"], [type="image"]'); formFields.filter(':checkbox') .click(function() { checkConflicts(); }); formFields.not(':checkbox') .change(function(event) { checkConflicts(); }); checkConflicts(); $('#conflict_check, #policy_check').click(function() { var tabId; var checkResults = $('#check_results'); var checkTabs = $('#check_tabs'); switch ($(this).attr('id')) { case 'policy_check': tabId = 'policy_details'; break; case 'conflict_check': default: tabId = 'schedule_details'; break; } if (arguments.callee.alreadyExists) { if (!checkResults.dialog("isOpen")) { checkResults.dialog("open"); } checkTabs.tabs("select", tabId); return; } checkTabs.tabs(); checkTabs.tabs("select", tabId); checkResults.dialog({'width':400, 'height':200, 'minWidth':300, 'minHeight':150, 'draggable':true }); $('#ui-tab-dialog-close').append($('a.ui-dialog-titlebar-close')); $('.ui-dialog').addClass('ui-tabs') .prepend($('#details_tabs')) .draggable('option', 'handle', '#details_tabs'); $('.ui-dialog-titlebar').remove(); $('#details_tabs').addClass('ui-dialog-titlebar'); arguments.callee.alreadyExists=true; }); window.setInterval(function() { checkConflicts(true); }, 10000); };