gd-sprest-bs
Version:
SharePoint JavaScript, TypeScript and Web Components designed using the Bootstrap framework.
255 lines (254 loc) • 10.7 kB
JavaScript
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;
};