En este tutorial vamos a ver los pasos que se deben seguir para crear un organigrama.
Para este ejemplo utilizaremos 3 aplicaciones, la primera, un espacio en blanco que mostrará el organigrama, un segundo en blanco que se ejecutará vía Ajax para realizar las actualizaciones en la base de datos, y finalmente, una aplicación de formulario que se mostrará en modal para editar los datos de un empleado.
Creando el formulario
1.1 – Cree una nueva aplicación de formulario basada en la tabla “employees“.
1.2 – Acceda a la opción SQL y agregue una cláusula WHERE a la aplicación: employee_id = [empkey].
1.3 – Como vamos a llamar a esta aplicación para que se abra en una ventana modal, usaremos un dispositivo para cerrarla automáticamente después de cambiar los datos, y recargar la aplicación anterior. Para ello accedemos al menú “Programación >> Métodos Javascript >> Nuevo Método”, donde crearemos una función Javascript denominada “upd_parent”, con el código:
1.4 – Acceda ahora al menú “Formulario >> Eventos >> onAfterUpdate” y llame a la función Javascript que creamos, y repita el procedimiento para el evento onAfterDelete.
sc_ajax_javascript(‘upd_parent’);
1.5 – Acceda al evento onApplicationInit para incluir un código de validación para la variable empkey.
if( isset($_GET[“empkey”]) ){ [empkey] = $_GET[“empkey”]; }
1.6 – Generar el código fuente de la aplicación.
Creando la aplicación Ajax
Ahora crearemos una aplicación secundaria más, que será complementaria a nuestra aplicación principal. Esta será una aplicación solo para ejecutar comandos de inserción, actualización y eliminación a través de Ajax.
2.1 – Crear una nueva aplicación tipo Blank
2.2 – En el evento OnExecute agregamos el siguiente código:
// UPDATE NODES if( $_POST['ajaxtp'] == 'save' ){ $var_sql_upd = "UPDATE example_gojs SET "; if( $_POST['item_mode'] == "updtext" ){ $var_sql_upd .= " employee_name = '".$_POST['item_value']."' "; } elseif( $_POST['item_mode'] == "updparent" ){ $var_sql_upd .= " employee_boss = ".$_POST['item_value']; } $var_sql_upd .= " WHERE employee_id = ". $_POST['item_id']; echo $var_sql_upd; sc_exec_sql( $var_sql_upd ); } //INSERT A NODE elseif( $_POST['ajaxtp'] == 'insert' ){ $today = date("Y-m-d"); if( $_POST['empboss'] == 0 ) { $sql_insert = "INSERT INTO example_gojs(employee_name, employee_title, employee_photo) VALUES ('(new person)', '(title)', 'grp__NM__img__NM__me.png')"; }else{ $sql_insert = "INSERT INTO example_gojs(employee_name, employee_title, employee_boss, employee_photo) VALUES ('(new person)', '(title)', ".$_POST['empboss'].", 'grp__NM__img__NM__me.png')"; } sc_exec_sql($sql_insert); sc_lookup(rs,"SELECT employee_id FROM example_gojs ORDER BY employee_id DESC LIMIT 1"); $result = {rs[0][0]}; echo $result; } //DELETE A NODE elseif( $_POST['ajaxtp'] == 'delete' ){ $sql_delete = "DELETE FROM example_gojs WHERE employee_id = ".$_POST['empkey']; sc_exec_sql($sql_delete); }
2.3 – Generar el código fuente de la aplicación.
Creación del organigrama
Finalmente crearemos nuestra aplicación principal donde construiremos y mostraremos el organigrama.
3.1 – Crear una nueva aplicación tipo Blank
function chkChildren($empkey){
$chk_sql = "SELECT COUNT(*) FROM example_gojs WHERE employee_boss=".$empkey;
sc_lookup(rs, $chk_sql);
return {rs[0][0]};
}
function getChildren($empid, $str_ret, $level){
if($empid==0){
$check_sql = "SELECT employee_id, employee_name, employee_title, employee_boss, employee_photo FROM example_gojs WHERE employee_boss IS NULL OR employee_boss = 0";
}else{
$check_sql = "SELECT employee_id, employee_name, employee_title, employee_boss, employee_photo FROM example_gojs WHERE employee_boss=".$empid;
}
sc_lookup(result, $check_sql);
$counter = count({result});
for($i=0;$i<$counter;$i++){
if ( substr({result[$i][4]}, 0, 7) == 'grp__NM'){
$urlimg = "../_lib/img/".{result[$i][4]}; // Just for the purpose of example. Gets the project directory path
}else{
$urlimg = "../../../file/img/" .{result[$i][4]}; // Image upload. It gets from the images directory path
}
if( $level>4 ) { $level = 4; }
$str_ret .= " { 'key': '".{result[$i][0]}."', 'title': '".{result[$i][1]}."', 'content': '".{result[$i][2]}."', 'picture': '".$urlimg."', 'className': 'level-".$level."' ";
$haschildren = chkChildren({result[$i][0]});
if($haschildren > 0 ){
$str_ret .= ", 'children': [";
$level++;
$str_ret = getChildren({result[$i][0]}, $str_ret, $level);
$level--;
$str_ret = substr($str_ret, 0, -1);
$str_ret .= "]";
}
$str_ret .= "},";
}
return $str_ret;
}
$var_nodes_array = 'var datasource = ';
$nodes = '';
$nodes = getChildren(0,$nodes,1);
$var_nodes_array .= substr($nodes, 0, -1);
$var_nodes_array .= ';';
//echo $var_nodes_array;
?>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Organogram</title>
sc_include_lib("Jquery");
sc_include_lib("jquery_thickbox");
sc_include_lib("orgchart");
<style> html, body{ background-color: #F9FAFC; } </style>
</head>
<body>
<div id="organogram"> </div>
<script type="text/javascript">
$(function() {
var getId = function() {
return (new Date().getTime()) * 1000 + Math.floor(Math.random() * 1001);
};
var nodeSelected = null;
<?php echo $var_nodes_array; ?>
var nodeTemplate = function(data) {
return '<div class="node-picture"><img width="50px" src="' + (data.picture ? data.picture : 'http://placehold.it/48/?text=%') + '"></div><div class="node-content"><div class="node-title">' + data.title + '</div>' + data.content + '</div>';
};
var template = [];
var oc = $('#organogram').orgchart({
'data' : datasource,
'nodeTemplate': nodeTemplate,
'draggable': true,
'createNode': function(nodeSelected, data) {
nodeSelected[0].id = data.key; //getId();
},
'dropCriteria': function($draggedNode, $dragZone, $dropZone) {
return true;
}
});
oc.$chart.on('nodedrop.orgchart', function(event, nodeSelected) {
var droppednode = nodeSelected.draggedNode[0].id;
var parentnode = nodeSelected.dropZone.parent().closest('table').find('.node')[0].id;
console.log('draggedNode:' + droppednode + ', Parent:' + parentnode
//+ ', dragZone:' + event.dragZone.children('.title').text()
//+ ', dropZone:' + event.dropZone.children('.title').text()
);
save(droppednode, 'updparent', parentnode);
});
$('.node').append('<div class="node-menu"><em></em><em></em><em></em><ul><li class="edit-item"><a href="#"><?php echo {lang_context_menu_edit}; ?></a></li><li class="divider"></li><li class="add-children"><a href="#"><?php echo {lang_context_menu_add_child}; ?></a></li><li class="add-sibling"><a href="#"><?php echo {lang_context_menu_add_sibling}; ?></a></li><li class="divider"></li><li class="del-item"><a href="#"><?php echo {lang_context_menu_rem}; ?></a></li></ul></div>');
$('.node-menu').click(function(){
$(this).toggleClass('active');
nodeSelected = $(this).parent();
});
$('.add-children a').click(function(e){
e.preventDefault();
var hasChild = nodeSelected.parent().attr('colspan') > 0 ? true : false;
var nodeVals = [];
var template = [{'title': ' ', 'content': ' ', 'className': 'level-2', 'relationship': rel, 'id': getId()}]
if (!hasChild) {
var rel = nodeVals.length > 1 ? '110' : '100';
oc.addChildren(nodeSelected, template);
} else {
oc.addSiblings(nodeSelected.closest('tr').siblings('.nodes').find('.node:first'), template);
}
insertNode(nodeSelected[0].id);
})
$('.add-sibling a').click(function(e){
e.preventDefault();
var template = [{'title': ' ', 'content': ' ', 'className': 'level-2', 'id': getId()}]
oc.addSiblings(nodeSelected, template);
insertNode(nodeSelected.parent().closest('table').parent().closest('table').find('.node')[0].id);
})
$('.edit-item a').click(function(e){
var strAppEdit = 'org_chart_form';
tb_show('', '../'+ strAppEdit +'/?empkey='+nodeSelected[0].id+'&KeepThis=true&TB_iframe=true&height=600&width=600', null);
})
$('.del-item a').click(function(e){
e.preventDefault();
oc.removeNodes(nodeSelected);
deleteNode(nodeSelected[0].id);
})
function insertNode(node_id) {
$.post( "../org_chart_ajax/index.php",
{ ajaxtp: "insert", empboss: node_id })
.done(function(response,status){
return response;
});
window.location.reload();
}
function save(v_id, v_mode, v_value) {
var val = v_value;
if ( v_mode == "updstep") { val = v_value.substring(5); }
$.post( "../org_chart_ajax/index.php",
{ ajaxtp: "save", item_id: v_id, item_mode: v_mode, item_value: val },
function(response, status){
return response;
}
);
}
function deleteNode(node_id) {
$.post( "../org_chart_ajax/index.php",
{ ajaxtp: "delete", empkey: nodeSelected[0].id },
function(response, status){
return response;
}
);
}
});
</script>
</body>
</html>
<?php
Obs1: Perceba que no código estamos incluindo bibliotecas nativas do Scriptcase. Especificamente para a construção do Organograma, precisamos da biblioteca “orgchart”.
sc_include_lib("Jquery");
sc_include_lib("jquery_thickbox");
sc_include_lib("orgchart");
Obs2: observe también las llamadas al formulario y las aplicaciones Ajax.
3.3 – Finalmente ejecutamos la aplicación
Comment this post