Skills: adding student view, now students can see the status of the skills (still ugly but works) see #1791

skala
Julio Montoya 14 years ago
parent 5721da93f6
commit 158a3467c4
  1. 8
      main/admin/skills.php
  2. 6
      main/inc/ajax/skill.ajax.php
  3. 73
      main/inc/lib/javascript/skills.js
  4. 57
      main/inc/lib/skill.lib.php
  5. 1
      main/inc/lib/skill.visualizer.lib.php
  6. 10
      main/social/skills_tree.php
  7. 38
      main/template/default/skill/skill_tree.tpl
  8. 112
      main/template/default/skill/skill_tree_student.tpl

@ -14,20 +14,15 @@ require_once api_get_path(LIBRARY_PATH).'skill.lib.php';
require_once api_get_path(LIBRARY_PATH).'skill.visualizer.lib.php'; require_once api_get_path(LIBRARY_PATH).'skill.visualizer.lib.php';
$this_section = SECTION_PLATFORM_ADMIN; $this_section = SECTION_PLATFORM_ADMIN;
//api_protect_admin_script(); api_protect_admin_script();
//Adds the JS needed to use the jqgrid //Adds the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_jquery_ui_js(true); $htmlHeadXtra[] = api_get_jquery_ui_js(true);
$htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js'); $htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js');
$htmlHeadXtra[] = api_get_js('skills.js'); $htmlHeadXtra[] = api_get_js('skills.js');
//Display::display_header();
//Display::display_reduced_header();
$skill = new Skill(); $skill = new Skill();
$skills = $skill->get_all(true);
$type = 'edit'; //edit $type = 'edit'; //edit
$tree = $skill->get_skills_tree(null, true); $tree = $skill->get_skills_tree(null, true);
$skill_visualizer = new SkillVisualizer($tree, $type); $skill_visualizer = new SkillVisualizer($tree, $type);
@ -45,4 +40,3 @@ $tpl->assign('js', $skill_visualizer->return_js());
$content = $tpl->fetch('default/skill/skill_tree.tpl'); $content = $tpl->fetch('default/skill/skill_tree.tpl');
$tpl->assign('content', $content); $tpl->assign('content', $content);
$tpl->display_no_layout_template(); $tpl->display_no_layout_template();

