JSFiddle - React, Tailwind, and code Playground
Custom UI controls and views
by Flexmonster Pivot Table
HTML
<script src="https://cdn.flexmonster.com/flexmonster.js"></script>
<div id="wrapper">
<div id="backdrop"></div>
<div id="filter-list">
<h3>Custom Filter</h3>
<button id="filter-cancel-button" class="button" onclick="closeFilter()">
Cancel
</button>
<button id="filter-apply-button" class="button">
Apply
</button>
<div id="filters">
</div>
</div>
<div id="pivot-container"></div>
</div>
CSS
body {
font-family: sans-serif;
}
h3 {
display: inline;
}
#fm-pivot-view div.fm-ui-modal-overlay {
display: none !important;
}
#wrapper {
height: 580px;
position: relative;
}
#field-list,
#filter-list {
position: absolute;
inset: 0 0 0 0;
margin: auto;
min-width: 400px;
width: 60%;
height: 400px;
z-index: 3;
background: white;
padding: 30px;
display: none;
border: 1px solid #d5d5d5;
box-shadow: 0 0 20px rgb(0 0 0 / 10%);
transition: width 0.3s ease-in-out;
}
#field-list {
z-index: 5;
}
#filter-list {
z-index: 10;
}
#backdrop {
position: absolute;
display: none;
top: 0;
left: 0;
z-index: 3;
width: 100%;
height: 100%;
background-color: #fff;
opacity: 0.6;
}
#filters {
margin-top: 30px;
height: 300px;
padding: 15px;
overflow: auto;
border: 1px solid #d5d5d5;
}
#filters h4 {
margin-bottom: 0;
margin-top: 0;
}
.button {
user-select: none;
font: inherit;
transition: none;
border-collapse: collapse;
border-spacing: 0;
font-family: Arial, sans-serif;
margin: 0;
text-shadow: none;
line-height: normal;
box-sizing: border-box;
text-transform: uppercase;
position: relative;
outline: none;
border-radius: 4px;
cursor: pointer;
text-align: center;
display: inline-block;
vertical-align: top;
font-size: 14px;
font-weight: bold;
padding: 10px 12px;
letter-spacing: 0.5px;
min-width: 90px;
border: 1px solid #555;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-right: 20px;
height: 38px;
}
#filter-apply-button {
float: right;
color: #fff;
background: #555;
}
#filter-cancel-button {
float: right;
color: #555;
background: #fff;
}
,
#filter-apply-button:hover {
background-color: #3c3c3c;
cursor: pointer;
}
.filter-item {
display: flex;
justify-content: space-between;
flex-direction: row;
align-items: center;
padding: 12px 40px;
user-select: none;
border-bottom: 1px dashed...
JavaScript
const pivot = new Flexmonster({
container: "pivot-container",
componentFolder: "https://cdn.flexmonster.com/",
height: "100%",
toolbar: true,
licenseFilePath: "https://cdn.flexmonster.com/jsfiddle.charts.key",
report: {
dataSource: {
filename: "data/sales.csv",
},
},
});
const filtersConfig = {};
const fields = document.getElementById("fields");
const filterList = document.getElementById("filter-list");
const filters = document.getElementById("filters");
const backdrop = document.getElementById("backdrop");
let currentHierarchy = null;
pivot.on("filteropen", (event) => {
const element = document.querySelector(".fm-filter-view");
if (element) {
element.remove();
}
currentHierarchy = event.hierarchy;
openFilter(currentHierarchy.uniqueName, true);
});
function applyFilter(field, openedFromGrid) {
let unchecked = [...document.querySelectorAll(".filter-checkbox")].filter(
(item) => !item.checked,
);
filtersConfig[field] = [];
for (let member of unchecked) {
filtersConfig[field].push(member.getAttribute("member"));
}
closeFilter();
if (openedFromGrid) {
pivot.setFilter(field, {
exclude: filtersConfig[field],
});
}
}
function openFilter(uniqueName, openedFromGrid) {
pivot.getMembers(uniqueName, "", (members) => {
for (let member of members) {
filters.appendChild(createFilterItem(uniqueName, member));
}
});
document.getElementById("filter-apply-button")
.setAttribute("onclick", `applyFilter("${uniqueName}",${openedFromGrid})`);
filterList.style.display = "block";
}
function createFilterItem(field, member) {
let item = document.createElement("div");
item.classList.add("filter-item");
item.innerHTML =
`<label
class="filter-name"
for='${member.uniqueName}'
>
${member.caption}
</label>` +
`<input
type="checkbox"
class="filter-checkbox"
id='${member.uniqueName}'
member="${member.uniqueName}"
...