Keine Beschreibung

edit_five_year_plan.blade.php 18KB

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