UNPKG

gd-sprest-bs

Version:

SharePoint JavaScript, TypeScript and Web Components designed using the Bootstrap framework.

255 lines (254 loc) • 10.7 kB
import { Components } from "gd-bs"; import { WebPart } from "../base"; /** * Web Part Tab Types */ export var WPTabTypes; (function (WPTabTypes) { WPTabTypes[WPTabTypes["Pillars"] = 1] = "Pillars"; WPTabTypes[WPTabTypes["Tabs"] = 2] = "Tabs"; })(WPTabTypes || (WPTabTypes = {})); /** * Web Part Tabs */ export const WPTabs = (props) => { let _elWebPart = null; let _isContentZone = false; let _nav = null; // Method to get the webparts let getWebParts = (wpInfo) => { let wps = []; // Get the webpart element and zone let elWebPart = document.querySelector("div[webpartid='" + wpInfo.cfg.WebPartId + "']"); let elWebPartZone = elWebPart ? getWebPartZone(elWebPart) : null; if (elWebPart && elWebPartZone) { // Add a class name to the webpart zone elWebPartZone.className += " wp-tabs"; // Remove the empty elements removeEmptyElements(elWebPartZone); // Parse the webparts in this zone let webparts = elWebPartZone.querySelectorAll(".ms-webpartzone-cell[id^='MSOZoneCell_WebPart']"); for (let i = 0; i < webparts.length; i++) { let webpart = webparts[i]; // See if it's this webpart if (webpart.querySelector("div[webpartid='" + wpInfo.cfg.WebPartId + "']")) { // Save a reference _elWebPart = webpart; // Set the class _elWebPart.className += " wp-tab"; // Skip this webpart continue; } // Skip hidden webparts let wpTitle = (webpart.querySelector(".ms-webpart-titleText") || {}).innerText || ""; let isHidden = webpart.firstElementChild && webpart.firstElementChild.classList.contains("ms-hide"); isHidden = isHidden || /^\(Hidden\)/.test(wpTitle); if (isHidden) { continue; } // See if this is within a content zone if (_isContentZone) { // Get the parent webpart box while (webpart.parentNode) { // See if this is the webpart box element if (webpart.classList.contains("ms-rte-wpbox")) { // Find the div containing the webpart id let wpElement = webpart.querySelector("div[webpartid*='-']"); if (wpElement) { // Set the webpart id attribute webpart.setAttribute("wpid", wpElement.getAttribute("webpartid")); } // Add this webpart and break from the loop wps.push(webpart); break; } // Check the parent element webpart = webpart.parentNode; } } else { // Add the webpart wps.push(webpart); } } } // Return the webparts return wps; }; // Method to get the webpart zone let getWebPartZone = (el) => { // Ensure the element exists if (el && el.classList) { // See if this is the webpart zone element if (el.classList.contains("ms-webpart-zone")) { // Return it return el; } // See if this is the inner page zone if (el.classList.contains("ms-rte-layoutszone-inner") || el.classList.contains("ms-rtestate-field")) { // Set the flag _isContentZone = true; // Return it return el; } // Check the parent element return getWebPartZone(el.parentNode); } // Return nothing return null; }; // Method to remove empty paragraph or new lines for webparts w/in content zones let removeEmptyElements = (elWebPartZone) => { let elChildren = []; // See if this webpart is within a layout zone or rich html field if (elWebPartZone.className.indexOf("ms-rte-layoutszone-inner") >= 0 || elWebPartZone.className.indexOf("ms-rtestate-field") >= 0) { // Set the children elements elChildren = elWebPartZone.children; } // Parse the children elements for (let i = 0; i < elChildren.length; i++) { let elChild = elWebPartZone.children[i]; // See if the last element is a new line let elBreakLine = elChild.children[elChild.children.length - 1]; if (elBreakLine && elBreakLine.nodeName == "BR") { // Remove the element elChild.removeChild(elBreakLine); } // See if this is an empty paragraph tag if (elChild.nodeName == "P") { let removeElement = false; let content = elChild.innerHTML.trim(); // See if this is an empty element if (content.length == 0) { // Set the flag removeElement = true; } // Else, see if this is a line break else if (content.length == 1 && content.charCodeAt(0) == 8203) { // Set the flag removeElement = true; } // Remove the element removeElement ? elWebPartZone.removeChild(elChild) : null; } } }; // Method to update the visibility of the webparts let updateWebParts = (tab, ev) => { let selectedTabId = 0; // See if the tab exists if (tab) { // Parse the webparts for (let i = 0; i < _webparts.length; i++) { // Get the webpart let wpTitle = _webparts[i].querySelector(".ms-webpart-titleText"); if (wpTitle && wpTitle.innerText == tab.title) { // Update the selected tab id selectedTabId = i; break; } } } // Else, default the selected tab to the first visible webpart else { // Parse the webparts for (selectedTabId = 0; selectedTabId < _webparts.length; selectedTabId++) { // Break if this webpart has a title if (_webparts[selectedTabId].querySelector(".ms-webpart-titleText")) { break; } } } // Parse the webparts for (let i = 0; i < _webparts.length; i++) { let wp = _webparts[i]; // Determine the query selector let selector = wp.id ? "#" + wp.id : ".ms-rte-wpbox[wpid='" + wp.getAttribute("wpid") + "']"; // Get the webpart let webpart = document.querySelector(selector); if (webpart) { // See if we are displaying this webpart if (i == selectedTabId) { // Display the webpart webpart.className = webpart.className.replace(" is-hidden", ""); // See if this tab contains a calendar webpart if (webpart.querySelector(".ms-acal-rootdiv")) { let ev = null; // Create the resize event try { ev = new Event("resize"); } // This will fail for IE catch (e) { // Create the event ev = document.createEvent("Event"); ev.initEvent("resize", true, false); } finally { // Call the window resize event to fix the events ev ? window.dispatchEvent(ev) : null; } } // Call the click if it exists props.onClick ? props.onClick(webpart) : null; } // Ensure the webpart is hidden else if (webpart.classList.contains("is-hidden") == false) { // Hide the webpart webpart.classList.add("is-hidden"); } } } }; /** * Main */ let _webparts = []; // Return the webpart let wp = WebPart({ className: props.className, cfgElementId: props.cfgElementId, editForm: props.editForm, elementId: props.elementId, helpProps: props.helpProps, onPostRender: props.onPostRender, onRenderEdit: props.onRenderEdit, wpClassName: ["wp-tabs-main", props.wpClassName || ""].join(' ').trim(), onRenderDisplay: (wpInfo) => { // Set the webparts _webparts = getWebParts(wpInfo); // Parse the webparts let items = []; for (let i = 0; i < _webparts.length; i++) { // Ensure a title exists let wpTitle = _webparts[i].querySelector(".ms-webpart-titleText"); if (wpTitle) { // Add the tab items.push({ isActive: i == 0, title: wpTitle.innerText, onClick: updateWebParts }); } } // Render the navigation _nav = Components.Nav({ className: props.className, el: wpInfo.el, isPills: props.type == WPTabTypes.Pillars, isTabs: true, items }); // Update the webparts updateWebParts(); // See if a custom event exists props.onRenderDisplay ? props.onRenderDisplay(wpInfo) : null; } }); // Add the custom methods wp.getNav = () => { return _nav; }; wp.getTabs = () => { return _webparts; }; // Return the webpart return wp; };