Index: controlies/www/users/form.html
===================================================================
--- controlies/www/users/form.html	(revision 61)
+++ controlies/www/users/form.html	(revision 62)
@@ -75,6 +75,8 @@
 	<p><span id="nameTag">Nombre y Apellidos</span><br><input type="text" id="name" name="name" onChange="searchUsername();"/></p>
 	<p><span id="surnameTag">Primer Apellido</span><br><input type="text" id="surname" name="surname"/></p>	
 	<p><span id="nifTag">NIF</span><br><input type="text" id="nif" name="nif"/></p>
+	<p><span id="departmentsTag">Departamentos</span><br><select type="text" id="departments" name="departments" style="width:250px;"></select>
+	<p><span id="classroomsTag">Clases</span><br><select type="text" id="classrooms" name="classrooms" style="width:250px;"></select>	
 	<p><span id="userTag">Usuario</span><br><input type="text" id="user" name="user"/></p>
 	<p><span id="passwordTag">Contraseña</span><br><input type="text" id="password" name="password"/></p>
 	<p><span id="password2Tag">Repita Contraseña</span><br><input type="text" id="password2" name="password2"/></p>
Index: controlies/www/users/index.html
===================================================================
--- controlies/www/users/index.html	(revision 61)
+++ controlies/www/users/index.html	(revision 62)
@@ -109,6 +109,20 @@
 
 				$("#dialog-form").html("");
 				$("#dialog-form").load("users/form.html", function() {
+					
+					$.post('groups','action=getAllGroups', function(data) {
+						var groups = $.parseJSON(data);					
+						
+						$.each( groups.departments, function(i, l){
+							$("#form_data #departments").append("<option value='"+l+"'>"+l+"</option>");
+						 });
+						$.each( groups.classrooms, function(i, l){
+							$("#form_data #classrooms").append("<option value='"+l+"'>"+l+"</option>");
+						 });						 
+						$("#form_data #departments").multiselect(); 
+						$("#form_data #classrooms").multiselect(); 						 
+					});
+					
 					$("#form_data #action").val("modify");
 					$("#form_data #user").attr("readonly","true");
 					$("#form_data #user").css("background-color","#DDD");
@@ -116,11 +130,21 @@
 					
 					$.post('users', 'action=getUserData&user='+uid, function(data) {
 						var result = $.parseJSON(data);
-						$("#form_data #type").val(result.response['type']).attr("disabled","true");
+
+						if(result.response['type']=="teacher")
+							var textType = "Profesor";
+						else
+							var textType = "Alumno";
+
+						$("#form_data #type").replaceWith(textType+"<input type='hidden' id='type' name='type' value='"+result.response['type']+"'/>");
 						$("#form_data #name").val(result.response['name']);
-						$("#form_data #nif").val(result.response['nif']);
+						$("#form_data #nif").val(result.response['nif']);		
 						$("#form_data #user").val(result.response['user']);
 						$("#form_data #surname").val(result.response['surname']);
+						
+						$.each(result.response['groups']['departments'], function(i, l){
+							$("#form_data #departments option:contains('"+l+"')").attr("selected","selected");  
+						});
 					});				  
 				});
 
@@ -130,6 +154,7 @@
 				$("#dialog-form").dialog({
 					resizable: false,
 					modal: true,
+					width: 400,
 					title: "Modificar Usuario"
 				}).dialog('option', 'position', [x, y]);
 			}
Index: controlies/www/main.html
===================================================================
--- controlies/www/main.html	(revision 61)
+++ controlies/www/main.html	(revision 62)
@@ -14,6 +14,11 @@
 	<script language="javascript" src="js/jquery/jquery-ui-1.8.9.custom.min.js"></script>
 	<script language="javascript" src="js/jquery/jquery.dropdown.js"></script>
 
+	<!-- Libreria Multiselect -->
+	<link rel="stylesheet" type="text/css" href="js/multiselect/jquery.multiselect.css" />
+	<script language="javascript" src="js/multiselect/jquery.multiselect.min.js"></script>
+	<script language="javascript" src="js/multiselect/jquery.multiselect.es.js"></script>
+	
 	<!-- Libreria JGrid -->
 	<link rel="stylesheet" type="text/css" media="screen" href="js/jquery/jdgrid/css/ui.jqgrid.css" />
 	<script src="js/jquery/jdgrid/grid.locale-sp.js" type="text/javascript"></script>
