summaryrefslogblamecommitdiffstats
path: root/modules-available/exams/templates/page-add-edit-exam.html
blob: 5946874cb102098f0de93d61d03a406f97ebac0c (plain) (tree)
1
2
3
4
5
6
7
8
9
                
                                 

                
                                
                


                                                                                                 
 
 
                                                                   

                                                                     








                                                                                                 
                                                                                                                                                                


                                                      
                                                           
                      

              
                                         
                                                                  






















                                                                                                                                                      
                              
 





















                                                                                                                                                  
                              
 



                                                                                                       
                              

                      
 

                                                                                                           
                                        













                                                                                                                                     
                                      










                                                                                                                                                   
                                      


                                                                                      
                                      
                              




                                                                                                                                                                                                                                                    
                      

              


                                                                                                      






                                                                                                                                          
                                                            
                                                                                                                                   
                                                                                                                                                          













                                                                                                                                                                         

              

       

 
                                          
 
                                                           
 

                               
 











                                                   
 

                                                     
 




                                              
 


                                             

                                          

                                                                


                                                              
                                            


                 

                               
                                           



                                                                                                    

                               

















                                                                                           
                                       















                                                                                                                          
                                









                                                                                                                  
                         





















                                                                                                          
                                                            












                                                                                                                                                  
          
 


                                                                                                        
                        









                                                                                         
                 
          
 

                              



                                           

                                                                                
 
                                              
                                      

           

               
{{#exam.examid}}
<h1>{{lang_headingEditExam}}</h1>
{{/exam.examid}}
{{^exam.examid}}
<h1>{{lang_headingAddExam}}</h1>
{{/exam.examid}}
{{#exam.displayname}}
<div class="alert alert-info">{{lang_addingBasedOnLecture}}:<br><b>{{exam.displayname}}</b></div>
{{/exam.displayname}}


<form class="form" method="POST" action="?do=exams" id="tolleform">
	<!-- fake button to prevent return from messing things up -->
	<button type="submit" hidden onclick="return false"></button>
	<div class="panel panel-default">
		<div class="panel-heading"><label for="locations">{{lang_location}}</label></div>
		<div class="panel-body">
			<div class="form-group">
				<div>
					<p><i>{{lang_locationInfo}}</i></p>
				</div>
				<select id="locations" multiple name="locations[]">
					{{#locations}}
					<option value="{{locationid}}" {{disabled}} {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option>
					{{/locations}}
				</select>
			</div>
			{{lang_checkLocationSelectionHint}}
		</div>
	</div>

	<div class="panel panel-default">
		<div class="panel-heading">{{lang_dateTime}}</div>
		<div class="panel-body">
			<div class="row form-group">
				<div class="col-xs-6">
					<label for="starttime_date">{{lang_begin_date}}</label>
					<div class="input-group">
						<span class="input-group-addon">
							<span class="glyphicon glyphicon-calendar"></span>
						</span>
						<input required class="form-control datepicker" name="starttime_date" id="starttime_date"
								 value="{{exam.starttime_date}}">
					</div>
				</div>
				<div class="col-xs-6">
					<label for="starttime_time">{{lang_begin_time}}</label>
					<div class="input-group bootstrap-timepicker timepicker">
						<span class="input-group-addon">
							<span class="glyphicon glyphicon-time"></span>
						</span>
						<input required type="text" class="form-control timepicker2" name="starttime_time" id="starttime_time"
								 value="{{exam.starttime_time}}"
								 pattern="[0-9]{1,2}:[0-9]{2}">
					</div>
				</div>
			</div>

			<div class="row form-group">
				<div class="col-xs-6">
					<label for="endtime_date">{{lang_end_date}}</label>
					<div class="input-group">
						<span class="input-group-addon">
							<span class="glyphicon glyphicon-calendar"></span>
						</span>
						<input required class="form-control datepicker" name="endtime_date" id="endtime_date"
								 value="{{exam.endtime_date}}">
					</div>
				</div>
				<div class="col-xs-6">
					<label for="endtime_time">{{lang_end_time}}</label>
					<div class="input-group bootstrap-timepicker timepicker">
						<span class="input-group-addon">
							<span class="glyphicon glyphicon-time"></span>
						</span>
						<input required type="text" class="form-control timepicker2" name="endtime_time" id="endtime_time"
								 value="{{exam.endtime_time}}"
								 pattern="[0-9]{1,2}:[0-9]{2}">
					</div>
				</div>
			</div>

			<div>
				{{lang_duration}}: <span id="exam-duration">-</span>
				<span class="hidden" id="txt-invalid">{{lang_startOrEndInvalid}}</span>
				<span class="hidden" id="txt-reverse">{{lang_startAfterEnd}}</span>
			</div>
		</div>
	</div>

	<div class="panel panel-default">
		<div class="panel-heading"><label for="lecturelist">{{lang_autoStartLecture}}</label></div>
		<div class="panel-body">
			<div class="form-group">
				<p><i>{{lang_autoStartInfo}}</i></p>
				<div class="input-group">
					<span class="input-group-addon">
						<span class="glyphicon glyphicon-pencil"></span>
					</span>
					<select class="form-control" id="lecturelist" name="lectureid">
						<option value="">{{lang_none}}</option>
						{{#lectures}}
						<option data-from="{{starttime}}" data-to="{{endtime}}"
								{{#islocationprivate}}data-locations="{{lids}}"{{/islocationprivate}}
								value="{{lectureid}}" {{selected}} >{{displayname}}</option>
						{{/lectures}}
					</select>
				</div>
				<b id="sanity-check" class="slx-smallspace collapse">{{lang_sanityCheck}}</b>
				<div id="warn-range" class="collapse">
					<div class="text-warning">
						<div class="item start-before-lecture-start text-danger">{{lang_examStartBeforeLectureStart}}</div>
						<div class="item start-after-lecture-start">{{lang_examStartAfterLectureStart}}</div>
						<div class="item start-after-lecture-end text-danger">{{lang_examStartAfterLectureEnd}}</div>
						<div class="item end-before-lecture-end">{{lang_examEndBeforeLectureEnd}}</div>
						<div class="item end-after-lecture-end">{{lang_examEndAfterLectureEnd}}</div>
					</div>
					{{lang_lectureTimespan}}:
					<span class="lecture-range"></span>
				</div>
				<div id="warn-locations" class="text-danger collapse">
					{{lang_lectureNotForLocation}}:
					<span class="locname"></span>
				</div>
			</div>
			<div class="slx-space"></div>
			<div class="form-group">
				<div class="checkbox"><input id="autologin" type="checkbox" name="autologin" value="demo" class="form-control" {{#exam.autologin}}checked{{/exam.autologin}}><label for="autologin">{{lang_autoLogin}}</label></div>
				<p><i>{{lang_autoLoginInfo}}</i></p>
			</div>
		</div>
	</div>

	<div class="panel panel-default">
		<div class="panel-heading"><label for="description">{{lang_description}}</label></div>
		<div class="panel-body">
			<textarea class="form-control" type="textarea" name="description" id="description">{{exam.description}}</textarea>
		</div>
	</div>

	<input type="hidden" name="action" value="save">
	<input type="hidden" name="token" value="{{token}}">
	<input type="hidden" name="examid" value="{{exam.examid}}">
	<div class="text-right" style="margin-bottom: 20px">
		<button type="button" id="cancelButton" class="btn btn-default" style="margin-right: 10px">{{lang_cancel}}</button>
		<button type="button" id="saveButton" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
	</div>

	<div class ="modal fade" id="confirmGlobalModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
		<div class="modal-dialog" style="width: 400px" role="document">
			<div class="modal-content">
				<div class="modal-body">
					{{lang_comfirmGlobalExam}}
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
					<button type="submit" class="btn btn-sm btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
				</div>
			</div>
		</div>
	</div>

</form>



<script type="application/javascript"><!--

document.addEventListener("DOMContentLoaded", function () {

	moment.locale(LANG);
	var slxMoment = moment;

	var dateSettings = {
		format: 'yyyy-mm-dd',
		todayHighlight: true,
	};
	var timeSettings = {
		showSeconds: false,
		showMeridian: false,
		minuteStep: 5,
		appendWidgetTo: 'body',
	};
	$('.datepicker').datepicker(dateSettings);
	$('.timepicker2').timepicker(timeSettings);

	var $locations = $('#locations');
	$locations.multiselect({numberDisplayed: 1});

	var start_date = $('#starttime_date');
	var start_time = $('#starttime_time');
	var end_date = $('#endtime_date');
	var end_time = $('#endtime_time');
	var rspan = $('#exam-duration');

	start_date.focusout(function () {
		var start = start_date.val();
		var end = end_date.val();
		var ok = end.length === 0;
		if (!ok) {
			var ms = slxMoment(start, 'YYYY-MM-DD');
			var me = slxMoment(end, 'YYYY-MM-DD');
			ok = !me.isValid() || me.isBefore(ms);
		}
		if (ok) {
			end_date.val(start);
		}
	});

	var examStart, examEnd;

	var startEndChanged = function () {
		examStart = slxMoment(start_date.val() + ' ' + start_time.val(), 'YYYY-MM-DD H:mm');
		examEnd = slxMoment(end_date.val() + ' ' + end_time.val(), 'YYYY-MM-DD H:mm');
		if (!examStart.isValid() || !examEnd.isValid()) {
			rspan.text($('#txt-invalid').text()).addClass('text-danger');
			return;
		}
		var diff = examEnd.diff(examStart);
		if (diff <= 0) {
			rspan.text($('#txt-reverse').text()).addClass('text-danger');
			return;
		}
		rspan.text(slxMoment.duration(diff).humanize()).removeClass('text-danger');
		updateLectureInfo();
	};

	var $timespanWarning = $('#warn-range');
	var $locationWarning = $('#warn-locations');
	var updateLectureInfo = function() {
		(function() {
			var $sel = $('#lecturelist option:selected');
			var lectureStart = $sel.data('from');
			var lectureEnd = $sel.data('to');
			if (!lectureStart || !lectureEnd) {
				$timespanWarning.hide();
				return;
			}
			lectureStart = slxMoment.unix(lectureStart);
			lectureEnd = slxMoment.unix(lectureEnd);
			var diff;
			var warnings = [];
			if (examStart.isBefore(lectureStart)) {
				warnings.push('.start-before-lecture-start');
			}
			if (lectureEnd.diff(lectureStart, 'hours') >= 12) {
				// Lecture is longer than 12 hours -- only consider exam start/end date outside range
				if (lectureEnd.diff(examStart, 'minutes') < 15) { // Start after end, or very close to end
					warnings.push('.start-after-lecture-end');
				}
				if (examEnd.diff(lectureEnd, 'minutes') > 15) {
					warnings.push('.end-after-lecture-end');
				}
			} else {
				// Lecture is shorter than 12 hours -- assume it's the actual timespan of the exam
				if (examStart.diff(lectureStart, 'minutes') > 30) {
					warnings.push('.start-after-lecture-start');
				}
				diff = examEnd.diff(lectureEnd, 'minutes');
				if (diff > 15) {
					warnings.push('.end-after-lecture-end');
				} else if (diff < -30) {
					warnings.push('.end-before-lecture-end');
				}
			}
			if (warnings.length === 0) {
				$timespanWarning.hide();
				return;
			}
			$timespanWarning.find('.item').hide();
			for (var i = 0; i < warnings.length; ++i) {
				$timespanWarning.find(warnings[i]).show();
			}
			$timespanWarning.find('.lecture-range').text(slxMoment.unix($sel.data('from'))
				.format('LLL') + ' – ' + slxMoment.unix($sel.data('to')).format('LLL'));
			$timespanWarning.show();
		})();
		showHeading();
	};
	var updateLocationsInfo = function() {
		(function() {
			var selectedLocs = $locations.val();
			var lecLocs = $('#lecturelist option:selected').data('locations');
			if (!lecLocs || lecLocs.length === 0 || !selectedLocs) {
				$locationWarning.hide();
				return;
			}
			lecLocs = ('' + lecLocs).split(',');
			if (!$.isArray(selectedLocs)) {
				selectedLocs = [selectedLocs];
			}
			for (var i = 0; i < selectedLocs.length; ++i) {
				if (lecLocs.indexOf(selectedLocs[i]) === -1) {
					$locationWarning.find('.locname').text($locations.find('option[value="' + selectedLocs[i] + '"]').text());
					$locationWarning.show();
					return;
				}
			}
			$locationWarning.hide();
		})();
		showHeading();
	};

	$('#saveButton').click(function () {
		if ($('#locations option:selected').length === 0 && $('#locations option').length > 1) {
			$("#confirmGlobalModal").modal();
		} else {
			$('#tolleform').submit();
		}
	});

	var $sanity = $('#sanity-check');
	var showHeading = function() {
		if ($locationWarning.is(':visible') || $timespanWarning.is(':visible')) {
			$sanity.show();
		} else {
			$sanity.hide();
		}
	};

	startEndChanged();
	updateLocationsInfo();
	start_date.change(startEndChanged);
	start_time.change(startEndChanged);
	end_date.change(startEndChanged);
	end_time.change(startEndChanged);
	$('#lecturelist').change(updateLectureInfo).change(updateLocationsInfo);
	$locations.change(updateLocationsInfo);

	$("#cancelButton").click(function () {
		window.history.back();
	});

}, false);
// --></script>