I am trying to create a function that converts data stored hierarchically into an array in the following format: id , name , idType , members , idParent to text , children .
The content of the array:
[
{"id":"1", "idType": "1", "name": "FCB", "Members": [{"name": "Lionel"},{"name": "Pique"}], "idParent": ""},
{"id":"2", "idType": "2", "name": "Football", "Members": [{"name": "Pique"}], "idParent": "1"},
{"id":"3", "idType": "2", "name": "Basketball", "Members": [{"name": "Pique"}], "idParent": "1"},
{"id":"4", "idType": "3", "name": "UEFA 14", "Members": [{"name": "Test"}], "idParent": "2"},
{"id":"5", "idType": "3", "name": "UEFA 15", "Members": [{"name": "Carlos"}], "idParent": "2"},
{"id":"6", "idType": "3", "name": "NBA 15", "Members": [], "idParent": "3"}
]
What I need is to create two groups inside the children key :
- Check if the parent has members and if so create an object {text: "Member": children: The members of the parent will go here}
- Group the children of the parent into an object with a name based on the idType key.
The tree should be like this:
var array_expected =
[{ "text" : "FCB", "children": [
{ "text" : "Members", "children":[{"text":"Lionel"}, {"text":"Pique"}]},
{"text" : "Sports", "children": [
{"text": "Football", "children": [{"text":"Members", "children":[{"text": "Pique"}]},{"text":"Categories", "children":[{"text": "UEFA 14", "children": [{"text": "Teams", "children": [{"text": "Team 1", "children": [{"text": "Members","children": [{"text": "Puyol"}, {"text": "Iniesta"}]}]}, {"text": "Team 2"}]}]}, {"text": "UEFA 15", "children":[{"text":"Members", "children": [{"text": "Xavi"}]}]}]}]},
{"text": "Basketball", "children":[{"text":"Members", "children":[{"text": "Pique"}]},{"text":"Categories", "children":[{"text": "NBA 14"}, {"text": "NBA 15"}]}]}]},
] }
]
$(function() {
$("#expected_jstree").jstree({
'core' : {
'themes': {
'responsive': true
},
'data' : array_expected
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.9/themes/default/style.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.9/jstree.min.js"></script>
<div id="expected_jstree"></div>
I've tried doing this function, but I can't group the children by the idTypo in an object and the members don't appear in the elements that don't have children. For example UEFA 15 has members but they do not appear.
var array = [
{"id":"1", "idType": "1", "name": "FCB", "Members": [{"name": "Lionel"},{"name": "Pique"}], "idParent": ""},
{"id":"2", "idType": "2", "name": "Football", "Members": [{"name": "Pique"}], "idParent": "1"},
{"id":"3", "idType": "2", "name": "Basketball", "Members": [{"name": "Pique"}], "idParent": "1"},
{"id":"4", "idType": "3", "name": "UEFA 14", "Members": [{"name": "Test"}], "idParent": "2"},
{"id":"5", "idType": "3", "name": "UEFA 15", "Members": [{"name": "Carlos"}], "idParent": "2"},
{"id":"6", "idType": "3", "name": "NBA 15", "Members": [], "idParent": "3"},
{"id":"7", "idType": "4", "name": "Team 1", "Members": [{"name": "Lionel"},{"name": "Pique"}], "idParent": "4"},
{"id":"8", "idType": "4", "name": "Team 2", "Members": [{"name": "Lionel"}], "idParent": "4"},
]
function create_jstree(array){
var parent = [], children = {};
for (var i = 0, len = array.length; i < len; ++i) {
var item = array[i],
idParent = item.idParent,
target = !idParent ? parent : (children[idParent] || (children[idParent] = []));
target.push({ text: item.name, id: item.id, idParent: item.idParent, Members: item.Members, idType: item.idType});
}
var find_child = function(parent) {
if(children[parent.id]) {
if(parent.Members.length >= 1){
var members = [];
for(var i = 0; i < parent.Members.length; i++){
members.push({text: parent.Members[i].name})
}
children[parent.id].splice(0, 0, {text: "Members", children: members});
}
parent.children = children[parent.id];
for (var i = 0, len = parent.children.length; i < len; ++i) {
find_child(parent.children[i]);
}
}
};
for (var y = 0, leng = parent.length; y < leng; ++y) {
find_child(parent[y]);
}
return parent;
}
$(function() {
$("#jstree_try").jstree({
'core' : {
'themes': {
'responsive': true
},
'data' : create_jstree(array)
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.9/themes/default/style.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.9/jstree.min.js"></script>
<div id="jstree_try"></div>
The properties
children
andparent
are incompatible. If you usechildren
, don't useparent
, and if you use ,parent
don't usechildren
.The tree
parent
needs at least these 3 properties:I make a reconstruction of the tree. He
parent
depends onid
:I rebuild the array
parent
as follows:The tree
children
needs at least these 2 properties:I manually rebuild the array with
children
:Converting from
parent
tochildren
:The following function loops through each element and for each element loops back through the array to find the parent element and then inserts it as a child.
Lastly remove the property
id
and the propertyparent
... This way onlytext
and remainschildren
.The property
children
is an array of objects. If a parent doesn't have such a property, it adds it and builds the list of children.The array it returns will only contain the elements that its
parent
is"#"
, that is, the first level ones.Example of converting from
parent
tochildren
(see in Full Page ):Converting from
children
toparent
:The following function first copies the
array
intosalida
, so as not to modify the original array.Then it goes through the array
salida
adding the parametersid
andparent
.As it goes through it, it moves the child of the current element to the end of the array, that is,
children
it adds it to the end and then assigns the child asnull
.This serves to unpack the array, flattening it out little by little. By adding the element to the end, this will make it part of the array traversal, and when there are no more children left, it will stop traversing the array, leaving all the elements at the first level.
I show the process of how it works in a simplified way:
First step:
for
) First element.Second step:
for
) Second (child of first element)Third step:
for
) Third (son of Second)Example of converting from
children
toparent
(see in Full Page ):Converting the original array
For this array, it is necessary that
Members
, is taken as the child of the current element, and then the elements of the array ofMember
will be children ofMember
.We take as an example the element that has
id
value 7 . Originally it is like the following:It is then
Members
passed as a son, that is, itsidParent
will be theid
, which is 7 . The property is added to itchildren
, which will then be removed.Es momento de quitar
valores
, pasando todos sus elementos al final del array, que en este caso son dos. Estos elementos serán hijos deMembers
, es decir, suidParent
es el mismo que elid
deMembers
.Siguiendo esta lógica, se puede programar la función que convierte el formato original del array al formato de jsTree.
Aquí además cambio los parámetros
idParent
porparent
yname
portext
, y alid
lo calculo mediante elid
del último elemento del array.Esta función también genera las secciones a partir del
idType
. Si la sección no existe, la crea, y si existe la busca por el nombre y además coincidiendo con elparent
.idType
es 2, genera la sección Sports.idType
es 3, genera la sección Categories.idType
es 4, genera la sección Teams.La función
generar_id
sirve para asignar unid
que no exista dentro del array. Lo que hace es obtener todos losid
del array, luego obtiene el máximo de esa lista numérica y le suma 1.Nota: Ahora
Members
aparecerá abajo porque siempre se ordena por abecedario.Código sobre el array original (ver en Página completa):