Index: controlies/www/js/multiselect/jquery.multiselect.min.js
===================================================================
--- controlies/www/js/multiselect/jquery.multiselect.min.js	(nonexistent)
+++ controlies/www/js/multiselect/jquery.multiselect.min.js	(revision 62)
@@ -0,0 +1,20 @@
+/*
+ * jQuery MultiSelect UI Widget 1.9
+ * Copyright (c) 2011 Eric Hynds
+ *
+ * http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
+ *
+ * Depends:
+ *   - jQuery 1.4.2+
+ *   - jQuery UI 1.8 widget factory
+ *
+ * Optional:
+ *   - jQuery UI effects
+ *   - jQuery UI position utility
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+*/
+(function(d){var o=0;d.widget("ech.multiselect",{options:{header:true,height:175,minWidth:225,classes:"",checkAllText:"Check all",uncheckAllText:"Uncheck all",noneSelectedText:"Select options",selectedText:"# selected",selectedList:0,show:"",hide:"",autoOpen:false,multiple:true,position:{}},_create:function(){var a=this.element.hide(),b=this.options;this.speed=d.fx.speeds._default;this._isOpen=false;a=(this.button=d('<button type="button"><span class="ui-icon ui-icon-triangle-2-n-s"></span></button>')).addClass("ui-multiselect ui-widget ui-state-default ui-corner-all").addClass(b.classes).attr({title:a.attr("title"), "aria-haspopup":true}).insertAfter(a);(this.buttonlabel=d("<span />")).html(b.noneSelectedText).appendTo(a);a=(this.menu=d("<div />")).addClass("ui-multiselect-menu ui-widget ui-widget-content ui-corner-all").addClass(b.classes).insertAfter(a);var e=(this.header=d("<div />")).addClass("ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix").appendTo(a);(this.headerLinkContainer=d("<ul />")).addClass("ui-helper-reset").html(function(){return b.header===true?'<li><a class="ui-multiselect-all" href="#"><span class="ui-icon ui-icon-check"></span><span>'+ b.checkAllText+'</span></a></li><li><a class="ui-multiselect-none" href="#"><span class="ui-icon ui-icon-closethick"></span><span>'+b.uncheckAllText+"</span></a></li>":typeof b.header==="string"?"<li>"+b.header+"</li>":""}).append('<li class="ui-multiselect-close"><a href="#" class="ui-multiselect-close"><span class="ui-icon ui-icon-circle-close"></span></a></li>').appendTo(e);(this.checkboxContainer=d("<ul />")).addClass("ui-multiselect-checkboxes ui-helper-reset").appendTo(a);this._bindEvents(); this.refresh(true);b.multiple||a.addClass("ui-multiselect-single")},_init:function(){this.options.header===false&&this.header.hide();this.options.multiple||this.headerLinkContainer.find(".ui-multiselect-all, .ui-multiselect-none").hide();this.options.autoOpen&&this.open();this.element.is(":disabled")&&this.disable()},refresh:function(a){var b=this.options,e=this.menu,c=this.button,g=this.checkboxContainer,f=[],h=this.element.attr("id")||o++;g.empty();this.element.find("option").each(function(k){var i= d(this),m=i.html(),n=this.value;k=this.id||"ui-multiselect-"+h+"-option-"+k;var j=i.parent();i=i.is(":disabled");var l=["ui-corner-all"];if(j.is("optgroup")){j=j.attr("label");if(d.inArray(j,f)===-1){d('<li><a href="#">'+j+"</a></li>").addClass("ui-multiselect-optgroup-label").appendTo(g);f.push(j)}}if(n.length>0){i&&l.push("ui-state-disabled");j=d("<li />").addClass(i?"ui-multiselect-disabled":"").appendTo(g);l=d("<label />").attr("for",k).addClass(l.join(" ")).appendTo(j);d('<input type="'+(b.multiple? "checkbox":"radio")+'" '+(this.selected?'checked="checked"':"")+' name="multiselect_'+h+'" />').attr({id:k,checked:this.selected,title:m,disabled:i,"aria-disabled":i,"aria-selected":this.selected}).val(n).appendTo(l).after("<span>"+m+"</span>")}});this.labels=e.find("label");this._setButtonWidth();this._setMenuWidth();c[0].defaultValue=this.update();a||this._trigger("refresh")},update:function(){var a=this.options,b=this.labels.find("input"),e=b.filter(":checked"),c=e.length;a=c===0?a.noneSelectedText: d.isFunction(a.selectedText)?a.selectedText.call(this,c,b.length,e.get()):/\d/.test(a.selectedList)&&a.selectedList>0&&c<=a.selectedList?e.map(function(){return this.title}).get().join(", "):a.selectedText.replace("#",c).replace("#",b.length);this.buttonlabel.html(a);return a},_bindEvents:function(){function a(){b[b._isOpen?"close":"open"]();return false}var b=this,e=this.button;e.find("span").bind("click.multiselect",a);e.bind({click:a,keypress:function(c){switch(c.which){case 27:case 38:case 37:b.close(); break;case 39:case 40:b.open()}},mouseenter:function(){e.hasClass("ui-state-disabled")||d(this).addClass("ui-state-hover")},mouseleave:function(){d(this).removeClass("ui-state-hover")},focus:function(){e.hasClass("ui-state-disabled")||d(this).addClass("ui-state-focus")},blur:function(){d(this).removeClass("ui-state-focus")}});this.header.delegate("a","click.multiselect",function(c){d(this).hasClass("ui-multiselect-close")?b.close():b[d(this).hasClass("ui-multiselect-all")?"checkAll":"uncheckAll"](); c.preventDefault()});this.menu.delegate("li.ui-multiselect-optgroup-label a","click.multiselect",function(c){c.preventDefault();var g=d(this),f=g.parent().nextUntil("li.ui-multiselect-optgroup-label").find("input:visible:not(:disabled)");b._trigger("optgrouptoggle",c,{inputs:f.get(),label:g.parent().text(),checked:f[0].checked})!==false&&b._toggleChecked(f.filter(":checked").length!==f.length,f)}).delegate("label","mouseenter.multiselect",function(){if(!d(this).hasClass("ui-state-disabled")){b.labels.removeClass("ui-state-hover"); d(this).addClass("ui-state-hover").find("input").focus()}}).delegate("label","keydown.multiselect",function(c){switch(c.which){case 9:case 27:b.close();break;case 38:case 40:case 37:case 39:b._traverse(c.which,this);c.preventDefault();break;case 13:c.preventDefault();d(this).find("input")[0].click()}}).delegate('input[type="checkbox"], input[type="radio"]',"click.multiselect",function(c){var g=d(this),f=this.value,h=this.checked,k=b.element.find("option");if(g.is(":disabled")||b._trigger("click", c,{value:f,text:this.title,checked:h})===false)c.preventDefault();else{g.attr("aria-selected",h);k.filter(function(){return this.value===f}).attr("selected",h?"selected":"");if(!b.options.multiple){k.not(function(){return this.value===f}).removeAttr("selected");b.labels.removeClass("ui-state-active");g.closest("label").toggleClass("ui-state-active",h);b.close()}setTimeout(d.proxy(b.update,b),10)}});d(document).bind("mousedown.multiselect",function(c){b._isOpen&&!d.contains(b.menu[0],c.target)&&c.target!== b.button[0]&&b.close()});d(this.element[0].form).bind("reset.multiselect",function(){setTimeout(function(){b.update()},10)})},_setButtonWidth:function(){var a=this.element.outerWidth(),b=this.options;if(/\d/.test(b.minWidth)&&a<b.minWidth)a=b.minWidth;this.button.width(a)},_setMenuWidth:function(){var a=this.menu,b=this.button.outerWidth()-parseInt(a.css("padding-left"),10)-parseInt(a.css("padding-right"),10)-parseInt(a.css("border-right-width"),10)-parseInt(a.css("border-left-width"),10);a.width(b|| this.button.outerWidth())},_traverse:function(a,b){var e=d(b),c=a===38||a===37;e=e.parent()[c?"prevAll":"nextAll"]("li:not(.ui-multiselect-disabled, .ui-multiselect-optgroup-label)")[c?"last":"first"]();if(e.length)e.find("label").trigger("mouseover");else{e=this.menu.find("ul:last");this.menu.find("label")[c?"last":"first"]().trigger("mouseover");e.scrollTop(c?e.height():0)}},_toggleChecked:function(a,b){var e=b&&b.length?b:this.labels.find("input");e.not(":disabled").attr({checked:a,"aria-selected":a}); this.update();var c=e.map(function(){return this.value}).get();this.element.find("option").filter(function(){return!this.disabled&&d.inArray(this.value,c)>-1}).attr({selected:a,"aria-selected":a})},_toggleDisabled:function(a){this.button.attr({disabled:a,"aria-disabled":a})[a?"addClass":"removeClass"]("ui-state-disabled");this.menu.find("input").attr({disabled:a,"aria-disabled":a}).parent()[a?"addClass":"removeClass"]("ui-state-disabled");this.element.attr({disabled:a,"aria-disabled":a})},open:function(){var a= this.button,b=this.menu,e=this.speed,c=this.options;if(!(this._trigger("beforeopen")===false||a.hasClass("ui-state-disabled")||this._isOpen)){var g=b.find("ul:last"),f=c.show,h=a.position();if(d.isArray(c.show)){f=c.show[0];e=c.show[1]||this.speed}g.scrollTop(0).height(c.height);if(d.ui.position&&!d.isEmptyObject(c.position)){c.position.of=c.position.of||a;b.show().position(c.position).hide().show(f,e)}else b.css({top:h.top+a.outerHeight(),left:h.left}).show(f,e);this.labels.eq(0).trigger("mouseover").trigger("mouseenter").find("input").trigger("focus"); a.addClass("ui-state-active");this._isOpen=true;this._trigger("open")}},close:function(){if(this._trigger("beforeclose")!==false){var a=this.options,b=a.hide,e=this.speed;if(d.isArray(a.hide)){b=a.hide[0];e=a.hide[1]||this.speed}this.menu.hide(b,e);this.button.removeClass("ui-state-active").trigger("blur").trigger("mouseleave");this._trigger("close");this._isOpen=false}},enable:function(){this._toggleDisabled(false)},disable:function(){this._toggleDisabled(true)},checkAll:function(){this._toggleChecked(true); this._trigger("checkAll")},uncheckAll:function(){this._toggleChecked(false);this._trigger("uncheckAll")},getChecked:function(){return this.menu.find("input").filter(":checked")},destroy:function(){d.Widget.prototype.destroy.call(this);this.button.remove();this.menu.remove();this.element.show();return this},isOpen:function(){return this._isOpen},widget:function(){return this.menu},_setOption:function(a,b){var e=this.menu;switch(a){case "header":e.find("div.ui-multiselect-header")[b?"show":"hide"](); break;case "checkAllText":e.find("a.ui-multiselect-all span").eq(-1).text(b);break;case "uncheckAllText":e.find("a.ui-multiselect-none span").eq(-1).text(b);break;case "height":e.find("ul:last").height(parseInt(b,10));break;case "minWidth":this.options[a]=parseInt(b,10);this._setButtonWidth();this._setMenuWidth();break;case "selectedText":case "selectedList":case "noneSelectedText":this.options[a]=b;this.update();break;case "classes":e.add(this.button).removeClass(this.options.classes).addClass(b)}d.Widget.prototype._setOption.apply(this, arguments)}})})(jQuery);
\ No newline at end of file
Index: controlies/www/js/multiselect/jquery.multiselect.es.js
===================================================================
--- controlies/www/js/multiselect/jquery.multiselect.es.js	(nonexistent)
+++ controlies/www/js/multiselect/jquery.multiselect.es.js	(revision 62)
@@ -0,0 +1,9 @@
+﻿/* Spanish initialisation for the jQuery UI multiselect plugin. */
+/* Written by Vinius Fontoura Correa(vinusfc@gmail.com). */
+
+$.extend($.ech.multiselect.prototype.options, {
+	checkAllText: 'Todas',
+	uncheckAllText: 'Ninguna',
+	noneSelectedText: 'Seleccione las opciones',
+	selectedText: '# seleccionado'
+});
Index: controlies/www/js/multiselect/jquery.multiselect.css
===================================================================
--- controlies/www/js/multiselect/jquery.multiselect.css	(nonexistent)
+++ controlies/www/js/multiselect/jquery.multiselect.css	(revision 62)
@@ -0,0 +1,23 @@
+.ui-multiselect { padding:2px 0 2px 4px; text-align:left }
+.ui-multiselect span.ui-icon { float:right }
+.ui-multiselect-single input { position:absolute !important; top: auto !important; left:-9999px; }
+.ui-multiselect-single label { padding:5px !important }
+
+.ui-multiselect-header { margin-bottom:3px; padding:3px 0 3px 4px }
+.ui-multiselect-header ul { font-size:0.9em }
+.ui-multiselect-header ul li { float:left; padding:0 10px 0 0 }
+.ui-multiselect-header a { text-decoration:none }
+.ui-multiselect-header a:hover { text-decoration:underline }
+.ui-multiselect-header span.ui-icon { float:left }
+.ui-multiselect-header li.ui-multiselect-close { float:right; text-align:right; padding-right:0 }
+
+.ui-multiselect-menu { display:none; padding:3px; position:absolute; z-index:10000 }
+.ui-multiselect-checkboxes { position:relative /* fixes bug in IE6/7 */; overflow-y:scroll }
+.ui-multiselect-checkboxes label { cursor:default; display:block; border:1px solid transparent; padding:3px 1px }
+.ui-multiselect-checkboxes label input { position:relative; top:1px }
+.ui-multiselect-checkboxes li { clear:both; font-size:0.9em; padding-right:3px }
+.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label { text-align:center; font-weight:bold; border-bottom:1px solid }
+.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label a { display:block; padding:3px; margin:1px 0; text-decoration:none }
+
+/* remove label borders in IE6 because IE6 does not support transparency */
+* html .ui-multiselect-checkboxes label { border:none }
Index: controlies/MainLoop.py
===================================================================
--- controlies/MainLoop.py	(revision 61)
+++ controlies/MainLoop.py	(revision 62)
@@ -43,7 +43,7 @@
         connection = l.connect()
 			
         pagename=request.path[1:].lower()