@ -67,14 +67,16 @@ switch ($action) {
$skills = $skill->get_children($id); $skills = $skill->get_children($id);
$return = array(); $return = array();
foreach($skills as $skill) { foreach($skills as $skill) {
$return [$skill['data']['id']] = array('name' => $skill['data']['name'], 'id'=>$skill['data']['id']); $return [$skill['data']['id']] = array(
'id' => $skill['data']['id'],
'name' => $skill['data']['name'],
'passed'=> $skill['data']['passed']);
} }
echo json_encode($return); echo json_encode($return);
break; break;
case 'load_direct_parents': case 'load_direct_parents':
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null; $id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$skills = $skill->get_direct_parents($id); $skills = $skill->get_direct_parents($id);
$return = array(); $return = array();
foreach($skills as $skill) { foreach($skills as $skill) {
$return [$skill['data']['id']] = array ( $return [$skill['data']['id']] = array (

@ -1,3 +1,5 @@
// Arrow settings
var exampleDropOptions = { var exampleDropOptions = {
tolerance:'touch', tolerance:'touch',
hoverClass:'dropHover', hoverClass:'dropHover',
@ -16,7 +18,7 @@
}; };
//Settings when editing stuff //Admin arrows
var edit_arrow_color = '#ccc'; var edit_arrow_color = '#ccc';
var editEndpoint = { var editEndpoint = {
@ -42,7 +44,50 @@
}; };
//Student arrows
//If user does not completed the skill
var default_arrow_color = '#ccc'; //gray
var defaultEndpoint = {
connector:[ "Flowchart", { stub:28 } ],
anchors: ['BottomCenter','TopCenter'],
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:default_arrow_color },
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, default_arrow_color], [0.5, default_arrow_color], [1, default_arrow_color]] },
lineWidth:5,
strokeStyle:default_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
// If user completed the skill
var done_arrow_color = '#73982C'; //green
var doneEndpoint = {
connector:[ "Flowchart", { stub:28 } ],
anchors: ['BottomCenter','TopCenter'],
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:done_arrow_color},
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, done_arrow_color], [0.5, done_arrow_color], [1, done_arrow_color]] },
lineWidth:5,
strokeStyle:done_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
//Functions
/* Clean window block classes*/ /* Clean window block classes*/
@ -52,6 +97,7 @@
obj.removeClass('third_window'); obj.removeClass('third_window');
} }
/* When clicking the red block */
function open_parent(parent_id, id) { function open_parent(parent_id, id) {
console.log("open_parent call : id " + id + " parent_id:" + parent_id); console.log("open_parent call : id " + id + " parent_id:" + parent_id);
var numeric_parent_id = parent_id.split('_')[1]; var numeric_parent_id = parent_id.split('_')[1];
@ -59,7 +105,8 @@
load_parent(numeric_parent_id, numeric_id); load_parent(numeric_parent_id, numeric_id);
} }
//open block function /* When clicking a children block */
function open_block(id) { function open_block(id) {
console.log("open_block id : " + id); console.log("open_block id : " + id);
var numeric_id = id.split('_')[1]; var numeric_id = id.split('_')[1];
@ -96,6 +143,7 @@
load_children(numeric_id, top_value); load_children(numeric_id, top_value);
} }
/* Loads parent blocks */
function load_parent(parent_id, id) { function load_parent(parent_id, id) {
console.log("load_parent call : id " + id + " parent_id:" + parent_id); console.log("load_parent call : id " + id + " parent_id:" + parent_id);
var ix= 0; var ix= 0;
@ -126,7 +174,6 @@
} }
ix++; ix++;
}); });
} }
}); });
} }
@ -143,14 +190,21 @@
//Display::url($skill['name'], '#', array('id'=>'edit_block_'.$block_id, 'class'=>'edit_block')) //Display::url($skill['name'], '#', array('id'=>'edit_block_'.$block_id, 'class'=>'edit_block'))
item.name = '<a href="#" class="edit_block" id="edit_block_'+item.id+'">'+item.name+'</a>'; item.name = '<a href="#" class="edit_block" id="edit_block_'+item.id+'">'+item.name+'</a>';
$('body').append('<div id="block_'+item.id+ '" class="third_window open_block window " >'+item.name+'</div>');
var es = prepare("block_" + item.id, editEndpoint); var status_class = ' ';
var e2 = prepare("block_" + my_id, editEndpoint); my_edit_point = editEndpoint;
jsPlumb.connect({ if (item.passed == 1) {
source: es, target:e2 my_edit_point = doneEndpoint;
}); status_class = 'done_window';
}
$('body').append('<div id="block_'+item.id+ '" class="third_window open_block window '+status_class+'" >'+item.name+'</div>');
var es = prepare("block_" + item.id, my_edit_point);
var e2 = prepare("block_" + my_id, my_edit_point);
jsPlumb.connect({source: es, target:e2});
jsPlumb.animate("block_" + item.id, { jsPlumb.animate("block_" + item.id, {
left: left_value, top : top_value left: left_value, top : top_value
}, { duration:duration_value}); }, { duration:duration_value});
@ -170,4 +224,3 @@
return true; return true;
} }
} }

