説明なし

edit_five_year_plan.blade.php 13KB

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