-        print pagename
+
         if  pagename=='':
             request.path='/index.html'
             pagename='index.html'
@@ -138,6 +138,10 @@
 				g = Groups(l,"","")
 				response = g.list(request.args)
 				return json.dumps(response)
+        	elif request.args['action'][0] == "getAllGroups":
+				g = Groups(l,"","")
+				response = g.getAllGroups()
+				return json.dumps(response)				
         	else:
 				g = Groups(l,request.args['name'][0],request.args['gid'][0])
 				response = g.process(request.args['action'][0])
Index: controlies/Server.py
===================================================================
--- controlies/Server.py	(revision 61)
+++ controlies/Server.py	(revision 62)
@@ -34,7 +34,7 @@
 
 # Start up the web service.     
 Root = MainLoop.ControlIESProtocol() #Resource object
-Root.PageDir='/home/manu/proyectos/adminies/www/'
+Root.PageDir='/home/manu/proyectos/controlies/www/'
 site = server.Site(Root)
 
 #my_server = static.File('/home/chisco/workspace/adminies/www/')
Index: controlies/Plugins/Groups.py
===================================================================
--- controlies/Plugins/Groups.py	(revision 61)
+++ controlies/Plugins/Groups.py	(revision 62)
@@ -133,6 +133,20 @@
 
 		return { "page":page, "total":totalPages, "records":len(search), "rows":result[start:finish] }
 
