UNPKG

gd-sprest-bs

Version:

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

296 lines (249 loc) • 9.82 kB
import { Components } from "gd-bs"; import { Types } from "gd-sprest"; import { x as CloseIcon } from "../../icons/svgs/x"; import { IWPListField, IWPListFieldsCfg, IWPListFieldsEditForm, IWPListFieldsInfo } from "./types"; /** * List Fields WebPart Edit Form */ export const WPListFieldsEditForm = (props: IWPListFieldsEditForm = {}): IWPListFieldsEditForm => { let _ddlFields: Components.IDropdown = null; let _ddlSelectedFields: Components.IDropdown = null; let _selectedFields: Array<Components.IDropdownItem> = null; let _tbFilter: Components.IInputGroup = null; let _wpInfo: IWPListFieldsInfo = null; // Adds a selected field let addField = (field: Components.IDropdownItem) => { // Add the selected field _selectedFields.push({ text: field.text, value: field.value, onRender: (el => { // Set the styling el.classList.add("d-flex"); el.classList.add("justify-content-between"); // Append an icon to remove the field el.appendChild(CloseIcon(16, 16)); // Set the click event el.addEventListener("click", () => { // Remove this field removeField(field); }); // Clear the filter _tbFilter.setValue(""); }) }); // Render the fields _ddlSelectedFields.setItems(_selectedFields); } // Filters the fields dropdown items let filterFields = (filter: string) => { // Parse the items let items = _ddlFields.el.querySelectorAll(".dropdown-item"); for (let i = 0; i < items.length; i++) { let item = items[i] as HTMLAnchorElement; let field = (item.innerText || "").toLowerCase(); // See if the field contains this value if (filter == "" || field.indexOf(filter) >= 0) { // Show this element item.classList.remove("d-none"); } else { // Hide this element item.classList.add("d-none"); } } } // Gets the selected field values let getSelectedFields = () => { let fields: Array<IWPListField> = []; // Get the selected fields for (let i = 0; i < _selectedFields.length; i++) { let field = _selectedFields[i]; // Ensure this is a field if (field.text && field.value) { // Save the field fields.push({ Name: field.value, Title: field.text }); } } // Return the fields return fields; } // Removes a selected field let removeField = (field: Components.IDropdownItem) => { // Parse the selected fields for (let i = 0; i < _selectedFields.length; i++) { let selectedField = _selectedFields[i]; // See if this is the target field if (selectedField.value == field.value) { // Remove this field _selectedFields.splice(i, 1); // Render the items _ddlSelectedFields.setItems(_selectedFields); // Stop the loop break; } } } // Renders the fields control let renderFields = (el: HTMLElement, fields: Array<IWPListField>) => { let filter = ""; // Create the dropdown menu _ddlFields = Components.Dropdown({ id: "calendarFields", menuOnly: true, onChange: item => { // Close the popover popover.hide(); // Clear the filter filterFields(""); // Add the selected field addField(item as any); } }); // Render the textfield _tbFilter = Components.InputGroup({ el, placeholder: "Select a Field...", onChange: value => { // Set the filter filter = value; // Wait for the user to stop typing setTimeout(() => { // Ensure the value hasn't changed if (value != filter) { return; } // Filter the fields filterFields(filter.toLowerCase()); // Display the popover popover.show(); }, 250); } }); // Render the selected fields _ddlSelectedFields = Components.Dropdown({ el, id: "selectedFields", menuOnly: true }); // Add a click event to display the popover _tbFilter.el.addEventListener("click", () => { // Display the popover popover.show(); }); // Create a popover let popover = Components.Popover({ el, target: _tbFilter.el, type: Components.PopoverPlacements.Auto, options: { trigger: "click", content: _ddlFields.el } }); } // Updates the fields let setItems = (fields: Array<Components.IDropdownItem>, selectedFields: Array<IWPListField> = []) => { // Update the dropdown _ddlFields.setItems(fields); // Parse the selected fields for (let i = 0; i < selectedFields.length; i++) { let fieldInfo = selectedFields[i]; // Parse the fields for (let j = 0; j < fields.length; j++) { let field = fields[j]; // See if this is the target field if (field.value == fieldInfo.Name) { // Add this field addField(field); break; } } } } // Updates the fields dropdown in the edit panel let updateFieldsDDL = (list: Types.SP.List, selectedFields: Array<IWPListField> = []) => { let items: Array<Components.IDropdownItem> = []; // Clear the dropdown setItems([{ isHeader: true, text: list ? "Loading the Fields" : "Select a List" }]); // Ensure the list exists if (list) { // Get the fields list.Fields().query({ OrderBy: ["Title"] }).execute(fields => { // Parse the fields for (let i = 0; i < fields.results.length; i++) { let field = fields.results[i]; // Skip the title fields if (field.InternalName == "LinkTitle" || field.InternalName == "LinkTitleNoMenu") { continue; } // Skip hidden fields if (field.Hidden) { continue; } // Set the dropdown value items.push({ text: field.Title, value: field.InternalName }); } // Update the dropdown values setItems(items, selectedFields); }); } } // Return the edit panel return { actions: props.actions, showSaveButton: props.showSaveButton, onListChanged: (wpInfo, list) => { // Update the fields dropdown updateFieldsDDL(list as any); }, onRenderForm: (wpInfo, list) => { // Save the webpart information _wpInfo = wpInfo; // Clear the selected fields _selectedFields = []; // Set the default control let controls: Array<Components.IFormControlProps> = [ { name: "Fields", label: "Fields", onControlRendered: ctrl => { // Render the fields control renderFields(ctrl.el, wpInfo.cfg.Fields); // Update the fields dropdown updateFieldsDDL(list as any, wpInfo.cfg.Fields); } } ]; // Call the render form event let returnVal: any = props.onRenderForm ? props.onRenderForm(_wpInfo, list) : null; if (returnVal) { // See if this is a promise if (returnVal.then) { // Return a promise return new Promise((resolve, reject) => { // Wait for the promise to complete returnVal.then((formControls = []) => { // Add the form controls controls = controls.concat(formControls); // Resolve the promise resolve(controls); }); }); } // Add the form controls controls = controls.concat(returnVal); } // Return the custom properties return controls; }, onSave: (cfg: IWPListFieldsCfg, form) => { // Update the configuration cfg.Fields = getSelectedFields(); // Return the configuration return props.onSave ? props.onSave(_wpInfo.cfg, form) : _wpInfo.cfg; } }; }