interface IOrganizationNode { id: string; code: string; name: string; localName: string; localNameLocale: string; parentCode: string; description: string; children?: IOrganizationNode[]; } interface IOrganizationTree { organizationTree: IOrganizationNode[]; } interface IOrganization { id: string; code: string; name: string; localName: string; localNameLocale: string; parentCode: string; description: string; } export class OrganizationTree { public static GenerateOrganizationsDom: string = "GenerateOrganizationsDom" + _gcEditingInput; public static createTreeDom(array: IOrganization[]): HTMLElement { let DOMObject: HTMLElement = document.createElement("div"); DOMObject.className = "select-user-tree-container"; let organizationTree: IOrganizationTree = OrganizationTree.CreateTreeData(array); DOMObject.appendChild(OrganizationTree.CreateTreeDom(organizationTree.organizationTree, true)); this._bindEvent(DOMObject); return DOMObject; } private static CreateTreeData(array: IOrganization[]): IOrganizationTree { let r: IOrganizationNode[] = []; let codeToOrganizationMap: Dictionary<IOrganization> = {}; let len = array.length; let orgs: IOrganization[] = []; //deep copy for (let i = 0; i < len; i++) { let org: any = {}; for (var attr in array[i]) { org[attr] = array[i][attr]; } orgs.push(org); } for (let i = 0; i < len; i++) { codeToOrganizationMap[orgs[i].code] = orgs[i]; } for (let j = 0; j < len; j++) { let org: IOrganizationNode = orgs[j]; let parentOrg: IOrganizationNode = codeToOrganizationMap[org.parentCode];
if (parentOrg) {
if (parentOrg.children) {
parentOrg.children.push(org);
} else {
parentOrg.children = [];
parentOrg.children.push(org);
}
} else {
r.push(org);
}
} let result: any = {}; result.organizationTree = r; return result; } private static CreateTreeDom(treeNodes: IOrganizationNode[], top?: boolean): HTMLElement { let ul = document.createElement("ul") as HTMLUListElement; if (top) { ul.classList.add("tree"); ul.classList.add("tree-root"); //ul.classList.add("tree", "tree-root");//chrome unsupport } else { ul.classList.add("tree"); } for (let i = 0; i < treeNodes.length; i++) { let li = document.createElement("li") as HTMLLIElement; li.classList.add("tree-node"); let a = document.createElement("a") as HTMLAnchorElement; a.classList.add("tree-node-label"); let spanName = document.createElement("span") as HTMLSpanElement; spanName.classList.add("tree-node-name"); spanName.innerText = treeNodes[i].name; spanName["GCSK_OrganizationCode"] = treeNodes[i].code; let spanArrow = document.createElement("span") as HTMLSpanElement; spanArrow.classList.add("tree-node-arrow"); a.appendChild(spanName); a.appendChild(spanArrow); li.appendChild(a); if (treeNodes[i].children) { li.classList.add("tree-node-haschildren"); li.appendChild(OrganizationTree.CreateTreeDom(treeNodes[i].children)); } ul.appendChild(li); } return ul; } private static _bindEvent(DOMObject: HTMLElement) { let self = this; GC$(DOMObject).bind("click", (event) => { let srcElement = <HTMLElement>(event.srcElement || event.target); if (srcElement.classList.contains("tree-node-name")) { let liElement = srcElement.parentElement.parentElement; // first remove all <li> classname Array.prototype.forEach.call(DOMObject.querySelectorAll(".tree-node"), item => { item.classList.remove("tree-node-selected"); }); //then add current <li> if (liElement.classList.contains("tree-node-haschildren")) { liElement.classList.add("tree-node-opened"); } liElement.classList.add("tree-node-selected"); var evt = document.createEvent("UIEvent") as UIEvent; evt.initEvent(OrganizationTree.GenerateOrganizationsDom, true, false); evt["GCSK_OrganizationCode"] = srcElement["GCSK_OrganizationCode"]; liElement.dispatchEvent(evt); } else if (srcElement.classList.contains("tree-node-arrow")) { let liElement = srcElement.parentElement.parentElement; if (srcElement.parentElement.parentElement.classList.contains("tree-node-opened")) { liElement.classList.remove("tree-node-opened"); } else { liElement.classList.add("tree-node-opened"); } } }); } }