UNPKG

@indexea/sdk

Version:

Indexea JavaScript SDK (indexea.com)

234 lines (218 loc) 6.38 kB
/** * widget layout manager * example: <layout> <row> <col width='6'> <control type='input'/> </col> <col width='6'> <control type='hotwords'/> </col> </row> <row> <col width='9'> <control type='results'/> </col> <col width='3'> <control type='aggregation'/> <control type='aggregation'/> </col> </row> <row> <col width='9'> <control type='pagination'/> </col> </row> </layout> */ export class WidgetLayout { private xml: Document; private constructor(xml: Document) { this.xml = xml } /** * parse layout xml string * @param xmlstring * @returns */ static parse(xmlstring: string): WidgetLayout { const parser = new DOMParser() const xml = parser.parseFromString(xmlstring, 'text/xml') return new WidgetLayout(xml); } /** * turn to layout xml string * @returns */ toString(): string { var oSerializer = new XMLSerializer() var sXML = oSerializer.serializeToString(this.xml) return sXML } /** * check if exists a control named `ctrl_name` * @param ctrl_name * @returns */ control(ctrl_name: string): any { return this.xml.querySelector(`control[type='${ctrl_name}']`); } /** * get all rows in layout * @returns */ rows(): any { return this.xml.getElementsByTagName("row"); } /** * append node to position * @param node * @param row * @param col * @returns */ append(node: any, row = 0, col = 0): WidgetLayout { if (this.control(node.type) != null) return this; //get position of row and col let theNode: any; let rowNodes = this.xml.getElementsByTagName('row') if (row >= 0 && row < rowNodes.length) { var rowNode = rowNodes[row] var colNodes = rowNode.getElementsByTagName('col') if (col >= 0 && col < colNodes.length) { theNode = colNodes[col] } } var elem = this.xml.createElement('control') elem.setAttribute('type', node.type) if (theNode) { //拖入设计器的某个元素之上 var cols = theNode.parentNode?.getElementsByTagName('col') var lastWidth = parseInt(cols[cols.length - 1].getAttribute('width')) var totalWidth = 0 for (var i = 0; i < cols.length; i++) { totalWidth += parseInt(cols[i].getAttribute('width')) } if (totalWidth + node.width > 12) { if (node.width == lastWidth) cols[cols.length - 1].appendChild(elem) else this.appendToNewRow(theNode, elem, node.width) } else { this.appendToNewCol(theNode, elem, node.width) } } else { //拖入设计器的空白处 this.appendToNewRow(theNode, elem, node.width) } return this } /** * remove node from position * @param row * @param col * @param index * @returns */ remove(row: number, col: number, index: number): WidgetLayout { let rowNodes = this.xml.getElementsByTagName('row') if (row < rowNodes.length) { var rowNode = rowNodes[row] var colNodes = rowNode.getElementsByTagName('col') if (col < colNodes.length) { colNodes[col].removeChild(colNodes[col].childNodes[index]) //如果该列已经没有子节点了,则删除该列 if (!colNodes[col].hasChildNodes()) { rowNode.removeChild(colNodes[col]) } //如果该行已经没有子节点了,则删除该行 if (!rowNode.hasChildNodes()) { rowNode.parentNode?.removeChild(rowNode) } } } return this; } /** * get control attribute with name `attr_name` * @param ctrl_name * @param attr_name * @returns */ getAttribute(ctrl_name: string, attr_name: string): any { var ctl = this.xml.querySelector(`control[type='${ctrl_name}']`); return ctl ? ctl.getAttribute(attr_name) : null; } /** * get attributes of control * @param ctrl_name */ getAttributes(ctrl_name: string = ""): any { let attrs = ctrl_name ? this.xml.querySelector(`control[type='${ctrl_name}']`)?.attributes : this.xml.querySelector('layout')?.attributes var props: {[key: string]:any} = {} if (attrs) for (var i = 0; i < attrs.length; i++) { var att = attrs.item(i) if (att) { if (att.value === 'true') props[att.name] = true else if (att.value === 'false') props[att.name] = false else if (att.value) props[att.name] = att.value } } return props } /** * set control attributes * @param {row}} ctrl_name * @param {attrs} attrs */ setAttributes(ctrl_name: string, attrs: any) { let ctrl = this.xml.querySelector(`control[type='${ctrl_name}']`); if (ctrl) { for (let key in attrs) { ctrl.setAttribute(key, attrs[key]); } } } /** * set control attributes * @param {row}} row * @param {col} col * @param {index} index * @param {attrs} attrs */ setAttributesByPos(row: number, col: number, index: number, attrs: any) { let rowNodes = this.xml.getElementsByTagName('row') if (row < rowNodes.length) { var rowNode = rowNodes[row] var colNodes = rowNode.getElementsByTagName('col') if (col < colNodes.length) { if (index < colNodes[col].childNodes.length) { var controls = colNodes[col].getElementsByTagName('control') if (index < controls.length) { var control = controls[index] for (var key in attrs) { control.setAttribute(key, attrs[key]) } } } } } } private appendToNewRow(node: any, elem: any, width: number) { var row = this.xml.createElement('row') var col = this.xml.createElement('col') col.setAttribute('width', width + "") col.appendChild(elem) row.appendChild(col) this.xml.getElementsByTagName('layout')[0].appendChild(row) } private appendToNewCol(node: any, elem: any, width: number) { var col = this.xml.createElement('col') col.setAttribute('width', width + "") col.appendChild(elem) node.parentNode.appendChild(col) } }