diff options
author | Kedar Aitawdekar <kedar2a@gmail.com> | 2015-07-07 11:42:27 +0530 |
---|---|---|
committer | Kedar Aitawdekar <kedar2a@gmail.com> | 2015-07-07 11:42:27 +0530 |
commit | 260dfe404b642a2f9b0b0e9568b04a047a83219b (patch) | |
tree | 7763dda4e9c7301b875e7f985f3897b55050bdb8 /gnowsys-ndf/gnowsys_ndf | |
parent | 2b0b9640310477dadbc5e420b3238a3c968fa030 (diff) | |
parent | ebd6ef6ff10522b487b53424527b1637ec16bcee (diff) | |
download | gnowsys-260dfe404b642a2f9b0b0e9568b04a047a83219b.tar.gz |
Merge branch 'mongokit-graph' into mongokit-dev
Diffstat (limited to 'gnowsys-ndf/gnowsys_ndf')
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/hierarchy_tree.html | 619 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/new_create_batch.html | 549 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html | 2 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html | 818 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme_drag_zoom_d3tree.html | 199 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/urls/batch.py | 5 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/views/ajax_views.py | 167 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/views/batch.py | 350 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/views/enrollment.py | 6 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py | 20 | ||||
-rw-r--r-- | gnowsys-ndf/gnowsys_ndf/ndf/views/topics.py | 3 |
11 files changed, 1836 insertions, 902 deletions
diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/hierarchy_tree.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/hierarchy_tree.html new file mode 100644 index 0000000..ff7f674 --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/hierarchy_tree.html @@ -0,0 +1,619 @@ +{% load i18n %} +{% load cache %} + +{% load ndf_tags %} +{% get_group_name groupid as group_name_tag %} + +<style> + + #app-set-item li { padding:0.5em } + + .jqtree-closed > .jqtree-element i.icon-folder-open:before { + content: "\f07b"; + } + .jqtree-tree i { + margin-right: 4px; + } +</style> + + +<script type="text/javascript"> + + // $(document).ready(function() { + function plotHierarchyTree() { + // Funtion for loading tree for showing collection list left side panel + doc(); + + // Function for manipulating tree when user visits to page directly via browser url + {% if selected %} TreeTillNode(); {% endif %} + } + // }); + + + function TreeTillNode () { + + // This gives the last hierarchy node id from browser url. + var url = "{{selected}}"; + + var tree_build = $(".themes").not(".jqtree-loading"); + var node = tree_build.tree('getNodeById', url); + tree_build.tree('openNode', node); + + // Javascript function to be used for checking objects in specific time of interval + setTimeout(function(){ + + // console.log($(".themes")) + if( ($(".themes").length > 0) ) { TreeTillNode() } + }, 100 ); + } + + + function doc() { + + var $tree = $('.themes'); + var user = "{{user.is_authenticated}}"; + var unfold = "{{unfold}}"; + + if(unfold == "true"){ + unfold = true + } + else{ + unfold = false + } + + $tree.tree({ + autoOpen: unfold, + + onCreateLi: function(node, $li) { + + if (node.node_type == "Topic"){ + $li.find('.jqtree-title').before('  <span class="fi-page"></span> '); + } + else{ + $li.find('.jqtree-title').before('  <span class="fi-folder" style="color:orange"></span> '); + } + + if (node.node_type == "Topic"){ + $li.find('.jqtree-element').append( + + ' <a id='+node.id+' name='+node.name+' class="topic" href="/{{groupid}}/topics/'+node.id+'/"> </a>' + ); + } + else{ + if (user == "True"){ + + $li.find('.jqtree-element').append( + {% user_access_policy groupid request.user as user_access %} + {% if user_access == "allow" %} + + ' <a href="/{{groupid}}/topics/'+node.id+'/"> <i class="fi-pencil edit"></i></a> <a id='+node.id+' class="objectsCheckbox"> <input type="checkbox"> </a>' + + {% endif %} + ); + } + } + } + }); + + // bind 'tree.click' event + $tree.bind( + 'tree.click', + function(event) { + // The clicked node is 'event.node' + var node = event.node; + + var parent_arr = []; + var parent_node = node; + parent_arr.push(node.id); + + // Bellow code manipulates the parent hierarchy of clicked node in a tree + while (parent_node) { + if (parent_node.name !== undefined){ + $tree.tree('openNode', parent_node); + parent_node = parent_node.parent; + if (parent_node.name !== undefined){ + parent_arr.push(parent_node.id); + } + } + else{ + break; + } + } + var nav_list = parent_arr.reverse(); + // alert(nav_list); + + // If its topic node i.e no children of this node then show the detail view for topic + if( node.children[0] == null ){ + + if (node.node_type == "Topic"){ + location.href = "/{{group_name_tag}}/topic_details/"+node.id+"?nav_li="+nav_list+""; + } + + } + + } + ); + + $tree.bind( + 'tree.contextmenu', + function(event) { + // The clicked node is 'event.node' + var node = event.node; + {% user_access_policy groupid request.user as user_access %} + {% if user_access == "allow" %} + var msg = confirm("Do you want to delete this topic ?"); + if (msg == true) { + + $.ajax({ + url: "{% url 'delete_themes' groupid %}", + type: 'POST', + data:{ + deleteobj: node.id, + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(result){ + alert("Topic "+node.name+" deleted successfully"); + location.reload(true); + }, + + }); + + } + {% endif %} + + } + ); + + + }; + + + // method to handle hover on topics + function showTopicStats(){ + // Javascript function to be used for checking objects in specific time of interval + setTimeout(function(){ + // On hover of topic node manipulate resources only once + + $(".jqtree-title.jqtree_common").hover( function(){ + + topic_id = $(this).siblings("a").attr("id"); + // var topic_name = $(this).siblings("a").attr("name"); + var data_info = $(this).attr("data-info"); + var hover_context = this; + if ( ! data_info && topic_id ){ + $(".topic_stats").css("display", "none"); + + $.ajax({ + url: "{% url 'get_topic_contents' groupid %}", + type: 'POST', + data:{ + node_id: topic_id, + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(data){ + + count = display_top_res(data) + + if (data != "{}"){ + + $(".topic_stats").html(count); + $(hover_context).attr("data-info", data) + + $(".topic_stats").css("display", "block"); + + } + else{ + $(hover_context).attr("data-info", data); + } + + }, + + }); + + + } + else{ + + if (topic_id){ + var data = $(this).attr("data-info"); + count = display_top_res(data) + $(".topic_stats").html(count); + $(".topic_stats").css("display", "block"); + } + + } + }); + + // console.log($(".jqtree-element.jqtree_common")) + if( ($(".jqtree-title.jqtree_common").length <= 0) ) { + showTopicStats() + } + + }, 1000 ); + } + + + function display_top_res(data){ + data_obj = JSON.parse(data); + count = "" + + if (data != "{}"){ + var k = Object.keys(data_obj); // To get the keys from incomming data + + for (var m = 0; m < k.length; m++) { + var key = k[m]; + var len = data_obj[key].length; // length of list as a value of key + // alert(key+": "+len); + count += key+": "+len+"<br/>"; + } + + } + else{ + count += "No Resources !<br/>"; + } + + return count + + } + + showTopicStats(); + + $("document").on("hover", ".jqtree-title.jqtree_common", function(){ + setTimeout(function(){ + }, 1000); + + alert($(this).siblings("a").attr("id")); + }); + + $("#add_theme_item").click(function() { + $.ajax({ + type: "POST", + url: "{% url 'add_theme_item' groupid %}", + datatype: "html", + data:{ + context_theme: "{{node.pk}}", + name: $(".name_id").val(), + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(data) { + + var item = $(".name_id").val(); + + if ($.trim(data) === "failure") { + alert("Theme item "+ item +" already available, Please choose different name"); + } + + if ($.trim(data) === "success") { + location.reload(true); + } + + $(".name_id").val(""); + } + }); + + }); + + // script for fold themes_cards hierarchy + $(".fold").click(function() { + $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}"; + }); + }); + + // script for unfold themes hierarchy + $(".unfold").click(function() { + $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}?unfold=true"; + }); + }); + + $(".tree_browser").click(function() { + $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}"; + }); + }); + + // script for delete themes + $(document).on('click',".button.deleteObjects",function(){ + var selectedobject = $(".objectsCheckbox input:checked") + + if(selectedobject.length > 0) + { + $('#myModal').foundation('reveal', 'open'); + + var i = 0; + var str = ""; + $.map(selectedobject,function(each){ + if(i == 0) + { + str = str.concat(each.parentElement.id) + } + else + { + str = str.concat(","+each.parentElement.id) + } + + i= i+1 + }) + + $.ajax({ + url: "{% url 'delete_themes' groupid %}", + type: 'POST', + data:{ + context_theme: "{{node.pk}}", + deleteobjects: str, + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(result){ + + $("#deletion_results").html(""); + for(var obj in result) + { + var li = $("<ul><li><b>"+result[obj].title+"</b></li></ul>").appendTo($("#deletion_results")); + } + + }, + }); + + } + else + { + alert("select object to delete") + } + + }); + + // Script for delete themes after confirm delete. + $(document).on('click',".button.confirmDeleteObjects",function(){ + var selectedobject = $(".objectsCheckbox input:checked") + + if(selectedobject.length > 0) + { + var i = 0; + var str = ""; + + $.map(selectedobject,function(each){ + if(i == 0) + { + str = str.concat(each.parentElement.id) + } + else + { + str = str.concat(","+each.parentElement.id) + } + + i= i+1 + }); + + $.ajax({ + url: "{% url 'delete_themes' groupid %}", + type: 'POST', + data:{ + context_theme: "{{node.pk}}", + deleteobjects: str, + confirm:"yes", + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(result){ + alert("Themes deleted successfully"); + $('#myModal').foundation('reveal', 'close'); + location.reload(true); + }, + + }); + + } + else{ + alert("select object to delete") + } + + }); + + // Script for selecting all objects + $(document).on('click',".checkedAll",function(){ + if($(this).is(":checked")==true) + { + $('.objectsCheckbox input').prop( "checked", true ); + } + else + { + $('.objectsCheckbox input').prop( "checked", false ); + } + }); + + // Script for cancel option for deleting themes + $(document).on('click',".button.cancelDeleteObjects",function(){ + $('#myModal').foundation('reveal', 'close'); + }); + + + $("document").on("hover", ".jqtree-title.jqtree_common", function(){ + setTimeout(function(){ + }, 1000); + + alert($(this).siblings("a").attr("id")); + }); + + // Script for selecting all objects + $(document).on('click',".checkedAll",function(){ + if($(this).is(":checked")==true) + { + $('.objectsCheckbox input').prop( "checked", true ); + } + else + { + $('.objectsCheckbox input').prop( "checked", false ); + } + }); + + // Script for cancel option for deleting themes + $(document).on('click',".button.cancelDeleteObjects",function(){ + $('#myModal').foundation('reveal', 'close'); + }); + + // script for delete themes + $(document).on('click',".button.deleteObjects",function(){ + var selectedobject = $(".objectsCheckbox input:checked") + + if(selectedobject.length > 0) + { + $('#myModal').foundation('reveal', 'open'); + + var i = 0; + var str = ""; + $.map(selectedobject,function(each){ + if(i == 0) + { + str = str.concat(each.parentElement.id) + } + else + { + str = str.concat(","+each.parentElement.id) + } + + i= i+1 + }) + + $.ajax({ + url: "{% url 'delete_themes' groupid %}", + type: 'POST', + data:{ + context_theme: "{{node.pk}}", + deleteobjects: str, + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(result){ + + $("#deletion_results").html(""); + for(var obj in result) + { + var li = $("<ul><li><b>"+result[obj].title+"</b></li></ul>").appendTo($("#deletion_results")); + } + + }, + }); + + } + else + { + alert("select object to delete") + } + + }); + + + // Script for delete themes after confirm delete. + $(document).on('click',".button.confirmDeleteObjects",function(){ + var selectedobject = $(".objectsCheckbox input:checked") + + if(selectedobject.length > 0) + { + var i = 0; + var str = ""; + + $.map(selectedobject,function(each){ + if(i == 0) + { + str = str.concat(each.parentElement.id) + } + else + { + str = str.concat(","+each.parentElement.id) + } + + i= i+1 + }); + + $.ajax({ + url: "{% url 'delete_themes' groupid %}", + type: 'POST', + data:{ + context_theme: "{{node.pk}}", + deleteobjects: str, + confirm:"yes", + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(result){ + alert("Themes deleted successfully"); + $('#myModal').foundation('reveal', 'close'); + location.reload(true); + }, + + }); + + } + else{ + alert("select object to delete") + } + + }); + + + </script> + + + {% if themes_hierarchy %} <!-- bool --> + + <h2> {{node.name}}</h2> + <div class="row"> + <div class="large-4 columns"> + + {% if user_access == "allow" %} + + <a class="button tiny" data-reveal-id="view_add_page" title="Add Theme Item"> + + Add Theme Item + </a> + + <div id="view_add_page" class="reveal-modal" data-reveal style="height:300px;"> + + <h3>Add New Theme Item:</h3> + <!-- To enter name of theme item --> + <div> + <input class="name_id" name="name" type="text" placeholder="Enter name..."> + </div> <br/> + + <input type="submit" id="add_theme_item" value="Save Theme Item" class="medium round button"/> + + <a class="close-reveal-modal">×</a> + + </div> + {% endif %} + </div> + + <div class="large-4 columns"> + + <a data-dropdown="hover1" data-options="is_hover:true; hover_timeout:5000" class="tree_browser" style="border: 2px solid #0eacb5; padding: 5px;"><b> {% trans "Tree Browser" %} </b></a> + <ul id="hover1" class="f-dropdown" data-dropdown-content> + <li><a class="fold"><i class="fi-plus"></i> {% trans "Fold" %} </a></li> + <li><a class="unfold"><i class="fi-minus"></i> {% trans "Unfold" %} </a></li> + </ul> + + <a class="collapsible_tree" style="border: 2px solid #0eacb5; padding: 5px;"><b> {% trans "Collapsible Tree" %} </b></a> + + </div> + + <div class="large-4 columns"> + {% if user.is_authenticated %} + {% if user_access == "allow" %} + + <input class="button tiny deleteObjects right" type="button" value="Delete"> + <span class="right"><input class="checkedAll" type="checkbox"> Select All </span> + + <div id="myModal" class="reveal-modal" data-reveal style="height:500px;overflow:scroll;"> + + <h3>{% trans "Are you sure you want to delete? All of the related items for the following themes also will be deleted:" %}</h3> + + <input class="button confirmDeleteObjects" type="button" value="Confirm"> + <input class="button cancelDeleteObjects" type="button" value="Cancel"> + <div id="deletion_results"></div> + <a class="close-reveal-modal">×</a> + + </div> + + {% endif %} + {% endif %} + </div> + </div> + <hr/> + + {% endif %} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/new_create_batch.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/new_create_batch.html index 77dcfa9..f6f9e0d 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/new_create_batch.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/new_create_batch.html @@ -4,6 +4,17 @@ {% load ndf_tags %} {% block title %} {{title}} {% endblock %} +{% block head %} + {{block.super}} + + <!-- DataTables --> + <script src="/static/ndf/bower_components/DataTables/media/js/jquery.dataTables.js"></script> + <script src="/static/ndf/bower_components/datatables-plugins/integration/foundation/dataTables.foundation.js"></script> + <!-- DataTables CSS --> + <link href="/static/ndf/bower_components/datatables-plugins/integration/foundation/dataTables.foundation.css" rel="stylesheet" type="text/css" /> +{% endblock %} + + {% block style %} {{block.super}} @@ -15,6 +26,9 @@ .margin-0 { margin: 0 !important; } + tr:hover{ + cursor:pointer; + } .resource-drawer { border-color: #D3D3D3; border-style: solid; @@ -40,10 +54,13 @@ font-size: 1rem; } + .existing_batch, .view_batch{ + text-decoration: underline; + } .posted-by{ color: #808080; font-size: small; } - .selected-resource { background-color:lightgray !important ; } + .selected { background-color:lightgray !important ; } .resource-type-image { height:40px; @@ -73,26 +90,24 @@ position: relative !important; } + .batch_create_edit_table > tr { + border: 1px solid black; + } {% endblock %} {% block body_content %} <div id="alertModal" class="reveal-modal small alert alert-box radius" data-reveal data-alert> <label id="alertModalLabel"> </label> - <div class="row hide"> - <div class="small-3 small-offset-3 columns"> - <input type="button" id="btnConfirmYes" class="button tiny expand" value="Yes"> - </div> - <div class="small-3 columns end"> - <input type="button" id="btnConfirmNo" class="button tiny expand " value="No"> - </div> - </div> <a class="close-reveal-modal">×</a> </div> -<form data-abide id="form-batch" method="POST" action="{% url 'save_batch_stud' groupid %}">{% csrf_token %} + <div id="batch_info" class="reveal-modal medium" data-reveal style="height:500px;overflow-y: auto !important;"> + <a class="close-reveal-modal">×</a> + </div> +<div class="course_details_div"> <fieldset id="stud-count" class="small-10 columns"> <div class="row"> <div class="small-2 columns"> @@ -119,43 +134,61 @@ <label id="stud_count" style='display: none'></label> <label id="lblstud" style='display: none'> {% trans "Student(s)" %}</label> </div> - <div class="small-12 columns" align="center"> <input type="button" class="small button right inline" id="nextbtn" value="Proceed" disabled="disabled" style='display: none'/> </div> - <br> - <fieldset id="make_batch_fs" class="hide small-12 columns"> +</div> - <div id="drawer-heading" class="row"> - <div class="small-6 columns right inline"> - <input type="text" id="drawer_head" name="drawer_head" disabled="disabled"> + <br> + <div class="batch_div hide"> + <div class="row"> + <div style="text-align: center;"> + <div class="small-4 columns end" style="display: inline-block; "> + <h4>{% trans 'Search Student by name : ' %}</h4> + </div> + <div class="small-4 columns end" style="display: inline-block; "> + <input type="text" class="ajax_input_name small-6 columns" value="" placeholder="Enter atleast 3 letters to search"> </div> </div> + </div> + </div> + <div class="datatable_div"></div> + + <div id="batch-details"></div> + - <br> - - <div id="drawer-div"> </div><br> - <div id="batch-details" style='display: block'> </div> - - <input type='button' name='add_btn' id='add_btn' value='Add Batch' class='button round small' onclick = 'add_new_batch()' style='display: none'> - <div> - <input type="submit" class="button right inline" id="save_batch" name="save_batch" value="Save" disabled="disabled" style='display: none'> - <input type="hidden" id="batch_user_list_dict" name="batch_user_list_dict"> - <input type="hidden" id="ac_id" name="ac_id"> + <fieldset id="make_batch_fs" class="hide small-12 columns"> + <table id="batch_create_edit_table"> + <tbody> + </tbody> + </table> + <input type="button" class="create_batch_row button small" value="Create Batch" disabled="disabled"> + <li style="color:red;">Batch once created CANNOT be deleted</li> + <li>Click on Batch name to add more students to the batch</li> + <li>Click on 'View' to display/remove batch members</li> + <div class="batch_create_div hide"> + <input type="text" class="batch_name_inp" placeholder="Enter name of Batch"> + <input type="button" class="save small round button" value="Save"> + <input type="button" class="cancel small round button" value="Cancel"> + </div> + <input type="hidden" name="batch_user_list_dict" id="batch_user_list_dict"> + <input type="hidden" name="ac_id" id="ac_id"> </div> </fieldset> - - </form> {% endblock %} - +<script> {% block script%} //global variables var ac_id="" + var ac; + var added_ids_list = [] var batch_name_index; + var batch_name; var ac_name_as_prefix; var batch_user_list_dict = {} var batch_user_list_list = {} var scount_lbl = 0 + var sce_dt_var; //For selecting Course type $("select#nussd_course_type").change(function() { var nussd_course_type = $("#nussd_course_type").val(); @@ -268,196 +301,343 @@ //Proceed to create batches for selected AC $("#nextbtn").click(function(event) { - ac_id = $("#acourse_list").val(); - if ($("#nextbtn").css("display") != "none") { $("#nextbtn").css("display", "none"); } - $("#nussd_course_type").attr("disabled","disabled") - $("#acourse_list").attr("disabled","disabled") - + // $("#nussd_course_type").attr("disabled","disabled") + // $("#acourse_list").attr("disabled","disabled") + // Give a textbox to enter name + + $(".batch_div").removeClass("hide"); + $(".course_details_div").addClass("hide"); + nc = $("#nussd_course_type").val(); + ac = $("#acourse_list option:selected").text() + ac_id = $("#acourse_list").val(); + $("aside.medium-2.columns").html("Batch creation for: <b>'"+ac+"'</b> ("+nc+")") $.ajax({ - url: "{% url 'get_students_for_batches' group_id %}", + url: "{% url 'get_possible_batches' groupid %}", + data: { - ac_id: ac_id + 'ac_id': ac_id, + 'create_new_batch':true, + 'csrfmiddlewaretoken': "{{csrf_token}}" }, - type: "GET", + + type: "POST", + dataType: "json", - success: function(data){ - success_state = data["success"]; - if (data["success"]) { - drawer_widget = data["drawer_widget"]; - ac_name_as_prefix = $("#acourse_list option:selected").text() - $("#drawer-div").html(drawer_widget); - scount_lbl = data["student_count"] - $("#stud_count").css("font-size", "53px"); - $("#stud_count").text(scount_lbl) - - - batch_name_index = data["batch_name_index"] - $("#drawer_head").attr("size",ac_name_as_prefix.length+10) - $("#drawer_head").attr("value",ac_name_as_prefix +"_Batch_"+batch_name_index); - a = data["batches_for_same_course"] - a = JSON.parse(a) - - $.each(a, function(index, batch_node) { - arr_batch_mem_nodes = [] - batch_user_list_list_arr = [] - $.each(batch_node["has_batch_member"],function (index, batch_mem_list){ - li_ele = "<li class='bullet-item text-left' value='"+batch_mem_list["_id"]+"'><input type='hidden' value='"+batch_mem_list["_id"]+"' name='"+batch_mem_list["name"]+"' class='node_id new_create_batch_values'><div class='row'><div class='small-1 columns resource-type-image' style='background-image: url();'></div><div class='small-11 columns'><div class='row'><div class='small-12 columns'><b>"+batch_mem_list["name"]+" </b></div><div class='small-12 columns text-left' style='padding-top:3px'><i class='posted-by'>Student by <a class='user' href='/1/dashboard' data-gnow=''></a> on 19 October 2014 </i></div></div><div class='row'><div class='small-12 columns text-left' style='padding-top:5px;'>None</div></div></div></div></li>" - arr_batch_mem_nodes.push(li_ele) - batch_user_list_list_arr.push(batch_mem_list["_id"]) - }); - batch_user_list_dict[batch_node["name"]] = arr_batch_mem_nodes - batch_user_list_list[batch_node["name"]] = batch_user_list_list_arr - batch_det_str = "<ul class='button-group'><li><a href='#' class='button edit_batch' id='"+batch_node["name"]+"'>"+batch_node["name"]+" -- " + arr_batch_mem_nodes.length + " members.</a></li></ul><br>" - $("#batch-details").append(batch_det_str) - }); - } - else { - alert("Failed to get drawer") + success: function(data){ + success_state = data["success"] + if(success_state){ + batch_data = data['old_batches'] + if (batch_data!=""){ + // batch_user_list_dict = batch_data + $("#make_batch_fs").removeClass("hide") + var table = document.getElementById("batch_create_edit_table"); + $.each(batch_data, function(index){ + $.each(batch_data[index], function(key,val){ + batch_user_list_dict[key] = val[0] + var row = table.insertRow(-1); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + cell1.innerHTML = "<span data-tooltip title='Click to view/edit'>View</span>"; + cell1.className = "view_batch"; + cell2.innerHTML = "<span data-tooltip title='Click to Add to this Batch'>"+key+"</span>"; + cell2.className = "save"; + cell2.className += " existing_batch"; + cell2.id = val[1]; + cell3.innerHTML = "<span data-tooltip title='Total students'>"+val[0].length+" student(s)<span>"; + cell3.className = "stud_count_in_batch"; + val.pop(); + }) + }) + } } }, - complete:function(data){ - $("#make_batch_fs").removeClass("hide") + });//end of ajax - if ($("#save_batch").css("display") == "none") { - $("#save_batch").toggle(); - } - if ($("#add_btn").css("display") == "none") { - $("#add_btn").toggle(); - } - {% if node %} - $("#{{node.name}}").trigger('click') - {% endif %} - } - }); });//end of nextbtn.click() - // On click of Batch link - $(document).on("click",".edit_batch", function(event){ - if ($("#new_create_batch_drawer2").children("li").length==0){ - edit_batch_name = $(this).attr('id'); - edit_batch_name=edit_batch_name - $("#drawer_head").attr("value",edit_batch_name); - $("#new_create_batch_drawer2").html("") + // Click event: "Student data" Row of DataTable + $(document).on( 'click', '#student_data_table tbody tr', function () { + $(this).toggleClass('selected'); + $("#make_batch_fs").removeClass("hide") + $(".create_batch_row").removeAttr("disabled") + }); + + // On click of create batch button + $(document).on( 'click', '.create_batch_row', function () { + $(".batch_create_div").removeClass("hide") + total_batches = Object.keys(batch_user_list_dict).length + 1 + $(".batch_name_inp").val(ac + " - Batch " + total_batches) + .attr("disabled", true) + $(".create_batch_row").attr("disabled",true) + + }); - if(batch_user_list_dict.hasOwnProperty(edit_batch_name)){ - for (i=0;i<batch_user_list_dict[edit_batch_name].length;i++){ - $("#new_create_batch_drawer2").append(batch_user_list_dict[edit_batch_name][i]) + // Create batch and add selected students to it. + // Also hide batch_create_div from first row + // Add new row to batch create edit table with the batch name as inputted + $(document).on( 'click', '.save', function () { + arr = [] + batch_id = null; + //do nothing + $(".create_batch_row").attr("disabled",true) + + $(".batch_create_div").addClass("hide"); + batch_name = $(".batch_name_inp").val(); + sce_dt_var.$("tr.selected").each(function () { + $(this).removeClass('selected'); + arr.push(this.id); + }); + if (arr.length != 0){ + if($(this).hasClass('existing_batch')){ + batch_name = $(this).text() + if(batch_user_list_dict.hasOwnProperty(batch_name)){ + old_arr = batch_user_list_dict[batch_name] + batch_user_list_dict[batch_name] = old_arr.concat(arr) + $(this).next('td').html(batch_user_list_dict[batch_name].length+ " student(s)") + arr = batch_user_list_dict[batch_name] + batch_id = $(this).attr('id') } } - if ($("#drawer_head").css("display") == "none") { - $("#drawer_head").toggle() - } - if ($("#add_btn").css("display") == "none") { - $("#add_btn").toggle() - } - if (!($("#batch-details").css("display") == "none")) { - $("#batch-details").toggle() - } - $("#save_batch").attr("disabled",true) - event.preventDefault(); - return false; + $.ajax({ + url: "{% url 'save_batch' groupid %}", + + data: { + 'ac_id': ac_id, + 'batch_name': batch_name, + 'batch_id': batch_id, + 'user_list':arr, + 'csrfmiddlewaretoken': "{{csrf_token}}" + }, + + type: "POST", + + dataType: "json", + + success: function(data){ + new_batch_node = data + if(new_batch_node['new_batch_created']){ + var table = document.getElementById("batch_create_edit_table"); + var row = table.insertRow(-1); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + batch_user_list_dict[batch_name] = arr; + cell2.innerHTML = "<span data-tooltip title='Click to Add to this Batch'>"+new_batch_node['new_batch_node_name']+"</span>"; + + cell2.className = "save"; + cell2.className += " existing_batch"; + cell2.id = new_batch_node['new_batch_node_id'] + cell3.innerHTML = "<span data-tooltip title='Total students'>"+batch_user_list_dict[batch_name].length+" student(s)<span>"; + cell3.className = "stud_count_in_batch"; + cell1.innerHTML = "<span data-tooltip title='Click to view/edit'>View</span>"; + + cell1.className = "view_batch"; + } + $(".batch_name_inp").val(''); + $('.ajax_input_name').val(''); + $(".datatable_div").html(''); + }, + });//end of ajax } else{ - alert("Please add to batch "); - event.preventDefault(); - return false; + alert("Please select students"); } - }); - - // Confirm create batch reveal modal - var create_batch_flag = false; - $(document).on("click", "#btnConfirmYes", function() { - create_batch_flag = true; - $("#alertModal").foundation('reveal', 'close'); - add_new_batch(); - }); - $(document).on("click", "#btnConfirmNo", function() { - create_batch_flag = false; - $("#alertModal").foundation('reveal', 'close'); - }); + }) - //Add new batch - function add_new_batch(event){ - - //Fetch the value of "#drawer_head" which will be key for above dict - batch_name= $("#drawer_head").val() - - arr = [] //Value for above key - arr1 = [] - //Add the right drawer resources to this list. - $("#new_create_batch_drawer2").children("li").each(function(c,v){arr.push(v);arr1.push(v.getAttribute("value"))}); - left_drawer_count = $("#new_create_batch_drawer1").children("li").length - if ((arr.length >= 30 && left_drawer_count >= 26) || (arr.length >= 25 && left_drawer_count == 1)) { - if(!create_batch_flag){ - $("#alertModal").foundation('reveal', 'open'); - $("#alertModal").find("div.row").removeClass("hide"); - lbl = "Batch once created CANNOT be deleted. Confirm to proceed. Do you want to continue?" - $("#alertModalLabel").text(lbl); + //view batch members on click of 'View' + $(document).on( 'click', '.view_batch ', function () { + + batch_id = $(this).next('.existing_batch').attr('id'); + batch_name = $(this).next('.existing_batch').text(); + $.ajax({ + url: "{% url 'batch_detail' groupid %}", + + data: { + 'batch_id': batch_id, + }, + + type: "GET", + + dataType: "json", + + success: function(data){ + $("#batch_info").html("") + if(data!=""){ + var table = document.createElement("TABLE"); + table.id = batch_id + table.className = "batch_table_id" + $.each(data, function(index){ + var row = table.insertRow(-1); + var cell1 = row.insertCell(0); + cell1.innerHTML = data[index]['name']; + var cell2 = row.insertCell(1); + cell2.innerHTML = "Remove from Batch"; + cell2.id = data[index]['_id']; + cell2.className = 'button alert remove_stud'; + }) + $("#batch_info").append(table) } else{ - create_batch_flag = false; - $("#save_batch").removeAttr("disabled") - $("#stud_count").css("font-size", "53px"); - $("#stud_count").text(left_drawer_count-1) + $("#batch_info").html("No data to display") + } + $("#batch_info").append("<a class='close-reveal-modal'>×</a>") + $('#batch_info').foundation('reveal', 'open'); - if(batch_user_list_dict.hasOwnProperty(batch_name)){ - batch_user_list_dict[batch_name] = arr - $("#"+batch_name).text(batch_name + " -- " + arr.length+" members"); - } - else{ - batch_user_list_dict[batch_name] = arr - //Display the Batch details - batch_det_str="<ul class='button-group'><li><a href='#' class='button edit_batch' id='"+batch_name+"'>" + batch_name + " -- " + arr.length + " members.</a></li></ul><br>" - $("#batch-details").append(batch_det_str) - batch_name_index += 1; - } - batch_user_list_list[batch_name] = arr1 - - //Remove these resources from right drawer. - $("#new_create_batch_drawer2").html("") - if($("#new_create_batch_drawer1").children("li").length==1) - { - $("#drawer_head").css("display","none") - $("#add_btn").css("display","none") - } - else{ - $("#drawer_head").attr("value",ac_name_as_prefix + "_Batch_"+ batch_name_index); - } - if ($("#batch-details").css("display") == "none") { - $("#batch-details").toggle() + }, + });//end of ajax + + + + }) + + + //remove batch members + $(document).on( 'click', '.remove_stud ', function () { + stud_id = $(this).attr('id'); + batch_id = $(".batch_table_id").attr('id') + $(this).closest("tr").remove() + $.ajax({ + url: "{% url 'remove_stud_from_batch' groupid %}", + + data: { + 'batch_id': batch_id, + 'stud_id': stud_id, + 'csrfmiddlewaretoken': "{{csrf_token}}" + }, + + type: "POST", + + dataType: "json", + + success: function(data){ + status = data + if(status=="success"){ + if(batch_user_list_dict.hasOwnProperty(batch_name)){ + old_arr = batch_user_list_dict[batch_name] + if(old_arr.indexOf(stud_id)>=0){ + i = old_arr.indexOf(stud_id) + old_arr.splice(i,1) + } + batch_user_list_dict[batch_name] = old_arr } + $("#batch_create_edit_table").find("#"+batch_id).next('.stud_count_in_batch').html(old_arr.length+ " student(s)") } - } - else{ - if(left_drawer_count < 26){ - alertlabel = "Please add Remaining students to the batch. As " + (left_drawer_count-1) + " cannot form a new batch."; - } - else{ - alertlabel = "Please select atleast 30 students"; + }, + });//end of ajax + + + }) + + + // Make an ajax call to search approved student + // of the selected AC with entered name + // ajax search student by name + var search_text_old = ""; + $(document).on( 'keyup', '.ajax_input_name', function (e) { + var search_text = (this.value).toLowerCase(); + var search_text_len = (search_text.length); + ac_id = $("#acourse_list").val(); + + // if (e.keyCode == 8) { + // // If backspace pressed, then do nothing + // search_text_len = 0; + // } + if (search_text_len > 2){ + for(var key in batch_user_list_dict){ + added_ids_list = added_ids_list.concat(batch_user_list_dict[key]) } - $("#alertModalLabel").text(alertlabel); - $("#alertModal").foundation('reveal', 'open'); - return false; + + $.ajax({ + type: "POST", + url: "{% url 'get_students_for_batches' groupid %}", + datatype: "json", + data:{ + 'search_text': search_text, + 'ac_id': ac_id, + 'added_ids_list':added_ids_list, + 'csrfmiddlewaretoken': '{{ csrf_token }}' + }, + success: function(data) { + data = JSON.parse(data) + success_state = data["success"]; + search_text_old = search_text + // $("#alertModalLabel").text(data["message"]); + + if (success_state) { + students_count = data["students_count"]; + column_headers = data["column_headers"]; + students_data_set = data["students_data_set"]; + dataTable_columns_set = []; + + if (parseInt(students_count) <= 0) { + c = '<div class="row">' + + '<div class="large-4 large-centered columns">' + + '<p class="alert-box alert radius text-center text-size-15">No records match the given criteria !!!</p>' + + '</div>' + + '</div>' + $(".datatable_div").html(c); + } + + else { + // Define table + student_data_table = '<table cellpadding="0" cellspacing="0" border="0" class="display" id="student_data_table">' + + '<caption>' + + '<h6>No. of Students: <b>' + students_count + '</b></h6>' + + '<label>(Click on Name to select student)</label></caption>' + + '</table>'; + $(".datatable_div").html(student_data_table); + + // Prepare title & data headers used in dataTable + $.each(column_headers, function(index, v) { + d = {}; + d["data"] = v[0]; + d["title"] = v[1]; + dataTable_columns_set.push(d); + }); + + // Set defintion dataTable + sce_dt_var = $("#student_data_table").dataTable({ + "data": students_data_set, + "columns": dataTable_columns_set, + "columnDefs": [{ "width": "15%", "targets": 0 }], + "createdRow": function ( row, data, index ) { + // Attaching Student's ObjectId to each row (i.e., assigning to it's id attribute) + s_id = data["stud_id"]; + $(row).attr("id", s_id); + } + }); + } + } + else { + $("#alertModal").removeClass("success").removeClass("warning"); + $("#alertModal").addClass("alert"); + $("#alertModal").foundation('reveal', 'open'); + } + }, + }); } - }; + }) + + // + $(document).on('click','.cancel',function(){ + $(".batch_create_div").addClass("hide") + $(".batch_name_inp").val(""); + $(".create_batch_row").removeAttr("disabled") + }); - //Saving students to batch as batch members - $("#form-batch").submit(function(event){ - $("#batch_user_list_dict").val(JSON.stringify(batch_user_list_list)) - $("#ac_id").val(ac_id) - }); // end of save_after_create_batch {% endblock %} - +</script> {% block document_ready %} {% if nussd_course_name %} $("select#nussd_course_type").val("{{nussd_course_name}}"); @@ -466,4 +646,5 @@ if ($("select#nussd_course_type :selected").index() > 0) { $("select#nussd_course_type").trigger("change"); } + {% endblock %} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html index 6f61ec2..bb3d0a0 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html @@ -1663,7 +1663,7 @@ ul#navigation li a.last { {% if topic %} - location.href = "{% url 'theme_page' group_name_tag theme_id %}?selected="+clicked_node+""; + location.href = "{% url 'theme_page' group_name_tag theme_id %}?tree=hierarchical&selected="+clicked_node+""; {% else %} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html index 280f231..d1aaf1d 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html @@ -7,52 +7,47 @@ {% get_group_name groupid as group_name_tag %} - {% block title %} {{ title }} {% endblock %} {% block head %} - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + + <!-- Scripts required for D3 graph --> + <script type="text/javascript" src="/static/ndf/bower_components/d3/d3.min.js"></script> + <script type="text/javascript" src="/static/ndf/bower_components/underscore/underscore.js"></script> + <script sync="text/javascript" src="/static/ndf/bower_components/FileSaver/FileSaver.js" ></script> - <!-- Scripts required for D3 graph --> - <script type="text/javascript" src="/static/ndf/bower_components/d3/d3.min.js"></script> <!-- checked --> - <script type="text/javascript" src="/static/ndf/bower_components/underscore/underscore.js"></script> <!-- checked --> - <script sync="text/javascript" src="/static/ndf/bower_components/FileSaver/FileSaver.js" ></script> <!-- checked --> + <link href="/static/ndf/bower_components/jqtree/jqtree.css" rel="stylesheet"> + <script src="/static/ndf/bower_components/jqtree/tree.jquery.js"></script> - <link href="/static/ndf/bower_components/jqtree/jqtree.css" rel="stylesheet"> - <script src="/static/ndf/bower_components/jqtree/tree.jquery.js"></script> <!-- checked --> - - <script type="text/javascript"> +<!-- <script type="text/javascript"> $(document).ready(function() { + // Funtion for loading tree for showing collection list left side panel + doc(); - // Funtion for loading tree for showing collection list left side panel - doc(); + // Function for manipulating tree when user visits to page directly via browser url + {% if selected %} TreeTillNode(); {% endif %} + }); - // Function for manipulating tree when user visits to page directly via browser url - {% if selected %} - TreeTillNode(); - {% endif %} + function TreeTillNode () { - }); + // This gives the last hierarchy node id from browser url. + var url = "{{selected}}"; + var tree_build = $(".themes").not(".jqtree-loading"); + var node = tree_build.tree('getNodeById', url); + tree_build.tree('openNode', node); - function TreeTillNode () { - // This gives the last hierarchy node id from browser url. - var url = "{{selected}}"; + // Javascript function to be used for checking objects in specific time of interval + setTimeout(function(){ - var tree_build = $(".themes").not(".jqtree-loading"); - var node = tree_build.tree('getNodeById', url); - tree_build.tree('openNode', node); - - // Javascript function to be used for checking objects in specific time of interval - setTimeout(function(){ - // console.log($(".themes")) - if( ($(".themes").length > 0) ) { TreeTillNode() } - }, 100 ); - + // console.log($(".themes")) + if( ($(".themes").length > 0) ) { TreeTillNode() } + }, 100 ); } @@ -80,16 +75,12 @@ else{ $li.find('.jqtree-title').before('  <span class="fi-folder" style="color:orange"></span> '); } - if (node.node_type == "Topic"){ - $li.find('.jqtree-element').append( ' <a id='+node.id+' name='+node.name+' class="topic" href="/{{groupid}}/topics/'+node.id+'/"> </a>' - ); - } else{ if (user == "True"){ @@ -103,12 +94,8 @@ {% endif %} ); } - } - - } - }); // bind 'tree.click' event @@ -143,7 +130,6 @@ if (node.node_type == "Topic"){ location.href = "/{{group_name_tag}}/topic_details/"+node.id+"?nav_li="+nav_list+""; - } } @@ -239,8 +225,6 @@ } } - - }); // console.log($(".jqtree-element.jqtree_common")) @@ -278,9 +262,9 @@ showTopicStats(); </script> - + --> <style> - +/* #app-set-item li { padding:0.5em } .jqtree-closed > .jqtree-element i.icon-folder-open:before { @@ -289,7 +273,7 @@ .jqtree-tree i { margin-right: 4px; } - /* for reingold tilford tree */ +*/ /* for reingold tilford tree */ /* .node { cursor: pointer; @@ -313,26 +297,31 @@ */ /* for reingold tilford tree -- end */ - .node { + /*.node { cursor: pointer; - } - + }*/ +/* .node circle { fill: #fff; stroke: steelblue; stroke-width: 1.5px; } - - .node text { +*/ + /*.node text { font-size:10px; font-family:sans-serif; - } - + }*/ +/* .link { fill: none; stroke: #ccc; stroke-width: 1.5px; } +*/ + #theme-drag-zoom-tree-container{ + border: medium dashed #D8BFD8; + border-radius: 5px; + } /* .templink { fill: none; @@ -340,25 +329,39 @@ stroke-width: 3px; } */ - .ghostCircle.show{ + /*.ghostCircle.show{ display:block; - } - + }*/ +/* .ghostCircle, .activeDrag .ghostCircle{ display: none; + }*/ + + .download-graph{ + color: gray + } + .download-graph:hover { + color: black; + background-color: #e5e5e5; + font-size: large; + cursor: pointer; + padding: 0.5em; + transition: all 1s; } </style> {% endblock%} -{% block shelf_content %} - {% if user.is_authenticated %} - {% include "ndf/shelf.html" %} - {% else %} - <h4>Please Login to create your shelf</h4> - {% endif %} -{% endblock %} +{% comment %} + {% block shelf_content %} + {% if user.is_authenticated %} + {% include "ndf/shelf.html" %} + {% else %} + <h4>Please Login to create your shelf</h4> + {% endif %} + {% endblock %} +{% endcomment %} {% block meta_content %} <a class="Tp" href="{% url 'topics' group_name_tag %}" title="Click to go to themes card view"><h2 class="subheader">{% trans "Themes" %}</h2></a> @@ -372,7 +375,7 @@ <ul class="no-bullet" id="app-set-item"> {% get_memberof_objects_count theme_GST_id groupid as count %} - + <li class="selected-app-set-item"> <div> {% if user_access == "allow" %} @@ -398,90 +401,30 @@ {% block body_content %} -{% user_access_policy groupid request.user as user_access %} - - <!-- This overlay is for displaying topic details from collapsible tree --> - <!-- <div id="collaps_topic_details" class="reveal-modal" style="height:500px;overflow:hidden;width:80%" data-reveal> - <h3>Topic details comming soon !!!</h3> - <a class="close-reveal-modal" >×</a> - </div> --> - <!-- End of overlay --> - - {% if themes_hierarchy %} - - <h2> {{node.name}}</h2> - <div class="row"> - <div class="large-4 columns"> - - {% if user_access == "allow" %} - - <a class="button tiny" data-reveal-id="view_add_page" title="Add Theme Item"> - + Add Theme Item - </a> - - <div id="view_add_page" class="reveal-modal" data-reveal style="height:300px;"> - - <h3>Add New Theme Item:</h3> - <!-- To enter name of theme item --> - <div> - <input class="name_id" name="name" type="text" placeholder="Enter name..."> - </div> <br/> - - <input type="submit" id="add_theme_item" value="Save Theme Item" class="medium round button"/> - - <a class="close-reveal-modal">×</a> - </div> - {% endif %} - </div> - - <div class="large-4 columns"> + {% user_access_policy groupid request.user as user_access %} - <a data-dropdown="hover1" data-options="is_hover:true; hover_timeout:5000" class="tree_browser" style="border: 2px solid #0eacb5; padding: 5px;"><b> {% trans "Tree Browser" %} </b></a> - <ul id="hover1" class="f-dropdown" data-dropdown-content> - <li><a class="fold"><i class="fi-plus"></i> {% trans "Fold" %} </a></li> - <li><a class="unfold"><i class="fi-minus"></i> {% trans "Unfold" %} </a></li> - </ul> - - <a class="collapsible_tree" style="border: 2px solid #0eacb5; padding: 5px;"><b> {% trans "Collapsible Tree" %} </b></a> - </div> + {% if themes_hierarchy and node %} - <div class="large-4 columns"> - {% if user.is_authenticated %} - {% if user_access == "allow" %} - - <input class="button tiny deleteObjects right" type="button" value="Delete"> - <span class="right"><input class="checkedAll" type="checkbox"> Select All </span> - <div id="myModal" class="reveal-modal" data-reveal style="height:500px;overflow:scroll;"> - - <h3>{% trans "Are you sure you want to delete? All of the related items for the following themes also will be deleted:" %}</h3> - - <input class="button confirmDeleteObjects" type="button" value="Confirm"> - <input class="button cancelDeleteObjects" type="button" value="Cancel"> - <div id="deletion_results"></div> - <a class="close-reveal-modal">×</a> + {% cache 300 theme_tree node.pk request.LANGUAGE_CODE %} - </div> + {% include "ndf/hierarchy_tree.html" %} + <div id="app-set-item" class="themes hide" data-url="{% url 'get_tree_hierarchy' groupid node.pk %}"> + </div> - {% endif %} - {% endif %} - </div> - </div> - <hr/> - - {% if node %} - {% cache 300 theme_tree node.pk request.LANGUAGE_CODE %} - <!-- If "Theme" node --> - <div id="app-set-item" class="themes" data-url="{% url 'get_tree_hierarchy' groupid node.pk %}"></div> - - <!-- testing --> + <div id="theme-drag-zoom-tree-container" class="hide"> + <div id="theme-drag-zoom-tree"></div> + <div class="row"> + <div class="small-6 small-centered text-center columns download-graph" onclick='downloadCollapsibleGraph("{{node.name}}");'> + Download "{{node.name}}" Collapsible Graph + </div> + </div> + </div> {% include 'ndf/theme_drag_zoom_d3tree.html' %} - {% endcache %} - - {% endif %} - + {% endcache %} + {% endif %} <!-- For displaying themes items --> @@ -654,358 +597,315 @@ <script type="text/javascript"> // ------ jqtree tree ------ - $("document").on("hover", ".jqtree-title.jqtree_common", function(){ - setTimeout(function(){ - }, 1000); + // script for fold themes_cards hierarchy - alert($(this).siblings("a").attr("id")); - }); + {% if node %} + + {% if tree == "hierarchical" %} + if({{unfold}}) + { + $("article").block({message: '<h4>Building a graph... <br/>Please hold on...</h4>'}); + $("#theme-drag-zoom-tree-container").addClass("hide") + $(".themes").removeClass("hide"); + plotHierarchyTree(true); + } + else + { + $("article").block({message: '<h4>Building a graph... <br/>Please hold on...</h4>'}); + $("#theme-drag-zoom-tree-container").addClass("hide") + $(".themes").removeClass("hide"); + plotHierarchyTree(false); + } + + {% else %} + + $(".themes").addClass("hide"); + + {% if node %} + + $("article").block({message: '<h4>Building a graph... <br/>Please hold on...</h4>'}); + $.getJSON("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(data){ treeData = data;}) + .done(function(){plotDragZoomTree(treeData); + }); + + {% endif %} + + $("#theme-drag-zoom-tree-container").removeClass("hide"); + + {% endif %} + + {% endif %} - $("#add_theme_item").click(function() { - $.ajax({ - type: "POST", - url: "{% url 'add_theme_item' groupid %}", - datatype: "html", - data:{ - context_theme: "{{node.pk}}", - name: $(".name_id").val(), - csrfmiddlewaretoken: '{{ csrf_token }}' - }, - success: function(data) { - - var item = $(".name_id").val(); - - if ($.trim(data) === "failure") { - alert("Theme item "+ item +" already available, Please choose different name"); - } - - if ($.trim(data) === "success") { - location.reload(true); - } - - $(".name_id").val(""); - } - }); - }); - // script for fold themes_cards hierarchy $(".fold").click(function() { - $(function() { - location.href = "{% url 'theme_page' group_name_tag app_id %}"; - }); + + // $("#theme-drag-zoom-tree-container").addClass("hide") + // $(".themes").removeClass("hide"); + // plotHierarchyTree(false); + // $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}?tree=hierarchical"; + // }); }); // script for unfold themes hierarchy $(".unfold").click(function() { - $(function() { - location.href = "{% url 'theme_page' group_name_tag app_id %}?unfold=true"; - }); + + // $("#theme-drag-zoom-tree-container").addClass("hide") + // $(".themes").removeClass("hide"); + // plotHierarchyTree(true); + // $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}?tree=hierarchical&unfold=true"; + // }); }); $(".tree_browser").click(function() { - $(function() { - location.href = "{% url 'theme_page' group_name_tag app_id %}"; - }); + + // $("#theme-drag-zoom-tree-container").addClass("hide") + // $(".themes").removeClass("hide"); + // plotHierarchyTree() + // $(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}?tree=hierarchical"; + // }); }); - // script for delete themes - $(document).on('click',".button.deleteObjects",function(){ - var selectedobject = $(".objectsCheckbox input:checked") - if(selectedobject.length > 0) - { - $('#myModal').foundation('reveal', 'open'); - - var i = 0; - var str = ""; - $.map(selectedobject,function(each){ - if(i == 0) - { - str = str.concat(each.parentElement.id) - } - else - { - str = str.concat(","+each.parentElement.id) - } - - i= i+1 - }) - - $.ajax({ - url: "{% url 'delete_themes' groupid %}", - type: 'POST', - data:{ - context_theme: "{{node.pk}}", - deleteobjects: str, - csrfmiddlewaretoken: '{{ csrf_token }}' - }, - success: function(result){ - - $("#deletion_results").html(""); - for(var obj in result) - { - var li = $("<ul><li><b>"+result[obj].title+"</b></li></ul>").appendTo($("#deletion_results")); - } - - }, - }); - - } - else - { - alert("select object to delete") - } - - }); - - // Script for delete themes after confirm delete. - $(document).on('click',".button.confirmDeleteObjects",function(){ - var selectedobject = $(".objectsCheckbox input:checked") - - if(selectedobject.length > 0) - { - var i = 0; - var str = ""; - - $.map(selectedobject,function(each){ - if(i == 0) - { - str = str.concat(each.parentElement.id) - } - else - { - str = str.concat(","+each.parentElement.id) - } + $(".collapsible_tree").click(function() { + location.href = "{% url 'theme_page' group_name_tag app_id %}?tree=collapsible"; - i= i+1 - }); + // $(".themes").addClass("hide"); - $.ajax({ - url: "{% url 'delete_themes' groupid %}", - type: 'POST', - data:{ - context_theme: "{{node.pk}}", - deleteobjects: str, - confirm:"yes", - csrfmiddlewaretoken: '{{ csrf_token }}' - }, - success: function(result){ - alert("Themes deleted successfully"); - $('#myModal').foundation('reveal', 'close'); - location.reload(true); - }, - - }); - - } - else{ - alert("select object to delete") - } + // {% if node %} - }); + // $.getJSON("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(data){ treeData = data;}) + // .done(function(){plotDragZoomTree(treeData)}); - // Script for selecting all objects - $(document).on('click',".checkedAll",function(){ - if($(this).is(":checked")==true) - { - $('.objectsCheckbox input').prop( "checked", true ); - } - else - { - $('.objectsCheckbox input').prop( "checked", false ); - } + // {% endif %} + + // $("#theme-drag-zoom-tree-container").removeClass("hide") }); - // Script for cancel option for deleting themes - $(document).on('click',".button.cancelDeleteObjects",function(){ - $('#myModal').foundation('reveal', 'close'); + // $("#theme-drag-zoom-container").removeClass("hide"); + + // // calling function plotDragZoomTree defined in theme_drag_zoom_d3tree.html + // } + + + $("#add_theme_item").click(function() { + $.ajax({ + type: "POST", + url: "{% url 'add_theme_item' groupid %}", + datatype: "html", + data:{ + context_theme: "{{node.pk}}", + name: $(".name_id").val(), + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(data) { + + var item = $(".name_id").val(); + + if ($.trim(data) === "failure") { + alert("Theme item "+ item +" already available, Please choose different name"); + } + + if ($.trim(data) === "success") { + location.reload(true); + } + + $(".name_id").val(""); + } + }); + }); + // ------END of jqtree tree ------ // --- start of D3 collapsible tree --- - treeData = "" + // treeData = "" - $(".collapsible_tree").click(function() { + // $(".collapsible_tree").click(function() { - if(treeData.length != 0) - { - plotCollapsibleTree(treeData) - } - else{ - {% if node %} - $.getJSON("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(data){ treeData = data;}) - .done(function(){plotCollapsibleTree(treeData)}); - {% endif %} - } - }); - - function plotCollapsibleTree (treeData) { - $(".themes").html(""); + // if(treeData.length != 0) + // { + // plotCollapsibleTree(treeData) + // } + // else{ + // {% if node %} - var margin = {top: 20, right: 40, bottom: 20, left: 40}, - width = Math.max($(".themes").width(), 960) - margin.right - margin.left, - height = Math.max($(".themes").height(), 800) - margin.top - margin.bottom; - - var i = 0, - duration = 750, - root; - - var tree = d3.layout.tree() - .size([height, width]); - - var diagonal = d3.svg.diagonal() - .projection(function(d) { return [d.y, d.x]; }); - - var svg = d3.select(".themes").append("svg") - .attr("width", width + margin.right + margin.left) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - {% if node %} - // d3.json("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(error, flare) { - root = treeData; - root.x0 = height / 2; // the point from where it starts it's animation. - root.y0 = 0; - - function collapse(d) { - if (d.children) { - d._children = d.children; - d._children.forEach(collapse); - d.children = null; - } - } - - root.children.forEach(collapse); - update(root); - // }); - {% endif %} - - // d3.select(self.frameElement).style("height", "800px"); - - function update(source) { - - // Compute the new tree layout. - var nodes = tree.nodes(root).reverse(), - links = tree.links(nodes); - - // Normalize for fixed-depth. - nodes.forEach(function(d) { d.y = d.depth * 150;}); - - // Update the nodes - var node = svg.selectAll("g.node") - .data(nodes, function(d) { return d.id || (d.id = ++i); }); - - // Enter any new nodes at the parent's previous position. - var nodeEnter = node.enter().append("g") - .attr("class", "node") - .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) - .attr("title", function(d) { return d.name; }) - .on("click", click); - - nodeEnter.append("circle") - .attr("r", 1e-6) - .style("fill", function(d) { return d._children ? "#10c1cb" : "#fff"; }); - - nodeEnter.append("text") - .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) - .attr("dy", "0.35em") - .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) - .text(function(d) { return d.name; }) - .style("fill-opacity", 1e-6); - - // Transition nodes to their new position. - var nodeUpdate = node.transition() - .duration(duration) - .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); - - nodeUpdate.select("circle") - .attr("r", 6.5) - .style("fill", function(d) { return d._children ? "#10c1cb" : "#fff"; }); - - nodeUpdate.select("text") - .style("fill-opacity", 1); - - // Transition exiting nodes to the parent's new position. - var nodeExit = node.exit().transition() - .duration(duration) - .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) - .remove(); - - nodeExit.select("circle") - .attr("r", 1e-6); - - nodeExit.select("text") - .style("fill-opacity", 1e-6); - - // Update the links - var link = svg.selectAll("path.link") - .data(links, function(d) { return d.target.id; }); - - // Enter any new links at the parent's previous position. - link.enter().insert("path", "g") - .attr("class", "link") - .attr("d", function(d) { - var o = {x: source.x0, y: source.y0}; - return diagonal({source: o, target: o}); - }); - - // Transition links to their new position. - link.transition() - .duration(duration) - .attr("d", diagonal); - - // Transition exiting nodes to the parent's new position. - link.exit().transition() - .duration(duration) - .attr("d", function(d) { - var o = {x: source.x, y: source.y}; - return diagonal({source: o, target: o}); - }) - .remove(); - - // Stash the old positions for transition. - nodes.forEach(function(d) { - d.x0 = d.x; - d.y0 = d.y; - }); - } + // $.getJSON("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(data){ treeData = data;}) + // .done(function(){plotCollapsibleTree(treeData)}); - // Toggle children on click. - function click(d) { - if (d.children) { - d._children = d.children; - d.children = null; - // console.log("non-leaf 1"); - } - else { - if(d._children){ - d.children = d._children; - d._children = null; - // console.log("non-leaf 2"); - } - else if (d.node_type == "Topic"){ - // console.log("Leaf!"); - var a = document.createElement('a'); - a.setAttribute('href', "/{{group_name_tag}}/topic_details/"+d.id+""); - // a.setAttribute('target', '_blank'); - document.body.appendChild(a); - a.click(); - a.remove(); - // location.href = "/{{group_name_tag}}/topic_details/"+d.id+""; - // $('#collaps_topic_details').foundation('reveal', 'open'); - } - } - update(d); - } - - $("#theme-drag-zoom-container").removeClass("hide"); + // {% endif %} + // } + // }); + + // function plotCollapsibleTree (treeData) { + // $(".themes").html(""); - // calling function plotDragZoomTree defined in theme_drag_zoom_d3tree.html - plotDragZoomTree(treeData); - } + // var margin = {top: 20, right: 40, bottom: 20, left: 40}, + // width = Math.max($(".themes").width(), 960) - margin.right - margin.left, + // height = Math.max($(".themes").height(), 800) - margin.top - margin.bottom; + + // var i = 0, + // duration = 750, + // root; + + // var tree = d3.layout.tree() + // .size([height, width]); + + // var diagonal = d3.svg.diagonal() + // .projection(function(d) { return [d.y, d.x]; }); + + // var svg = d3.select(".themes").append("svg") + // .attr("width", width + margin.right + margin.left) + // .attr("height", height + margin.top + margin.bottom) + // .append("g") + // .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + // {% if node %} + + // root = treeData; + // root.x0 = height / 2; // the point from where it starts it's animation. + // root.y0 = 0; + + // function collapse(d) { + // if (d.children) { + // d._children = d.children; + // d._children.forEach(collapse); + // d.children = null; + // } + // } + + // root.children.forEach(collapse); + // update(root); + // // }); + // {% endif %} + + // // d3.select(self.frameElement).style("height", "800px"); + + // function update(source) { + + // // Compute the new tree layout. + // var nodes = tree.nodes(root).reverse(), + // links = tree.links(nodes); + + // // Normalize for fixed-depth. + // nodes.forEach(function(d) { d.y = d.depth * 150;}); + + // // Update the nodes + // var node = svg.selectAll("g.node") + // .data(nodes, function(d) { return d.id || (d.id = ++i); }); + + // // Enter any new nodes at the parent's previous position. + // var nodeEnter = node.enter().append("g") + // .attr("class", "node") + // .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) + // .attr("title", function(d) { return d.name; }) + // .on("click", click); + + // nodeEnter.append("circle") + // .attr("r", 1e-6) + // .style("fill", function(d) { return d._children ? "#10c1cb" : "#fff"; }); + + // nodeEnter.append("text") + // .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) + // .attr("dy", "0.35em") + // .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) + // .text(function(d) { return d.name; }) + // .style("fill-opacity", 1e-6); + + // // Transition nodes to their new position. + // var nodeUpdate = node.transition() + // .duration(duration) + // .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); + + // nodeUpdate.select("circle") + // .attr("r", 6.5) + // .style("fill", function(d) { return d._children ? "#10c1cb" : "#fff"; }); + + // nodeUpdate.select("text") + // .style("fill-opacity", 1); + + // // Transition exiting nodes to the parent's new position. + // var nodeExit = node.exit().transition() + // .duration(duration) + // .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) + // .remove(); + + // nodeExit.select("circle") + // .attr("r", 1e-6); + + // nodeExit.select("text") + // .style("fill-opacity", 1e-6); + + // // Update the links + // var link = svg.selectAll("path.link") + // .data(links, function(d) { return d.target.id; }); + + // // Enter any new links at the parent's previous position. + // link.enter().insert("path", "g") + // .attr("class", "link") + // .attr("d", function(d) { + // var o = {x: source.x0, y: source.y0}; + // return diagonal({source: o, target: o}); + // }); + + // // Transition links to their new position. + // link.transition() + // .duration(duration) + // .attr("d", diagonal); + + // // Transition exiting nodes to the parent's new position. + // link.exit().transition() + // .duration(duration) + // .attr("d", function(d) { + // var o = {x: source.x, y: source.y}; + // return diagonal({source: o, target: o}); + // }) + // .remove(); + + // // Stash the old positions for transition. + // nodes.forEach(function(d) { + // d.x0 = d.x; + // d.y0 = d.y; + // }); + // } + + // // Toggle children on click. + // function click(d) { + // if (d.children) { + // d._children = d.children; + // d.children = null; + // // console.log("non-leaf 1"); + // } + // else { + // if(d._children){ + // d.children = d._children; + // d._children = null; + // // console.log("non-leaf 2"); + // } + // else if (d.node_type == "Topic"){ + // // console.log("Leaf!"); + // var a = document.createElement('a'); + // a.setAttribute('href', "/{{group_name_tag}}/topic_details/"+d.id+""); + // // a.setAttribute('target', '_blank'); + // document.body.appendChild(a); + // a.click(); + // a.remove(); + // // location.href = "/{{group_name_tag}}/topic_details/"+d.id+""; + // // $('#collaps_topic_details').foundation('reveal', 'open'); + // } + // } + // update(d); + // } + + // $("#theme-drag-zoom-container").removeClass("hide"); + + // // calling function plotDragZoomTree defined in theme_drag_zoom_d3tree.html + // plotDragZoomTree(treeData); + // } // ---END of D3 collapsible tree diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme_drag_zoom_d3tree.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme_drag_zoom_d3tree.html index 847bb78..a130c48 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme_drag_zoom_d3tree.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme_drag_zoom_d3tree.html @@ -1,23 +1,8 @@ -<div id="theme-drag-zoom-container" class="hide"> - - <a href="#" data-reveal-id="theme-drag-zoom-tree">Show graph with zoom and drag functionality</a> - - <div id="theme-drag-zoom-tree" class="reveal-modal xlarge" data-reveal> - <a class="close-reveal-modal">×</a> - </div> - -</div> - <script type="text/javascript"> - - // treeData = "" - // $.getJSON("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(data){ treeData = data;}); - - // d3.json("{% url 'get_tree_hierarchy' group_id node.pk %}?collapsible=true", function(error, treeData) { function plotDragZoomTree(treeData) { - $("#theme-drag-zoom-tree").html(""); + // $("#theme-drag-zoom-tree").html(""); // Calculate total nodes, max label length var totalNodes = 0; @@ -38,7 +23,7 @@ // size of the diagram var viewerHeight = $(window).height() * 0.80; - var viewerWidth = $(document).width() * 0.90; + var viewerWidth = $(document).width() * 0.80; var tree = d3.layout.tree() @@ -277,6 +262,25 @@ d._children = null; } } + + function getHierarchyIds(d) { + hierarchyIdsArr = [d.id]; + + while(d.parent) + { + hierarchyIdsArr.push(d.parent.id); + d = d.parent; + } + // currently treeData doesn't hold top-theme _id, + // so by default it's 1 in that place. Replace 1 with top theme's _id: + hierarchyIdsArr.pop(hierarchyIdsArr.indexOf(1)); + // hierarchyIdsArr.push("{{node.pk}}"); + + hierarchyIdsArr.reverse(); + // console.log(hierarchyIdsArr) + + return hierarchyIdsArr + } var overCircle = function(d) { selectedNode = d; @@ -322,7 +326,7 @@ scale = zoomListener.scale(); x = -source.y0; y = -source.x0; - x = x * scale + viewerWidth / 2; + x = x * scale + viewerWidth / 4; y = y * scale + viewerHeight / 2; d3.select('#theme-drag-zoom-tree g').transition() .duration(duration) @@ -344,13 +348,47 @@ } // Toggle children on click. - - function click(d) { - if (d3.event.defaultPrevented) return; // click suppressed - d = toggleChildren(d); - update(d); - centerNode(d); - } + + // Toggle children on click. + function click(d) { + if (d.children) { + d._children = d.children; + d.children = null; + console.log("non-leaf 1"); + } + else { + if(d._children){ + d.children = d._children; + d._children = null; + console.log("non-leaf 2"); + } + else if (d.node_type == "Topic"){ + console.log("Leaf!"); + + hierarchyIdsArr = getHierarchyIds(d); + + // alert("dddddd"); + // var a = document.createElement('a'); + // a.setAttribute('href', "/{{group_name_tag}}/topic_details/"+d.id+""); + // // a.setAttribute('target', '_blank'); + // document.body.appendChild(a); + // a.click(); + // a.remove(); + location.href = "/{{group_name_tag}}/topic_details/" + d.id + + "?nav_li=" + hierarchyIdsArr.toString() + ""; + // location.href = "/{{group_name_tag}}/topic_details/"+d.id+""; + // $('#collaps_topic_details').foundation('reveal', 'open'); + } + } + update(d); + } + + // function click(d) { + // if (d3.event.defaultPrevented) return; // click suppressed + // d = toggleChildren(d); + // update(d); + // centerNode(d); + // } function update(source) { // Compute the new height, function counts total children of root node and sets tree height accordingly. @@ -397,14 +435,18 @@ .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) + .attr("data-coll-node-id", function(d) {return d.id || (d.id = ++i); }) + .style("cursor", "pointer") .on('click', click); - + nodeEnter.append("circle") .attr('class', 'nodeCircle') .attr("r", 0) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; - }); + }) + .style("stroke-width", "1.5px") + .style("stroke", "steelblue"); nodeEnter.append("text") .attr("x", function(d) { @@ -418,21 +460,23 @@ .text(function(d) { return d.name; }) - .style("fill-opacity", 0); + .style("fill-opacity", 0) + .style("font-family", "sans-serif") + .style("font-size", "10px"); // phantom node to give us mouseover in a radius around it - nodeEnter.append("circle") - .attr('class', 'ghostCircle') - .attr("r", 30) - .attr("opacity", 0.2) // change this to zero to hide the target area - .style("fill", "red") - .attr('pointer-events', 'mouseover') - .on("mouseover", function(node) { - overCircle(node); - }) - .on("mouseout", function(node) { - outCircle(node); - }); + // nodeEnter.append("circle") + // .attr('class', 'ghostCircle') + // .attr("r", 30) + // .attr("opacity", 0.2) // change this to zero to hide the target area + // // .style("fill", "red") + // .attr('pointer-events', 'mouseover') + // .on("mouseover", function(node) { + // overCircle(node); + // }) + // .on("mouseout", function(node) { + // outCircle(node); + // }); // Update the text to reflect whether node has children or not. node.select('text') @@ -496,7 +540,10 @@ source: o, target: o }); - }); + }) + .style("stroke", "#ccc") + .style("stroke-width", "1.5px") + .style("fill", "none"); // Transition links to their new position. link.transition() @@ -530,12 +577,82 @@ // Define the root root = treeData; + aaa = root; root.x0 = viewerHeight / 2; root.y0 = 0; // Layout the tree initially and center on the root node. + // getData(root); root.children.forEach(collapse); update(root); centerNode(root); + + // recursive function needed to get data for {{selected}} node + // result = "" + // function getData (d) { + + // console.log("{{selected}} : " + d.name + " : " + d.id); + // if(d.id == "{{selected}}") + // { + // console.log("======================================================"); + // result = d + // } + + // if(d.children) + // { + // console.log(d.children) + // d.children.forEach(function(i){ + // res = getData(i); + // if (res) + // { + // return res + // } + // }) + // } + // else if(d._children) + // { + // console.log(d._children) + // d._children.forEach(function(i){ + // res = getData(i); + // if (res) + // { + // return res + // } + // }) + // } + // } + // console.log(getData(root)) } +// alert("{{selected}}"); +//called with every property and it's value + + + // selected = document.querySelector('[data-coll-node-id="{{selected}}"]'); + // selectedNodeData = d3.select(selected).data(); + // d = selectedNodeData[0]; + // hierarchyIdsArr = getHierarchyIds(d); + // console.log(hierarchyIdsArr); + + // while(d && d.parent) + // { + // console.log("11") + // click(d) + // d = d.parent; + // } + // function expandHierarchy(d) { + // console.log(d) + + // } + + // expandHierarchy(selectedNodeData[0]); + + function downloadCollapsibleGraph(filename) + { + var blob = new Blob([$("#theme-drag-zoom-tree").html()], {type: "image/svg+xml"}); + filename = filename.replace(/\ /g, '-'); + filename += "-Collapsible-Graph.svg"; + saveAs(blob, filename); + } + + </script> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/urls/batch.py b/gnowsys-ndf/gnowsys_ndf/ndf/urls/batch.py index abb8a27..2d8dc6d 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/urls/batch.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/urls/batch.py @@ -5,6 +5,11 @@ urlpatterns = patterns('gnowsys_ndf.ndf.views.batch', url(r'^/edit/(?P<_id>[\w-]+)$', 'new_create_and_edit', name='edit'), url(r'^/new_batch$', 'new_create_and_edit', name='new_batch'), url(r'^/save_batch_stud$', 'save_students_for_batches', name='save_batch_stud'), + url(r'^/save_batch$', 'save_batch', name='save_batch'), + url(r'^/remove_stud_from_batch$', 'remove_stud_from_batch', name='remove_stud_from_batch'), + url(r'^/batch_detail$', 'batch_detail', name='batch_detail'), url(r'^/detail/(?P<_id>[\w-]+)$', 'detail', name='detail'), url(r'^/delete_batch/(?P<_id>[\w-]+)$', 'delete_batch', name='delete_batch'), + url(r'^/get_possible_batches/$', 'get_possible_batches', name='get_possible_batches'), ) + diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/ajax_views.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/ajax_views.py index df7f25e..6dcbe83 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/ajax_views.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/ajax_views.py @@ -4559,110 +4559,79 @@ def mp_approve_students(student_cur, course_ids, course_enrollment_status_text, p.join() return resultlist +# ==================================================================================================== + @get_execution_time def get_students_for_batches(request, group_id): - """ - This view returns ... - - Arguments: - group_id - ObjectId of the currently selected group - Returns: - A dictionary consisting of following key-value pairs:- - success - Boolean giving the state of ajax call - message - Basestring giving the error/information message - """ - response_dict = {'success': False, 'message': ""} - b_arr=[] - try: - if request.is_ajax() and request.method == "GET": - btn_id = request.GET.get('btn_id', "") - batch_id = request.GET.get('node_id', "") - ac_id = request.GET.get('ac_id', "") - - batch_name_index = 1 - batches_for_same_course = [] - all_batches_in_grp = [] - batch_mem_dict = {} - batch_member_list = [] - - batch_gst = node_collection.one({'_type':"GSystemType", 'name':"Batch"}) - - batch_for_group = node_collection.find({'member_of': batch_gst._id, 'relation_set.has_course': ObjectId(ac_id)}) - - for each1 in batch_for_group: - existing_batch = node_collection.one({'_id': ObjectId(each1._id)}) - batch_name_index += 1 - for each2 in each1.relation_set: - if "has_batch_member" in each2: - batch_member_list.extend(each2['has_batch_member']) - break - each1.get_neighbourhood(each1.member_of) - batch_mem_dict[each1.name] = each1 - - # College's ObjectId is required, if student record can't be found - # using group's ObjectId - # A use-case where records created via csv file appends MIS_admin group's - # ObjectId in group_set field & not college-group's ObjectId - ann_course = node_collection.one({'_id': ObjectId(ac_id)}, {'relation_set.acourse_for_college': 1,"relation_set.course_has_enrollment":1}) - sce_id = None - for rel in ann_course.relation_set: - if rel and "course_has_enrollment" in rel: - sce_id = rel["course_has_enrollment"][0] - break - - sce_node = node_collection.one({"_id":ObjectId(sce_id)},{"attribute_set.has_approved":1}) - - approved_students_list = [] - for attr in sce_node.attribute_set: - if attr and "has_approved" in attr: - approved_students_list = attr["has_approved"] - break - - approve_not_in_batch_studs = [stud_id for stud_id in approved_students_list if stud_id not in batch_member_list] - - student = node_collection.one({'_type': "GSystemType", 'name': "Student"}) - - res = node_collection.find( - { - '_id': {"$in": approve_not_in_batch_studs}, - 'member_of': student._id - # '$or': [ - # {'group_set': ObjectId(group_id)}, - # {'relation_set.student_belongs_to_college': college_id} - # ], - # 'relation_set.selected_course': ObjectId(ac_id) - }, - {'_id': 1, 'name': 1, 'member_of': 1, 'created_by': 1, 'created_at': 1, 'content': 1} - ).sort("name", 1) - - - drawer_template_context = edit_drawer_widget("RelationType", group_id, None, None, None, left_drawer_content=res) - drawer_template_context["widget_for"] = "new_create_batch" - drawer_widget = render_to_string( - 'ndf/drawer_widget.html', - drawer_template_context, - context_instance = RequestContext(request) - ) - - response_dict["success"] = True - response_dict["drawer_widget"] = drawer_widget - response_dict["student_count"] = res.count() - response_dict["batch_name_index"] = batch_name_index - response_dict["batches_for_same_course"] = json.dumps(batch_mem_dict, cls=NodeJSONEncoder) + """ + This view returns ... - return HttpResponse(json.dumps(response_dict)) - else: - error_message = "Batch Drawer: Either not an ajax call or not a GET request!!!" - response_dict["message"] = error_message - return HttpResponse(json.dumps(response_dict)) + Arguments: + group_id - ObjectId of the currently selected group + Returns: + A dictionary consisting of following key-value pairs:- + success - Boolean giving the state of ajax call + message - Basestring giving the error/information message + """ + response_dict = {'success': False, 'message': ""} + result_set = None + query = {} + try: + if request.is_ajax() and request.method == "POST": + ann_course_id = unicode(request.POST.get('ac_id', "")) + added_ids_list = request.POST.getlist('added_ids_list[]', "") + if added_ids_list: + added_ids_list = list(set(added_ids_list)) + search_text = unicode(request.POST.get('search_text', "")) + stud_gst = node_collection.one({'_type': "GSystemType", 'name': "Student"}) + query.update({'member_of': stud_gst._id}) + if added_ids_list: + added_ids_list = [ObjectId(each) for each in added_ids_list] + query.update({'_id': {'$nin': added_ids_list}}) + query.update({'name': {'$regex': search_text, '$options': "i"}}) + query.update({'attribute_set.course_enrollment_status.' + ann_course_id: 'Enrollment Approved'}) + response_dict["success"] = True + rec = node_collection.collection.aggregate([{'$match': query}, + {'$project': {'_id': 0, + 'stud_id': '$_id', + 'enrollment_code': '$attribute_set.enrollment_code', + 'name': '$name', + # 'email_id': '$attribute_set.email_id', + # 'phone': '$attribute_set.mobile_number', + 'year_of_study': '$attribute_set.degree_year', + 'degree': '$attribute_set.degree_specialization', + # 'college': '$relation_set.student_belongs_to_college', + # 'college_roll_num': '$attribute_set.college_enroll_num', + # 'university': '$relation_set.student_belongs_to_university', + }}, + {'$sort': {'enrollment_code': 1}} + ]) + result_set = rec['result'] + # Column headers to be displayed on json_data + column_headers = [ + ('enrollment_code', 'Enr Code'), + ("name", "Name"), + ("degree", "Degree/Stream"), + ("year_of_study", "Year of Study"), + ] + + students_count = len(result_set) + response_dict["students_data_set"] = result_set + response_dict["success"] = True + response_dict["students_count"] = students_count + response_dict["column_headers"] = column_headers + return HttpResponse(json.dumps(response_dict, cls=NodeJSONEncoder)) + else: + error_message = "BatchFetchError: Either not an ajax call or not a GET request!!!" + response_dict["message"] = json_datarror_message + return HttpResponse(json.dumps(response_dict)) - except Exception as e: - error_message = "Batch Drawer: " + str(e) + "!!!" - response_dict["message"] = error_message - return HttpResponse(json.dumps(response_dict)) + except Exception as e: + error_message = "BatchFetchError: " + str(e) + "!!!" + response_dict["message"] = error_message + return HttpResponse(json.dumps(response_dict)) -# ==================================================================================================== @get_execution_time def edit_task_title(request, group_id): @@ -4972,7 +4941,7 @@ def event_assginee(request, group_id, app_set_instance_id=None): performance_record_dict = {} marks_dict = {} student_node = node_collection.find_one({"_id":ObjectId(a['Name'])}) - + for i in student_node.attribute_set: if unicode('student_event_details') in i.keys(): student_dict.update(i['student_event_details']) diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/batch.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/batch.py index 7f2a66a..c90530a 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/batch.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/batch.py @@ -1,6 +1,6 @@ from django.http import HttpResponseRedirect -#from django.http import HttpResponse -from django.shortcuts import render_to_response #render uncomment when to use +from django.http import HttpResponse +from django.shortcuts import render_to_response # render uncomment when to use from django.template import RequestContext from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required @@ -12,10 +12,11 @@ try: except ImportError: # old pymongo from pymongo.objectid import ObjectId -from gnowsys_ndf.settings import GAPPS, MEDIA_ROOT -from gnowsys_ndf.ndf.models import GSystemType, Node +# from gnowsys_ndf.settings import GAPPS, MEDIA_ROOT +# from gnowsys_ndf.ndf.models import GSystemType, Node +from gnowsys_ndf.ndf.models import NodeJSONEncoder from gnowsys_ndf.ndf.models import node_collection, triple_collection -from gnowsys_ndf.ndf.views.methods import create_grelation,get_execution_time +from gnowsys_ndf.ndf.views.methods import create_grelation, get_execution_time, get_group_name_id GST_BATCH = node_collection.one({"_type": "GSystemType", 'name': "Batch"}) app = GST_BATCH @@ -26,59 +27,64 @@ def batch(request, group_id): """ * Renders a list of all 'batches' available within the database. """ - ins_objectid = ObjectId() - st_student = node_collection.one({'_type':'GSystemType','name':'Student'}) - if ins_objectid.is_valid(group_id) is False : - group_ins = node_collection.find_one({'_type': "Group","name": group_id}) - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if group_ins: - group_id = str(group_ins._id) - else : - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if auth : - group_id = str(auth._id) - else : - pass + group_name, group_id = get_group_name_id(group_id) + # ins_objectid = ObjectId() + # st_student = node_collection.one({'_type':'GSystemType','name':'Student'}) + # if ins_objectid.is_valid(group_id) is False : + # group_ins = node_collection.find_one({'_type': "Group","name": group_id}) + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if group_ins: + # group_id = str(group_ins._id) + # else : + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if auth : + # group_id = str(auth._id) + # else : + # pass nussd_course_type_name = "" announced_course_name = "" - print group_id if request.method == "POST": - announced_course_name = request.POST.get("announced_course_name", "") - nussd_course_type_name = request.POST.get("nussd_course_name","") - colg_gst = node_collection.one({'_type': "GSystemType", 'name': 'College'}) - req_colg_id = node_collection.one({'member_of':colg_gst._id,'relation_set.has_group':ObjectId(group_id)}) - batch_coll = node_collection.find({'member_of':GST_BATCH._id,'relation_set.has_course':ObjectId(announced_course_name)}) - # for each_batch in batch_coll: - # each_batch['batch_name_human_readble'] = (each_batch.name).replace('_',' ') + announced_course_name = request.POST.get("announced_course_name", "") + nussd_course_type_name = request.POST.get("nussd_course_name", "") + # colg_gst = node_collection.one({'_type': "GSystemType", 'name': 'College'}) + # req_colg_id = node_collection.one({'member_of': colg_gst._id, 'relation_set.has_group': ObjectId(group_id)}) + batch_coll = node_collection.find({'member_of': GST_BATCH._id, 'relation_set.has_course': ObjectId(announced_course_name)}) + # for each_batch in batch_coll: + # each_batch['batch_name_human_readble'] = (each_batch.name).replace('_',' ') else: - batch_coll = node_collection.find({'member_of': GST_BATCH._id,'relation_set.batch_in_group':ObjectId(group_id)}) + batch_coll = node_collection.find({'member_of': GST_BATCH._id, 'relation_set.batch_in_group':ObjectId(group_id)}) fetch_ATs = ["nussd_course_type"] req_ATs = [] for each in fetch_ATs: - each = node_collection.one({'_type': "AttributeType", 'name': each}, {'_type': 1, '_id': 1, 'data_type': 1, 'complex_data_type': 1, 'name': 1, 'altnames': 1}) - - if each["data_type"] == "IS()": - dt = "IS(" - for v in each.complex_data_type: - dt = dt + "u'" + v + "'" + ", " - dt = dt[:(dt.rfind(", "))] + ")" - each["data_type"] = dt + each = node_collection.one({'_type': "AttributeType", 'name': each}, {'_type': 1, '_id': 1, 'data_type': 1, 'complex_data_type': 1, 'name': 1, 'altnames': 1}) - each["data_type"] = eval(each["data_type"]) - each["value"] = None - req_ATs.append(each) + if each["data_type"] == "IS()": + dt = "IS(" + for v in each.complex_data_type: + dt = dt + "u'" + v + "'" + ", " + dt = dt[:(dt.rfind(", "))] + ")" + each["data_type"] = dt - #users_in_group = node_collection.one({'_id':ObjectId(group_id)}).author_set + each["data_type"] = eval(each["data_type"]) + each["value"] = None + req_ATs.append(each) + # users_in_group = node_collection.one({'_id':ObjectId(group_id)}).author_set template = "ndf/batch.html" - variable = RequestContext(request, {'batch_coll': batch_coll,'appId':app._id,'nussd_course_name_var':nussd_course_type_name,'announced_course_name_var':announced_course_name, 'ATs': req_ATs,'group_id':group_id, 'groupid':group_id,'title':GST_BATCH.name,'st_batch_id':GST_BATCH._id}) + variable = RequestContext(request, {'batch_coll': batch_coll, + 'appId': app._id, + 'nussd_course_name_var': nussd_course_type_name, + 'announced_course_name_var': announced_course_name, + 'ATs': req_ATs, 'group_id': group_id, + 'groupid': group_id, 'title': GST_BATCH.name, + 'st_batch_id': GST_BATCH._id}) return render_to_response(template, variable) @get_execution_time def new_create_and_edit(request, group_id, _id=None): - node = "" - count = "" + # node = "" + # count = "" batch = "" batch_count = 1 ac = None @@ -87,14 +93,14 @@ def new_create_and_edit(request, group_id, _id=None): if request.method == 'POST': batch_count = int(request.POST.get('batch_count', '')) - st_student = node_collection.one({'_type':'GSystemType','name':'Student'}) + st_student = node_collection.one({'_type': 'GSystemType', 'name': 'Student'}) student_coll = node_collection.find( {'member_of': st_student._id, 'group_set': ObjectId(group_id)} ) if _id: batch = node_collection.one( - {'_id':ObjectId(_id)}, + {'_id': ObjectId(_id)}, {'relation_set.has_course': 1, 'name': 1} ) @@ -109,7 +115,8 @@ def new_create_and_edit(request, group_id, _id=None): if ac: for attr in ac.attribute_set: - if attr and attr.has_key("nussd_course_type"): + # if attr and attr.has_key("nussd_course_type"): + if attr and "nussd_course_type" in attr: nussd_course_name = attr["nussd_course_type"] break @@ -121,28 +128,29 @@ def new_create_and_edit(request, group_id, _id=None): if each["data_type"] == "IS()": dt = "IS(" for v in each.complex_data_type: - dt = dt + "u'" + v + "'" + ", " + dt = dt + "u'" + v + "'" + ", " dt = dt[:(dt.rfind(", "))] + ")" each["data_type"] = dt each["data_type"] = eval(each["data_type"]) each["value"] = None req_ATs.append(each) - + variable = RequestContext(request, { - 'group_id': group_id, 'groupid': group_id, + 'group_id': group_id, 'groupid': group_id, 'appId': app._id, 'title': GST_BATCH.name, 'ATs': req_ATs, - 'count':batch_count, 'batch_count': xrange(batch_count), 'st_batch_id': GST_BATCH._id, - 'ac_node': ac, - 'student_count': student_coll.count(), - 'nussd_course_name': nussd_course_name, + 'count': batch_count, 'batch_count': xrange(batch_count), 'st_batch_id': GST_BATCH._id, + 'ac_node': ac, + 'student_count': student_coll.count(), + 'nussd_course_name': nussd_course_name, 'node': batch }) - + template = "ndf/new_create_batch.html" return render_to_response(template, variable) -@get_execution_time + +@get_execution_time def save_students_for_batches(request, group_id): ''' This save method creates new and update existing the batches @@ -150,47 +158,68 @@ def save_students_for_batches(request, group_id): edit_batch = [] if request.method == 'POST': batch_user_list = request.POST.get('batch_user_list_dict', '') + # print "\n\n batch_user_list_dict", batch_user_list batch_user_list = json.loads(batch_user_list) ac_id = request.POST.get('ac_id', '') + # print "\n\n ac_id", ac_id + # raise Exception("batch") + for k, v in batch_user_list.items(): + save_btch(k, v, group_id, request, ac_id) + return HttpResponseRedirect(reverse('batch', kwargs={'group_id': group_id})) - for k,v in batch_user_list.items(): - save_batch(k,v, group_id, request, ac_id) - return HttpResponseRedirect(reverse('batch',kwargs={'group_id':group_id})) @get_execution_time -def save_batch(batch_name, user_list, group_id, request, ac_id): - - rt_has_batch_member = node_collection.one({'_type':'RelationType', 'name':'has_batch_member'}) - all_batches_in_grp=[] - b_node = node_collection.one({'member_of':GST_BATCH._id,'name':unicode(batch_name)}) - if not b_node: - b_node = node_collection.collection.GSystem() - b_node.member_of.append(GST_BATCH._id) - b_node.created_by = int(request.user.id) - b_node.group_set.append(ObjectId(group_id)) - b_node.name = batch_name - b_node.name = batch_name - b_node['altnames'] = batch_name.replace('_',' ') - - b_node.contributors.append(int(request.user.id)) - b_node.modified_by = int(request.user.id) - b_node.save() - all_batches_in_grp.append(b_node._id) - - rt_group_has_batch = node_collection.one({'_type':'RelationType', 'name':'group_has_batch'}) - rt_has_course = node_collection.one({'_type':'RelationType', 'name':'has_course'}) - - relation_coll = triple_collection.find({'_type':'GRelation','relation_type.$id':rt_group_has_batch._id,'subject':ObjectId(group_id)}) - - for each in relation_coll: - all_batches_in_grp.append(each.right_subject) - #to get all batches of the group - - create_grelation(b_node._id,rt_has_batch_member,user_list) +def save_batch(request, group_id): +# def save_batch(batch_name, user_list, group_id, request, ac_id): + + group_name, group_id = get_group_name_id(group_id) + response_dict = {"success": False} + # new_batch_node = None + rt_has_batch_member = node_collection.one({'_type': 'RelationType', 'name': 'has_batch_member'}) + if request.is_ajax() and request.method == "POST": + ac_id = request.POST.get("ac_id", '') + batch_name = request.POST.get("batch_name", '') + batch_id = request.POST.get("batch_id", '') + user_list = request.POST.getlist("user_list[]", '') + # create_new_batch = request.POST.get("create_new_batch", '') + # response_dict["old_batches"] = find_batches_of_ac(ac_id) + user_list = [ObjectId(each) for each in user_list] + all_batches_in_grp = [] + if not batch_id: + # b_node = node_collection.one({'member_of':GST_BATCH._id,'name':unicode(batch_name)}) + b_node = node_collection.collection.GSystem() + b_node.member_of.append(GST_BATCH._id) + b_node.created_by = int(request.user.id) + b_node.group_set.append(ObjectId(group_id)) + b_node.name = batch_name + b_node['altnames'] = batch_name.replace('_', ' ') + + b_node.contributors.append(int(request.user.id)) + b_node.modified_by = int(request.user.id) + b_node.save() + all_batches_in_grp.append(b_node._id) + + rt_group_has_batch = node_collection.one({'_type': 'RelationType', 'name': 'group_has_batch'}) + relation_coll = triple_collection.find({'_type': 'GRelation', 'relation_type.$id': rt_group_has_batch._id,'subject':ObjectId(group_id)}) + + for each in relation_coll: + all_batches_in_grp.append(each.right_subject) + # to get all batches of the group + rt_has_course = node_collection.one({'_type': 'RelationType', 'name': 'has_course'}) + + create_grelation(ObjectId(group_id), rt_group_has_batch, all_batches_in_grp) + create_grelation(b_node._id, rt_has_course, ObjectId(ac_id)) + response_dict['new_batch_created'] = True + response_dict['new_batch_node_name'] = b_node.name + response_dict['new_batch_node_id'] = str(b_node._id) + else: + response_dict['new_batch_created'] = False + b_node = node_collection.one({'_id': ObjectId(batch_id)}) + if user_list: + create_grelation(b_node._id, rt_has_batch_member, user_list) + response_dict['success'] = True + return HttpResponse(json.dumps(response_dict, cls=NodeJSONEncoder)) - create_grelation(b_node._id,rt_has_course,ObjectId(ac_id)) - - create_grelation(ObjectId(group_id),rt_group_has_batch,all_batches_in_grp) @get_execution_time def detail(request, group_id, _id): @@ -198,7 +227,7 @@ def detail(request, group_id, _id): node = node_collection.one({'_id':ObjectId(_id)}) rt_has_batch_member = node_collection.one({'_type':'RelationType','name':'has_batch_member'}) relation_coll = triple_collection.find({'_type':'GRelation','relation_type.$id':rt_has_batch_member._id,'subject':node._id,'status':u'PUBLISHED'}) - + for each in relation_coll: n = node_collection.one({'_id':ObjectId(each.right_subject)}) student_coll.append(n) @@ -207,37 +236,104 @@ def detail(request, group_id, _id): return render_to_response(template, variable) +@get_execution_time +def remove_stud_from_batch(request, group_id): + group_name, group_id = get_group_name_id(group_id) + if request.is_ajax() and request.method == "POST": + batch_id = request.POST.get("batch_id", '') + stud_id = request.POST.get("stud_id", '') + rt_has_batch_member = node_collection.one({'_type':'RelationType','name':'has_batch_member'}) + grelation_node = triple_collection.one({'_type':'GRelation', + 'relation_type.$id':rt_has_batch_member._id, + 'subject':ObjectId(batch_id),'status':u'PUBLISHED', + 'right_subject': ObjectId(stud_id)}) + rel_name = grelation_node.relation_type.name + inv_rel_name = grelation_node.relation_type.inverse_name + subj = grelation_node.subject + right_subj = grelation_node.right_subject + + # Remove right-subject-node's ObjectId from the value + # corresponding to subject-node's "relation-name" key + # referenced in relation_set field + res = node_collection.collection.update({ + '_id': subj, + 'relation_set.' + rel_name: {'$exists': True} + }, { + '$pull': {'relation_set.$.' + rel_name: right_subj} + }, + upsert=False, multi=False + ) + # Remove subject-node's ObjectId from the value corresponding + # to right-subject-node's "inverse-relation-name" key + # referenced in relation_set field + res = node_collection.collection.update({ + '_id': right_subj, + 'relation_set.' + inv_rel_name: {'$exists': True} + }, { + '$pull': {'relation_set.$.' + inv_rel_name: subj} + }, + upsert=False, multi=False + ) + + grelation_node.status = u"DELETED" + grelation_node.save() + status = "success" + return HttpResponse(json.dumps(status, cls=NodeJSONEncoder)) + + +@get_execution_time +def batch_detail(request, group_id): + group_name, group_id = get_group_name_id(group_id) + new_batch_node = None + if request.is_ajax() and request.method == "GET": + batch_id = request.GET.get("batch_id", '') + + student_coll = [] + node = node_collection.one({'_id':ObjectId(batch_id)}) + rt_has_batch_member = node_collection.one({'_type':'RelationType','name':'has_batch_member'}) + relation_coll = triple_collection.find({'_type':'GRelation','relation_type.$id':rt_has_batch_member._id,'subject':node._id,'status':u'PUBLISHED'}) + + for each in relation_coll: + n = node_collection.one({'_id':ObjectId(each.right_subject)}) + student_coll.append(n) + return HttpResponse(json.dumps(student_coll, cls=NodeJSONEncoder)) + + + @login_required @get_execution_time -def delete_batch(request,group_id,_id): - if ObjectId.is_valid(group_id) is False : - group_ins = node_collection.find_one({'_type': "Group","name": group_id}) - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if group_ins: - group_id = str(group_ins._id) - else : - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if auth : - group_id = str(auth._id) - else : - pass - - node = node_collection.one({ '_id': ObjectId(_id)}) - left_relations = triple_collection.find({"_type":"GRelation", "subject":node._id}) - right_relations = triple_collection.find({"_type":"GRelation", "right_subject":node._id}) - attributes = triple_collection.find({"_type":"GAttribute", "subject":node._id}) +def delete_batch(request, group_id, _id): + + group_name, group_id = get_group_name_id(group_id) + + # if ObjectId.is_valid(group_id) is False : + # group_ins = node_collection.find_one({'_type': "Group","name": group_id}) + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if group_ins: + # group_id = str(group_ins._id) + # else : + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if auth : + # group_id = str(auth._id) + # else : + # pass + + node = node_collection.one({'_id': ObjectId(_id)}) + left_relations = triple_collection.find({"_type": "GRelation", "subject": node._id}) + right_relations = triple_collection.find({"_type": "GRelation", "right_subject": node._id}) + attributes = triple_collection.find({"_type": "GAttribute", "subject": node._id}) for eachobject in right_relations: # If given node is used in relationship with any other node (as right_subject) # Then this node's ObjectId must be removed from relation_set field of other node node_collection.collection.update( - {'_id': eachobject.subject, 'relation_set.'+eachobject.relation_type.name: {'$exists': True}}, - {'$pull': {'relation_set.$.'+eachobject.relation_type.name: node._id}}, + {'_id': eachobject.subject, 'relation_set.' + eachobject.relation_type.name: {'$exists': True}}, + {'$pull': {'relation_set.$.' + eachobject.relation_type.name: node._id}}, upsert=False, multi=False ) eachobject.delete() - all_associates = list(left_relations)+list(attributes) + all_associates = list(left_relations) + list(attributes) # Deleting GAttributes and GRelations where given node is used as left subject for eachobject in all_associates: eachobject.delete() @@ -245,3 +341,37 @@ def delete_batch(request,group_id,_id): # Finally deleting given node node.delete() return HttpResponseRedirect(reverse('batch', kwargs={'group_id': group_id})) + + +@login_required +def get_possible_batches(request, group_id): + ''' + Returns: + * Batches of selected course + ''' + group_name, group_id = get_group_name_id(group_id) + response_dict = {"success": False} + new_batch_node = None + if request.is_ajax() and request.method == "POST": + ac_id = request.POST.get("ac_id", '') + create_new_batch = request.POST.get("create_new_batch", '') + response_dict["success"] = True + batch_user_list_dict = [] + list_of_members = [] + if ac_id: + batch_cur = node_collection.find({'member_of': GST_BATCH._id, + 'relation_set.has_course': ObjectId(ac_id)}) + for each_batch in batch_cur: + each_batch_dict = {} + if each_batch.relation_set: + for rel in each_batch.relation_set: + list_of_members = [] + if rel and 'has_batch_member' in rel: + list_of_members.append(rel['has_batch_member']) + list_of_members.append(str(each_batch._id)) + each_batch_dict[each_batch.name] = list_of_members + batch_user_list_dict.append(each_batch_dict) + # batch_user_list_dict.append(str(each_batch._id)) + # print "\n\nBatches----------", batch_user_list_dict + response_dict["old_batches"] = batch_user_list_dict + return HttpResponse(json.dumps(response_dict, cls=NodeJSONEncoder)) diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/enrollment.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/enrollment.py index 87758d7..82e6d2f 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/enrollment.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/enrollment.py @@ -372,7 +372,11 @@ def enrollment_create_edit(request, group_id, app_id, app_set_id=None, app_set_i for each_enrollment_task in enrollment_task_ids: if not updated_one_task: each_enrollment_task_node = node_collection.one({'_id': ObjectId(each_enrollment_task)}) - task_status = each_enrollment_task_node.attribute_set[0]['Status'] + if each_enrollment_task_node.attribute_set: + for each_attr_task in each_enrollment_task_node.attribute_set: + if each_attr_task and 'Status' in each_attr_task: + task_status = each_attr_task['Status'] + # task_status = each_enrollment_task_node.attribute_set[0]['Status'] if task_status in list_of_task_status: task_dict = {} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py index 64a26b3..7143e78 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py @@ -487,7 +487,7 @@ def get_drawers(group_id, nid=None, nlist=[], page_no=1, checked=None, **kwargs) for each in drawer: if each._id not in nlist: dict1[each._id] = each - + for oid in nlist: obj = node_collection.one({'_id': oid}) dict2.append(obj) @@ -502,9 +502,12 @@ def get_drawers(group_id, nid=None, nlist=[], page_no=1, checked=None, **kwargs) if each._id not in nlist: dict1[each._id] = each - for oid in nlist: + + for oid in nlist: obj = node_collection.one({'_id': oid}) dict2.append(obj) + + dict_drawer['1'] = dict1 dict_drawer['2'] = dict2 @@ -813,11 +816,12 @@ def build_collection(node, check_collection, right_drawer_list, checked): if node.prior_node != right_drawer_list: i = 0 node.prior_node=[] + node_prior_node_append_temp=node.prior_node.append #a temp. variable which stores the lookup for append method while (i < len(right_drawer_list)): node_id = ObjectId(right_drawer_list[i]) node_obj = node_collection.one({"_id": node_id}) if node_obj: - node.prior_node.append(node_id) + node_prior_node_append_temp(node_id) i = i+1 # print "\n Changed: prior_node" @@ -838,14 +842,16 @@ def build_collection(node, check_collection, right_drawer_list, checked): i = 0 node.collection_set = [] # checking if each _id in collection_list is valid or not + nlist_append_temp=nlist.append #a temp. variable which stores the lookup for append method + node_collection_set_append_temp=node.collection_set.append #a temp. variable which stores the lookup for append method while (i < len(right_drawer_list)): node_id = ObjectId(right_drawer_list[i]) node_obj = node_collection.one({"_id": node_id}) if node_obj: if node_id not in nlist: - nlist.append(node_id) + nlist_append_temp(node_id) else: - node.collection_set.append(node_id) + node_collection_set_append_temp(node_id) # After adding it to collection_set also make the 'node' as prior node for added collection element node_collection.collection.update({'_id': ObjectId(node_id), 'prior_node': {'$nin':[node._id]} },{'$push': {'prior_node': ObjectId(node._id)}}) @@ -853,7 +859,7 @@ def build_collection(node, check_collection, right_drawer_list, checked): for each in nlist: if each not in node.collection_set: - node.collection_set.append(each) + node_collection_set_append_temp(each) node.status = u"PUBLISHED" node.save() # After adding it to collection_set also make the 'node' as prior node for added collection element @@ -4003,3 +4009,5 @@ def repository(request, group_id): }, context_instance=RequestContext(request) ) + + diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/topics.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/topics.py index 2344f1f..6533647 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/topics.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/topics.py @@ -91,6 +91,7 @@ def themes(request, group_id, app_id=None, app_set_id=None): nodes = "" unfold_tree = request.GET.get('unfold','') selected = request.GET.get('selected','') + tree = request.GET.get('tree','collapsible') unfold = "false" # topics_GST = node_collection.find_one({'_type': 'GSystemType', 'name': 'Topics'}) @@ -130,7 +131,7 @@ def themes(request, group_id, app_id=None, app_set_id=None): return render_to_response("ndf/theme.html", {'theme_GST_id':theme_GST._id, 'themes_cards': themes_cards, - 'group_id': group_id,'groupid': group_id,'node': node,'shelf_list': shelf_list,'shelves': shelves, + 'group_id': group_id,'groupid': group_id,'node': node,'shelf_list': shelf_list,'shelves': shelves, 'tree': tree, 'nodes':nodes_dict,'app_id': app_id,'app_name': appName,"selected": selected, 'title': title,'themes_list_items': themes_list_items, 'themes_hierarchy': themes_hierarchy, 'unfold': unfold, |