JSFiddle - React, Tailwind, and code Playground
by Flexmonster Pivot Table
HTML
<script src="https://cdn.flexmonster.com/flexmonster.js"></script>
<div id="wrapper">
<div id="field-list">
<h3>Custom Field List</h3>
<button id="field-list-apply-button" onclick="runQuery()">
Apply
</button>
<div id="fields">
</div>
</div>
<div id="filter-list">
<h3>Custom Filter</h3>
<button id="filter-apply-button">
Apply
</button>
<div id="filters">
</div>
</div>
<div id="pivotContainer"></div>
</div>
CSS
body {
font-family: sans-serif;
}
h3 {
display: inline;
}
#wrapper {
height: 600px;
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: 15px;
display: none;
border: 1px solid #d5d5d5;
box-shadow: 0 0 20px rgb(0 0 0 / 10%);
}
#fields,
#filters {
margin-top: 30px;
max-height: 300px;
padding: 15px;
overflow-y: scroll;
border: 1px solid #d5d5d5;
}
#field-list-apply-button,
#filter-apply-button {
float: right;
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;
color: #fff;
background: #555;
margin-right: 20px;
height: 38px;
}
.field-item,
.fitler-item {
padding-bottom: 12px;
margin-bottom: 12px;
}
.field-select,
.field-button,
.sigma-icon {
margin-left: 10px;
}
.filter-checkbox {
float: right;
margin-left: auto;
}
.sigma-icon {
font-weight: bold;
}
.field-name,
.filter-name {
width: 150px;
max-width: 150px;
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
JavaScript
let pivot = new Flexmonster({
container: "pivotContainer",
componentFolder: "https://cdn.flexmonster.com/",
width: "100%",
height: "100%",
toolbar: true,
report: {
"dataSource": {
"type": "microsoft analysis services",
"proxyUrl": "https://olap.flexmonster.com/olap/msmdpump.dll",
"catalog": "Adventure Works DW Standard Edition",
"cube": "Adventure Works",
"binary": false
}
}
});
flexmonster.on("fieldslistopen", () => {
flexmonster.off("fieldslistopen");
flexmonster.closeFieldsList();
});
flexmonster.on("reportcomplete", () => {
flexmonster.off("reportcomplete");
openFieldList();
});
const filtersConfig = {};
const fieldList = document.getElementById("field-list");
const fields = document.getElementById("fields");
const filterList = document.getElementById("filter-list")
const filters = document.getElementById("filters");
function runQuery() {
let slice = {
columns: [],
rows: [],
measures: [],
reportFilters: []
};
for (let selectElement of document.querySelectorAll(".field-select")) {
if (selectElement.value != "none") {
let config = JSON.parse(selectElement.value);
slice[config.place].push({
uniqueName: config.uniqueName,
filter: {
exclude: filtersConfig[config.uniqueName]
}
});
}
}
if (slice.measures.length > 0) {
flexmonster.runQuery(slice);
closeFieldList();
} else {
flexmonster.alert({
title: "Error",
message: "Please select at least one measure",
type: "error",
buttons: [{
label: "OK",
}],
blocking: false
});
}
}
function applyFilter(field) {
let unchecked = [...document.querySelectorAll(".filter-checkbox")].filter(item => !item.checked);
filtersConfig[field] = [];
for (let member of unchecked) {
filtersConfig[field].push(member.getAttribute("member"));
}
closeFilter();
}
function openFieldList() {
for (let field of...