diff --git a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..c56f881e002f57622f6c794a36084061d48df894
--- /dev/null
+++ b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
@@ -0,0 +1,97 @@
+import("JditoFilter_lib");
+import("KeywordRegistry_basic");
+import("Keyword_lib");
+import("system.db");
+import("system.vars");
+import("system.result");
+import("Sql_lib");
+import("Attribute_lib");
+
+var condition = new SqlCondition();
+
+var getGroups = vars.exists("$param.GetGroups_param") && vars.get("$param.GetGroups_param");
+var objectType = vars.exists("$param.ObjectType_param") && vars.get("$param.ObjectType_param");
+if (getGroups)
+{
+    //this is for the selection of the superordinate attribute, this condition
+    //filters out the own id and the children to prevent loops
+    condition.andSqlCondition(SqlCondition.begin()
+        .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP)
+        .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$param.AttrParentId_param", "# != ?")
+        .and("AB_ATTRIBUTE.AB_ATTRIBUTEID not in ('" + AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param")).join("','") + "')")
+        .build());
+}
+else if (objectType)  //if there's an objectType, it comes from the AttributeRelation entity
+{
+    var filteredAttributes = [];
+    if (vars.exists("$param.FilteredAttributeIds_param") && vars.get("$param.FilteredAttributeIds_param"))
+        filteredAttributes = JSON.parse(vars.get("$param.FilteredAttributeIds_param"));
+    
+    var ids = AttributeUtil.getPossibleAttributes(objectType, false, filteredAttributes);
+    condition.and("AB_ATTRIBUTE.AB_ATTRIBUTEID in ('" + ids.join("','") + "')");
+} 
+else 
+{
+    var type = vars.exists("$param.AttrParentType_param") && vars.get("$param.AttrParentType_param");
+    if (type == $AttributeTypes.COMBO)
+        condition = SqlCondition.begin()
+            .andPrepareVars("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", "$param.AttrParentId_param")
+            .build();
+    else if (type)
+    {
+    var parentId = vars.exists("$param.AttrParentId_param") && vars.get("$param.AttrParentId_param");
+    if (parentId)
+        condition.and("AB_ATTRIBUTE.AB_ATTRIBUTEID in ('" + AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param")).join("','") + "')");
+    }
+}
+
+var sql = "select AB_ATTRIBUTEID, AB_ATTRIBUTEID, ATTRIBUTE_ACTIVE, " 
+    + "ATTRIBUTE_NAME, ATTRIBUTE_PARENT_ID, ATTRIBUTE_TYPE, " 
+    + KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.attributeType(), "ATTRIBUTE_TYPE")
+    + ", KEYWORD_CONTAINER from AB_ATTRIBUTE";
+
+if (vars.exists("$local.idvalues") && vars.get("$local.idvalues"))
+    condition.and(" AB_ATTRIBUTEID in ('" + vars.get("$local.idvalues").join("','") + "')");
+else if (vars.exists("$local.filter") && vars.get("$local.filter"))
+{
+    var filter = vars.get("$local.filter");
+    condition.andSqlCondition((JditoFilterUtils.getSqlCondition(filter, "AB_ATTRIBUTE")));
+}
+
+var attributes = db.table(condition.buildSql(sql, "1=1"));
+
+if (!(vars.exists("$local.idvalues") && vars.get("$local.idvalues")))
+    attributes = _sortArrayForTree(attributes);
+
+result.object(attributes);
+
+//sorts the records in a way that a tree can be built
+function _sortArrayForTree (pArray) 
+{
+    var rows = {};
+    var allIds = {};
+    var idIndex = 1;
+    var parentIdIndex = 4;
+    
+    pArray.forEach(function (row) {allIds[row[idIndex]] = true;});
+    
+    var index = 0;
+    
+    for (let itemsAdded = true; itemsAdded; itemsAdded = oldIndex != index)
+    {
+        var oldIndex = index;
+        pArray.forEach(function (row)
+        {
+            if (!(row[idIndex] in this) && (row[parentIdIndex] in this || !allIds[row[parentIdIndex]]))
+                this[row[idIndex]] = {
+                    data : row,
+                    index : index++
+                };
+        }, rows);
+    }
+    var sortedArray = new Array(Object.keys(rows).length);
+    for (let i in rows)
+        sortedArray[rows[i].index] = rows[i].data;
+    
+    return sortedArray;
+}
\ No newline at end of file
diff --git a/entity/Attribute_entity/recordcontainers/jdito/onDelete.js b/entity/Attribute_entity/recordcontainers/jdito/onDelete.js
new file mode 100644
index 0000000000000000000000000000000000000000..61929ba31c941a074a9666920632025c03fb614c
--- /dev/null
+++ b/entity/Attribute_entity/recordcontainers/jdito/onDelete.js
@@ -0,0 +1,35 @@
+import("Sql_lib");
+import("system.db");
+import("system.vars");
+import("Attribute_lib");
+
+var condition = SqlCondition.begin()
+    .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$field.UID")
+    .build("1=2");
+
+db.deleteData("AB_ATTRIBUTE", conditon);
+
+var attributeId = vars.get("$field.UID");
+
+var childIds = AttributeUtil.getAllChildren(attributeId).concat(attributeId);
+
+var condition = SqlCondition.begin()
+    .and("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID in ('" + childIds.join("','") + "')")
+    .build();
+
+//delete all entries in AB_ATTRIBUTEUSAGE belonging to the attribute to avoid unrelated entries
+db.deleteData("AB_ATTRIBUTEUSAGE", condition);
+
+condition = SqlCondition.begin()
+    .and("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID in ('" + childIds.join("','") + "')")
+    .build();
+
+//delete all entries in AB_ATTRIBUTERELATION for the attributes
+db.deleteData("AB_ATTRIBUTERELATION", condition);
+
+condition = SqlCondition.begin()
+    .and("AB_ATTRIBUTE.AB_ATTRIBUTEID in ('" + childIds.join("','") + "')")
+    .build();
+
+//delete all attribute children
+db.deleteData("AB_ATTRIBUTE", condition);
diff --git a/entity/Attribute_entity/recordcontainers/jdito/onInsert.js b/entity/Attribute_entity/recordcontainers/jdito/onInsert.js
new file mode 100644
index 0000000000000000000000000000000000000000..87565632d7cf592ac1bfe137d87ca62be849a32c
--- /dev/null
+++ b/entity/Attribute_entity/recordcontainers/jdito/onInsert.js
@@ -0,0 +1,23 @@
+import("system.db");
+import("system.vars");
+
+var columns = [
+    "AB_ATTRIBUTEID",
+    "ATTRIBUTE_ACTIVE",
+    "ATTRIBUTE_LEVEL",
+    "ATTRIBUTE_NAME",
+    "ATTRIBUTE_PARENT_ID",
+    "ATTRIBUTE_TYPE",
+    "KEYWORD_CONTAINER"
+];
+var values = [
+    vars.get("$field.UID"),
+    vars.get("$field.ATTRIBUTE_ACTIVE"),
+    vars.get("$field.ATTRIBUTE_LEVEL"),
+    vars.get("$field.ATTRIBUTE_NAME"),
+    vars.get("$field.ATTRIBUTE_PARENT_ID"),
+    vars.get("$field.ATTRIBUTE_TYPE"),
+    vars.get("$field.KEYWORD_CONTAINER")
+];
+
+db.insertData("AB_ATTRIBUTE", columns, null, values);
\ No newline at end of file
diff --git a/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js b/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js
new file mode 100644
index 0000000000000000000000000000000000000000..6740df0d149b19858958fbc5b0c9839a721bd4e1
--- /dev/null
+++ b/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js
@@ -0,0 +1,26 @@
+import("Sql_lib");
+import("system.db");
+import("system.vars");
+
+var columns = [
+    "ATTRIBUTE_ACTIVE",
+    "ATTRIBUTE_LEVEL",
+    "ATTRIBUTE_NAME",
+    "ATTRIBUTE_PARENT_ID",
+    "ATTRIBUTE_TYPE",
+    "KEYWORD_CONTAINER"
+];
+var values = [
+    vars.get("$field.ATTRIBUTE_ACTIVE"),
+    vars.get("$field.ATTRIBUTE_LEVEL"),
+    vars.get("$field.ATTRIBUTE_NAME"),
+    vars.get("$field.ATTRIBUTE_PARENT_ID"),
+    vars.get("$field.ATTRIBUTE_TYPE"),
+    vars.get("$field.KEYWORD_CONTAINER")
+];
+
+var condition = SqlCondition.begin()
+    .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$field.UID")
+    .build("1=2");
+
+db.updateData("AB_ATTRIBUTE", columns, null, values, conditon);
\ No newline at end of file