@ -26,7 +26,6 @@ class SkillProfile extends Model {
public function get_profiles() { public function get_profiles() {
$sql = "SELECT * FROM $this->table p INNER JOIN $this->table_rel_profile sp ON(p.id = sp.profile_id) "; $sql = "SELECT * FROM $this->table p INNER JOIN $this->table_rel_profile sp ON(p.id = sp.profile_id) ";
$result = Database::query($sql); $result = Database::query($sql);
$profiles = Database::store_result($result,'ASSOC'); $profiles = Database::store_result($result,'ASSOC');
return $profiles; return $profiles;
@ -47,7 +46,6 @@ class SkillProfile extends Model {
} }
} }
return false; return false;
} }
} }
@ -119,12 +117,26 @@ class SkillRelSkill extends Model {
return $parents; return $parents;
} }
public function get_children($skill_id, $add_child_info = true) { public function get_children($skill_id, $load_user_data = false, $user_id = false) {
$skills = $this->find('all', array('where'=> array('parent_id = ? '=> $skill_id))); $skills = $this->find('all', array('where'=> array('parent_id = ? '=> $skill_id)));
$skill_obj = new Skill(); $skill_obj = new Skill();
$skill_rel_user = new SkillRelUser();
if ($load_user_data) {
$passed_skills = $skill_rel_user->get_user_skills($user_id);
$done_skills = array();
foreach($passed_skills as $done_skill) {
$done_skills[] = $done_skill['skill_id'];
}
}
if (!empty($skills)) { if (!empty($skills)) {
foreach ($skills as &$skill) { foreach ($skills as &$skill) {
$skill['data'] = $skill_obj->get($skill['skill_id']); $skill['data'] = $skill_obj->get($skill['skill_id']);
if (!empty($done_skills)) {
$skill['data']['passed'] = 0;
if (in_array($skill['skill_id'], $done_skills)) {
$skill['data']['passed'] = 1;
}
}
} }
} }
return $skills; return $skills;
@ -176,7 +188,6 @@ class SkillRelGradebook extends Model {
public function update_gradebooks_by_skill($skill_id, $gradebook_list) { public function update_gradebooks_by_skill($skill_id, $gradebook_list) {
$original_gradebook_list = $this->find('all', array('where'=>array('skill_id = ?' => array($skill_id)))); $original_gradebook_list = $this->find('all', array('where'=>array('skill_id = ?' => array($skill_id))));
//var_dump($original_gradebook_list);
$gradebooks_to_remove = array(); $gradebooks_to_remove = array();
$gradebooks_to_add = array(); $gradebooks_to_add = array();
$original_gradebook_list_ids = array(); $original_gradebook_list_ids = array();
@ -282,11 +293,6 @@ class Skill extends Model {
return $skill_info; return $skill_info;
} }
public function skill_exists($skill_id) {
}
function get_skills_info($skill_list) { function get_skills_info($skill_list) {
$skill_list = array_map('intval', $skill_list); $skill_list = array_map('intval', $skill_list);
$skill_list = implode("', '", $skill_list); $skill_list = implode("', '", $skill_list);
@ -296,12 +302,11 @@ class Skill extends Model {
$result = Database::query($sql); $result = Database::query($sql);
$users = Database::store_result($result, 'ASSOC'); $users = Database::store_result($result, 'ASSOC');
return $users; return $users;
} }
function get_all($load_user_data = false) {
function get_all($load_user_data = false, $user_id = false) {
$sql = "SELECT id, name, description, parent_id, relation_type $sql = "SELECT id, name, description, parent_id, relation_type
FROM {$this->table} skill INNER JOIN {$this->table_skill_rel_skill} skill_rel_skill FROM {$this->table} s INNER JOIN {$this->table_skill_rel_skill} ss ON (s.id = ss.skill_id) ";
ON skill.id = skill_rel_skill.skill_id ";
$result = Database::query($sql); $result = Database::query($sql);
$skills = array(); $skills = array();
@ -315,17 +320,16 @@ class Skill extends Model {
} }
} }
if ($load_user_data) { if ($load_user_data && $user_id) {
$passed_skills = $this->get_user_skills(api_get_user_id()); $passed_skills = $this->get_user_skills($user_id);
foreach ($skills as &$skill) { foreach ($skills as &$skill) {
$skill['done_by_user'] = 0; $skill['done_by_user'] = 0;
if (in_array($skill['id'], $passed_skills)) { if (in_array($skill['id'], $passed_skills)) {
$skill['done_by_user'] = 1; $skill['done_by_user'] = 1;
} }
} }
} }
return $skills; return $skills;
} }
@ -341,7 +345,8 @@ class Skill extends Model {
function get_children($skill_id) { function get_children($skill_id) {
$skill_rel_skill = new SkillRelSkill(); $skill_rel_skill = new SkillRelSkill();
$skills = $skill_rel_skill->get_children($skill_id, true); $user_id = api_get_user_id();
$skills = $skill_rel_skill->get_children($skill_id, true, $user_id);
return $skills; return $skills;
} }
@ -409,7 +414,7 @@ class Skill extends Model {
$skill_rel_gradebook = new SkillRelGradebook(); $skill_rel_gradebook = new SkillRelGradebook();
//Saving name, description //Saving name, description
var_dump($params);
$this->update($params); $this->update($params);
$skill_id = $params['id']; $skill_id = $params['id'];
@ -465,18 +470,12 @@ class Skill extends Model {
} }
} }
public function remove_skill_to_user($user_id) {
}
/** /**
* Get user's skills * Get user's skills
* *
* @param int $userId User's id * @param int $userId User's id
*/ */
public function get_user_skills($user_id, $get_skill_data = false) { public function get_user_skills($user_id, $get_skill_data = false) {
$user_id = intval($user_id); $user_id = intval($user_id);
//$sql = 'SELECT skill.*, user.* FROM '.$this->table_skill_rel_user.' user INNER JOIN '.$this->table_skill.' skill //$sql = 'SELECT skill.*, user.* FROM '.$this->table_skill_rel_user.' user INNER JOIN '.$this->table_skill.' skill
@ -499,9 +498,13 @@ class Skill extends Model {
return $clean_skill; return $clean_skill;
} }
public function get_skills_tree($user_id = null, $return_flat_array = false) { public function get_skills_tree($user_id = null, $return_flat_array = false) {
if (isset($user_id) && !empty($user_id)) {
$skills = $this->get_all(true, $user_id);
} else {
$skills = $this->get_all(); $skills = $this->get_all();
}
$refs = array(); $refs = array();
$skills_tree = null; $skills_tree = null;

@ -71,6 +71,7 @@
$class = 'edit_window'; $class = 'edit_window';
$end_point = 'editEndpoint'; $end_point = 'editEndpoint';
} else { } else {
if ($skill['done_by_user'] == 1) { if ($skill['done_by_user'] == 1) {
$class = 'done_window'; $class = 'done_window';
$end_point = 'doneEndpoint'; $end_point = 'doneEndpoint';

@ -15,7 +15,7 @@ require_once api_get_path(LIBRARY_PATH).'skill.visualizer.lib.php';
$this_section = SECTION_MYPROFILE; $this_section = SECTION_MYPROFILE;
//api_protect_admin_script(); api_block_anonymous_users();
//Adds the JS needed to use the jqgrid //Adds the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_jquery_ui_js(true); $htmlHeadXtra[] = api_get_jquery_ui_js(true);
@ -23,10 +23,9 @@ $htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js');
$htmlHeadXtra[] = api_get_js('skills.js'); $htmlHeadXtra[] = api_get_js('skills.js');
$skill = new Skill(); $skill = new Skill();
$skills = $skill->get_all(true); $type = 'read'; //edit
$type = 'edit'; //edit
$tree = $skill->get_skills_tree(null, true); $tree = $skill->get_skills_tree(api_get_user_id(), true);
$skill_visualizer = new SkillVisualizer($tree, $type); $skill_visualizer = new SkillVisualizer($tree, $type);
$html = $skill_visualizer->return_html(); $html = $skill_visualizer->return_html();
@ -39,8 +38,7 @@ $tpl->assign('html', $html);
$tpl->assign('skill_visualizer', $skill_visualizer); $tpl->assign('skill_visualizer', $skill_visualizer);
$tpl->assign('js', $skill_visualizer->return_js()); $tpl->assign('js', $skill_visualizer->return_js());
//
$content = $tpl->fetch('default/skill/skill_tree_student.tpl'); $content = $tpl->fetch('default/skill/skill_tree_student.tpl');
$tpl->assign('content', $content); $tpl->assign('content', $content);
$tpl->display_no_layout_template(); $tpl->display_no_layout_template();

@ -19,8 +19,6 @@ var block_size = {$skill_visualizer->block_size};
//Setting the parent by default //Setting the parent by default
var parents = ['block_1']; var parents = ['block_1'];
jsPlumb.bind("ready", function() { jsPlumb.bind("ready", function() {
//Open dialog //Open dialog
@ -306,42 +304,6 @@ jsPlumb.bind("ready", function() {
jsPlumb.setMouseEventsEnabled(true); jsPlumb.setMouseEventsEnabled(true);
//Default
var default_arrow_color = '#ccc';
var defaultEndpoint = {
anchors: ['BottomCenter','TopCenter'],
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:default_arrow_color },
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, default_arrow_color], [0.5, default_arrow_color], [1, default_arrow_color]] },
lineWidth:5,
strokeStyle:default_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
// Done end point
var done_arrow_color = '#73982C';
var doneEndpoint = {
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:done_arrow_color},
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, done_arrow_color], [0.5, done_arrow_color], [1, done_arrow_color]] },
lineWidth:5,
strokeStyle:done_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
{$js} {$js}
// three ways to do this - an id, a list of ids, or a selector (note the two different types of selectors shown here...anything that is valid jquery will work of course) // three ways to do this - an id, a list of ids, or a selector (note the two different types of selectors shown here...anything that is valid jquery will work of course)
//jsPlumb.draggable("window1"); //jsPlumb.draggable("window1");

@ -165,6 +165,9 @@ jsPlumb.bind("ready", function() {
;(function() { ;(function() {
prepare = function(elId, endpoint) { prepare = function(elId, endpoint) {
jsPlumbDemo.initHover(elId); jsPlumbDemo.initHover(elId);
//jsPlumbDemo.initAnimation(elId); //jsPlumbDemo.initAnimation(elId);
@ -200,35 +203,6 @@ jsPlumb.bind("ready", function() {
jsPlumb.Defaults.Endpoint = "Rectangle"; jsPlumb.Defaults.Endpoint = "Rectangle";
jsPlumb.Defaults.Anchors = ["TopCenter", "TopCenter"]; jsPlumb.Defaults.Anchors = ["TopCenter", "TopCenter"];
var connections = [];
var updateConnections = function(conn, remove) {
if (!remove) connections.push(conn);
else {
var idx = -1;
for (var i = 0; i < connections.length; i++) {
if (connections[i] == conn) {
idx = i; break;
}
}
if (idx != -1) connections.splice(idx, 1);
}
if (connections.length > 0) {
var s = "<span>current connections</span><br/><br/><table><tr><th>scope</th><th>source</th><th>target</th></tr>";
for (var j = 0; j < connections.length; j++) {
s = s + "<tr><td>" + connections[j].scope + "</td>" + "<td>" + connections[j].sourceId + "</td><td>" + connections[j].targetId + "</td></tr>";
}
jsPlumbDemo.showConnectionInfo(s);
} else
jsPlumbDemo.hideConnectionInfo();
};
jsPlumb.bind("jsPlumbConnection", function(e) {
updateConnections(e.connection);
});
jsPlumb.bind("jsPlumbConnectionDetached", function(e) {
updateConnections(e.connection, true);
});
/** /**
@ -251,46 +225,8 @@ jsPlumb.bind("ready", function() {
//[ "Arrow", { location:0.5 } ], if you want to add an arrow in the connection //[ "Arrow", { location:0.5 } ], if you want to add an arrow in the connection
]; ];
jsPlumb.setMouseEventsEnabled(true); jsPlumb.setMouseEventsEnabled(true);
//Default
var default_arrow_color = '#ccc';
var defaultEndpoint = {
anchors: ['BottomCenter','TopCenter'],
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:default_arrow_color },
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, default_arrow_color], [0.5, default_arrow_color], [1, default_arrow_color]] },
lineWidth:5,
strokeStyle:default_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
// Done end point
var done_arrow_color = '#73982C';
var doneEndpoint = {
endpoint:"Rectangle",
paintStyle:{ width:1, height:1, fillStyle:done_arrow_color},
isSource:false,
scope:'blue rectangle',
maxConnections:10,
connectorStyle : {
gradient:{ stops:[[0, done_arrow_color], [0.5, done_arrow_color], [1, done_arrow_color]] },
lineWidth:5,
strokeStyle:done_arrow_color
},
isTarget:false,
setDraggableByDefault : false,
};
{$js} {$js}
// three ways to do this - an id, a list of ids, or a selector (note the two different types of selectors shown here...anything that is valid jquery will work of course) // three ways to do this - an id, a list of ids, or a selector (note the two different types of selectors shown here...anything that is valid jquery will work of course)
//jsPlumb.draggable("window1"); //jsPlumb.draggable("window1");
@ -309,26 +245,6 @@ jsPlumb.bind("ready", function() {
}; };
})(); })();
$(document).ready( function() {
//When creating a connection see
//http://jsplumb.org/apidocs/files/jsPlumb-1-3-2-all-js.html#bind
jsPlumb.bind("jsPlumbConnection", function(conn) {
//alert("Connection created " + conn.sourceId + " to " + conn.targetId + " ");
//jsPlumb.detach(conn);
});
//When double clicking a connection
jsPlumb.bind("click", function(conn) {
if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?"))
jsPlumb.detach(conn);
});
//When double clicking a connection
jsPlumb.bind("click", function(endpoint) {
if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?"))
jsPlumb.detach(conn);
});
$(".chzn-select").chosen();
});
;(function() { ;(function() {
@ -367,6 +283,16 @@ $(document).ready( function() {
}; };
})(); })();
$(document).ready( function() {
//When creating a connection see
//http://jsplumb.org/apidocs/files/jsPlumb-1-3-2-all-js.html#bind
jsPlumb.bind("jsPlumbConnection", function(conn) {
//alert("Connection created " + conn.sourceId + " to " + conn.targetId + " ");
//jsPlumb.detach(conn);
});
});
</script> </script>
{$html} {$html}
@ -383,15 +309,6 @@ $(document).ready( function() {
<input type="text" name="name" id="name" size="40" /> <input type="text" name="name" id="name" size="40" />
</div> </div>
</div> </div>
<div class="row">
<div class="label">
<label for="name">Parent</label>
</div>
<div class="formw">
<select id="parent_id" name="parent_id" />
</select>
</div>
</div>
<div class="row"> <div class="row">
<div class="label"> <div class="label">
<label for="name">Gradebook</label> <label for="name">Gradebook</label>
@ -399,9 +316,6 @@ $(document).ready( function() {
<div class="formw"> <div class="formw">
<select id="gradebook_id" name="gradebook_id[]" multiple="multiple"/> <select id="gradebook_id" name="gradebook_id[]" multiple="multiple"/>
</select> </select>
<span class="help-block">
Gradebook Description
</span>
</div> </div>
</div> </div>
<div class="row"> <div class="row">

Loading…
Cancel
Save