+    def getAllGroups(self):
+		result = self.ldap.search("ou=Group","(|(groupType=school_department)(groupType=school_class))",["cn","groupType"])
+		
+		departments = []
+		classrooms = []		
+		for g in result:
+			if g[0][1]["groupType"][0] == "school_department":
+				departments.append(g[0][1]["cn"][0])
+			elif g[0][1]["groupType"][0] == "school_class":
+				classrooms.append(g[0][1]["cn"][0])
+		
+		departments.sort()
+		classrooms.sort()
+		return { "departments":departments, "classrooms":classrooms }
 
     def buildFilter(self, args):
 		filter = "(&(cn=*)(|(groupType=school_class)(groupType=school_department))"
Index: controlies/Plugins/Users.py
===================================================================
--- controlies/Plugins/Users.py	(revision 61)
+++ controlies/Plugins/Users.py	(revision 62)
@@ -315,9 +315,23 @@
 				
 		return searching
 
-
+    def getUserGroups(self):
+		result = self.ldap.search("ou=Group","(&(memberUid="+self.user+")(|(groupType=school_department)(groupType=school_class)))",["cn","groupType"])
+		
+		departments = []
+		classrooms = []		
+		for g in result:
+			if g[0][1]["groupType"][0] == "school_department":
+				departments.append(g[0][1]["cn"][0])
+			elif g[0][1]["groupType"][0] == "school_class":
+				classrooms.append(g[0][1]["cn"][0])
+		
+		departments.sort()
+		classrooms.sort()
+		return { "departments":departments, "classrooms":classrooms }
+		
     def getUserData(self):
-
+		self.getUserGroups()
 		result = self.ldap.search("ou=People","uid="+self.user,["uid","cn","sn","employeenumber","homedirectory"])
 		
 		type = "student"
@@ -329,7 +343,8 @@
 			"name":result[0][0][1]["cn"][0],
 			"surname":result[0][0][1]["sn"][0],
 			"nif":result[0][0][1]["employeeNumber"][0],
-			"type":type
+			"type":type,
+			"groups":self.getUserGroups()
 		 }
 		 
 		return dataUser
