Без опису

create_five_year_plan.blade.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. @extends('layouts.master')
  2. @section('navigation')
  3. @if (Auth::user()->role == 1)
  4. @include('local.managers.admins._new_navigation')
  5. @elseif(Auth::user()->role == 2)
  6. @include('local.managers.sCoords._new_navigation')
  7. @elseif(Auth::user()->role == 3)
  8. @include('local.managers.pCoords._new_navigation')
  9. @endif
  10. @stop
  11. @section('main')
  12. <div class="row">
  13. <div class="col-md-12">
  14. <div id="quinquennium" data-quinquennium-id="{{ $current_quinquennium->id }}"></div>
  15. <div id="program" data-program-id="{{ $program->id }}"></div>
  16. @for ($i = date('Y', strtotime($current_quinquennium->start_date)); $i < date('Y', strtotime($current_quinquennium->end_date)); $i++)
  17. <div class="mini-plan">
  18. <table class="table table-bordered">
  19. <thead>
  20. <tr class="bg-danger text-center">
  21. <th class="text-center col-md-1">Academic Year</th>
  22. <th class="text-center col-md-3">Learning Outcome to be assessed</th>
  23. <th class="text-center col-md-4">Learning Objectives</th>
  24. <th class="text-center col-md-4">Courses to use for assessment</th>
  25. <th></th>
  26. </tr>
  27. </thead>
  28. <tbody>
  29. <tr>
  30. <th class="active academic-year text-center" rowspan="1"><span
  31. class="year-start">{{ $i }}</span>-<span
  32. class="year-end">{{ $i + 1 }}</span></th>
  33. <td class="outcome-cell">
  34. <select name="outcome" class="outcome form-control">
  35. @foreach ($outcomes as $outcome)
  36. <option value="{{ $outcome->id }}">{{ $outcome->name }}</option>
  37. @endforeach
  38. </select>
  39. </td>
  40. <td class="objectives-cell">
  41. <div class="objective-select-wrapper">
  42. <select name="objectives[]" class="objective shortened-select form-control">
  43. </select>
  44. <span
  45. class="glyphicon glyphicon-remove text-danger icon-btn remove-objective"></span>
  46. <br><br>
  47. </div>
  48. <button class="add-objective btn btn-success pull-right btn-xs"><span
  49. class="glyphicon glyphicon-plus"></span></button>
  50. </td>
  51. <td>
  52. <div class="course-select-wrapper">
  53. <select name="courses[]" class="course shortened-select form-control">
  54. @foreach ($courses as $course)
  55. <option value="{{ $course->id }}" data-course-code="{{ $course->code }}"
  56. data-course-number="{{ $course->number }}"
  57. data-course-name="{{ $course->name }}">
  58. {{ $course->code }}{{ $course->number }}: {{ $course->name }}
  59. </option>
  60. @endforeach
  61. </select>
  62. <span class="glyphicon glyphicon-remove text-danger icon-btn remove-course"></span>
  63. <br><br>
  64. </div>
  65. <button class="add-course btn btn-success pull-right btn-xs"><span
  66. class="glyphicon glyphicon-plus"></span></button>
  67. </td>
  68. <td></td>
  69. </tr>
  70. </tbody>
  71. </table>
  72. <div>
  73. <button class="add-outcome btn btn-success pull-right btn-sm"><span
  74. class="glyphicon glyphicon-plus"></span>Add Learning Outcome</button>
  75. <br><br><br>
  76. </div>
  77. </div>
  78. @endfor
  79. <div class="text-center">
  80. <button id="button-create-rubric" class="btn btn-lg btn-primary save">
  81. <span class="glyphicon glyphicon-floppy-disk"></span>
  82. Save
  83. </button>
  84. </div>
  85. </div>
  86. </div>
  87. @stop
  88. @section('included-js')
  89. @stop
  90. @section('javascript')
  91. // --------------------------------------------------------------------------
  92. // Page Load
  93. // --------------------------------------------------------------------------
  94. // Hide all 'x' buttons for courses and objectives
  95. $('.remove-course, .remove-objective').hide();
  96. $('.outcome').each(function()
  97. {
  98. fetchObjectives($(this));
  99. });
  100. // --------------------------------------------------------------------------
  101. // Events
  102. // --------------------------------------------------------------------------
  103. // On clicking a button to add outcome
  104. $('.add-outcome').on('click', function(e)
  105. {
  106. var table = $(this).closest('.mini-plan').find('table');
  107. addOutcome(table);
  108. });
  109. // On clicking a button to remove a course
  110. $('table').on('click', '.remove-objective', function(e)
  111. {
  112. removeObjective($(this));
  113. });
  114. // On clicking a button to remove a course
  115. $('table').on('click', '.remove-course', function(e)
  116. {
  117. removeCourse($(this));
  118. });
  119. // On clicking the x to remove an outcome from the plan
  120. $('table').on('click', '.remove-outcome', function(e)
  121. {
  122. var table = $(this).closest('.mini-plan').find('table');
  123. var row = $(this).closest('tr');
  124. removeOutcome(table, row);
  125. });
  126. // On clicking a button to add a objective
  127. $('.add-objective').on('click', function(e)
  128. {
  129. var table = $(this).closest('.mini-plan').find('table');
  130. var objective_select_wrapper = $(this).parent().find('.objective-select-wrapper:last');
  131. var select = $(this).parent().find('select:last');
  132. var selected_objective_id = select.find(':selected').val();
  133. var clone = objective_select_wrapper.clone();
  134. clone.insertAfter(objective_select_wrapper);
  135. objective_select_wrapper.parent().find('.remove-objective').show();
  136. });
  137. // On clicking a button to add a course
  138. $('.add-course').on('click', function(e)
  139. {
  140. var table = $(this).closest('.mini-plan').find('table');
  141. var course_select_wrapper = $(this).parent().find('.course-select-wrapper:last');
  142. var select = $(this).parent().find('select:last');
  143. var selected_course_id = select.find(':selected').val();
  144. var clone = course_select_wrapper.clone();
  145. clone.insertAfter(course_select_wrapper);
  146. course_select_wrapper.parent().find('.remove-course').show();
  147. });
  148. // When user selects another outcome
  149. $('.outcome').on('change', function(e)
  150. {
  151. fetchObjectives($(this));
  152. });
  153. // Gather, structure and send data to server for saving
  154. $('.save').on('click', function(e)
  155. {
  156. var five_year_plan = new Object();
  157. five_year_plan.quinquennium_id = $('#quinquennium').data('quinquennium-id');
  158. five_year_plan.program_id = $('#program').data('program-id');
  159. five_year_plan.mini_plans = new Array();
  160. $('.mini-plan').each(function(index){
  161. var mini_plan = new Object();
  162. mini_plan.year_start = $(this).find('.year-start').text();
  163. mini_plan.year_end = $(this).find('.year-end').text();
  164. // Array for outcome objects
  165. mini_plan.outcomes = new Array();
  166. $(this).find('.outcome').each(function(index){
  167. // Outcome object
  168. var outcome = new Object();
  169. outcome.id = $(this).find(':selected').val();
  170. outcome.objectives = new Array();
  171. outcome.courses = new Array();
  172. // Gather objective information
  173. $(this).closest('tr').find('.objective').each(function()
  174. {
  175. var objective = new Object();
  176. objective.original_id = $(this).find(':selected').val();
  177. objective.text = $(this).find(':selected').text();
  178. outcome.objectives.push(jQuery.extend({}, objective));
  179. objective = null;
  180. });
  181. // Gather course information
  182. $(this).closest('tr').find('.course').each(function()
  183. {
  184. var course = new Object();
  185. course.code = $(this).find(':selected').data('course-code');
  186. course.number = $(this).find(':selected').data('course-number');
  187. course.name = $(this).find(':selected').data('course-name');
  188. outcome.courses.push(jQuery.extend({}, course));
  189. course = null;
  190. });
  191. mini_plan.outcomes.push(jQuery.extend({}, outcome));
  192. outcome = null;
  193. });
  194. five_year_plan.mini_plans.push(jQuery.extend({}, mini_plan));
  195. mini_plan = null;
  196. });
  197. //console.log(five_year_plan);
  198. $.post(
  199. "{{ URL::action('FiveYearPlansController@store', [$program->id]) }}",
  200. {
  201. five_year_plan: JSON.stringify(five_year_plan)
  202. },
  203. function(data)
  204. {
  205. //console.log(data);
  206. var response = data;
  207. //console.log('status: '+response.status);
  208. if(response.status == 'success')
  209. {
  210. //console.log('success');
  211. window.location = response.redirect_url;
  212. }
  213. else
  214. {
  215. jsError(response.message);
  216. }
  217. },
  218. "json"
  219. )
  220. .fail( function(xhr, status, error) {
  221. //console.log('fail:'+error);
  222. // Always scroll to the top
  223. $(this).scrollTop(0);
  224. $('html').animate({scrollTop:0}, 1);
  225. $('body').animate({scrollTop:0}, 1);
  226. jsError(error);
  227. // Show js error with default message
  228. $('#js-error-row').fadeIn('slow', function () {
  229. $(this).delay(3000).fadeOut('slow');
  230. });
  231. }
  232. );
  233. });
  234. // --------------------------------------------------------------------------
  235. // Functions
  236. // --------------------------------------------------------------------------
  237. // Removes a objective
  238. function removeObjective(button)
  239. {
  240. var objective_select_wrapper = button.parent();
  241. // If only one objective will remain, hide 'x' button
  242. if(objective_select_wrapper.siblings('.objective-select-wrapper').length == 1)
  243. {
  244. objective_select_wrapper.siblings('.objective-select-wrapper').find('.remove-objective').hide();
  245. }
  246. // Remove objective
  247. objective_select_wrapper.remove();
  248. }
  249. // Removes a course
  250. function removeCourse(button)
  251. {
  252. var course_select_wrapper = button.parent();
  253. // If only one course will remain, hide 'x' button
  254. if(course_select_wrapper.siblings('.course-select-wrapper').length == 1)
  255. {
  256. course_select_wrapper.siblings('.course-select-wrapper').find('.remove-course').hide();
  257. }
  258. // Remove course
  259. course_select_wrapper.remove();
  260. }
  261. // Checks whether a mini plan has outcomes
  262. function hasOutcomes(table)
  263. {
  264. if(table.find('.outcome-cell').length > 0)
  265. return true;
  266. else
  267. return false;
  268. }
  269. // Add an outcome to a mini (annual) plan
  270. function addOutcome(table)
  271. {
  272. var header_rowspan = Number(table.find('.academic-year').attr('rowspan'));
  273. var clone = table.find('tbody tr:first').clone(true, true);
  274. // Remove academic year
  275. clone.children(':first').remove();
  276. // Remove all objectives and course except the first ones
  277. clone.find('.objective-select-wrapper').not(':first').remove();
  278. clone.find('.course-select-wrapper').not(':first').remove();
  279. // Add removal button
  280. clone.children(':last').append('<span class="glyphicon glyphicon-remove text-danger icon-btn remove-outcome"></span>');
  281. if(hasOutcomes(table))
  282. {
  283. table.find('tbody').append(clone);
  284. table.find('.academic-year').attr('rowspan', header_rowspan+1);
  285. }
  286. }
  287. // Remove an Outcome
  288. function removeOutcome(table, row)
  289. {
  290. var header_rowspan = Number(table.find('.academic-year').attr('rowspan'));
  291. row.remove();
  292. table.find('.academic-year').attr('rowspan', header_rowspan-1);
  293. }
  294. // Fetch objectives associated to an outcome and program
  295. function fetchObjectives(outcome)
  296. {
  297. var outcome_id = outcome.find(':selected').val();
  298. var program_id = $('#program').data('program-id');
  299. $.post(
  300. "{{ URL::action('ObjectivesController@fetch') }}",
  301. {
  302. outcome_id: outcome_id,
  303. program_id: program_id,
  304. format: 'select'
  305. },
  306. function(data)
  307. {
  308. var select = outcome.closest('tr').find('.objective');
  309. if(data == '')
  310. {
  311. select.prop('disabled', true);
  312. select.empty().append('<option value="0"><span class="glyphicon glyphicon-remove"></span> None</option>');
  313. }
  314. else
  315. {
  316. select.prop('disabled', false);
  317. select.empty().append(data);
  318. }
  319. if(select.length > 1) {
  320. select.first().parent().siblings('.objective-select-wrapper').remove();
  321. }
  322. }
  323. );
  324. }
  325. @stop