Despite the COVID-19 outbreak, our team continues operating at full speed. We are always here to support and answer all your questions.

Feel free to reach out by filling this quick form.

Fill the form
Get Free Trial

Always show report filters area

Resolved
Marc Faber asked on October 20, 2020

Hi,
I am looking for a way to “always” show the report filters area even when it is empty, to make use of Drag&Drop assignment.
Is there a setting like showReportFiltersArea which makes the area always visible?
Thank you in advance.

4 answers

Public
Illia Yatsyshyn Illia Yatsyshyn Flexmonster October 21, 2020

Hello, Marc,
 
Thank you for reaching out to us.
 
Our team wants to explain that Flexmonster does not provide the possibility to show the report filters area without any report filters present.
Please let us know how critical is this feature for your case.
 
We are looking forward to hearing from you.
 
Kind regards,
Illia

Public
Marc Faber October 22, 2020

Hi Illia,
thank you for the information. This is not crucial to us, but would be a nice feature nevertheless.
Perhaps we could add some kind of dummy element to the filter area and hide it, so the filter area stays open? Would that be possible?
Kind regards,
Marc

Public
Illia Yatsyshyn Illia Yatsyshyn Flexmonster October 22, 2020

Hello, Marc,
 
Thank you for your feedback.
 
We want to explain that if no actual fields are placed to report filters, Flexmonster will not be rendered correctly. Instead, we recommend checking out the workaround described below.
 
First, we recommend checking out the JSFiddle demonstrating the approach described below.
The approach implies using the dummy hierarchy to make the component render report filters area.
Therefore, you need to add the dummy field to your structure. To avoid modifying the data set itself, we suggest using the Mapping Object. It allows defining field data types, captions, etc. Moreover, it can be used to add a non-existing field to the structure:

mapping: {
  /* Existing fields */
  "Color": {
    "type": "string"
  },
  "Month": {
    "type": "month"
  },
  /* Dummy field */
  "Dummy": { }
}

 
Next, place the “Dummy” field to the report filters (for convenience, always place it on the first place):

"reportFilters": [
  {
    "uniqueName": "Dummy"
  },
  ...
]

 
Hide the element representing the cell and make it float to the right using the following CSS rule:

#pivotContainer a[data-h="0"] {
  visibility: hidden;
  float: right !important;
}

Now, the report filters area is always shown above the grid, and the dummy field is not visible and achievable.
 
However, the “Dummy” field persists in the Field List. It means the user can interact with it or remove it from the report filters.
Therefore, all references to the “Dummy” hierarchy should be removed from the Field List.
Please see the following code snippet to learn one of the possible options to do that:

pivot.on("fieldslistopen", function() { //subscribe to the fieldlistopen event
  pivot.off("fieldslistopen"); //unsubscribe from the fieldlistopen event (the function must be executed only once)
  let lists = document.querySelectorAll("#pivotContainer div.fm-ui-element.fm-ui.fm-list-content > ul"); //get all lists available in the Field List. The "#pivotContainer" container's id serves to avoid false positive results when using multiple Flexmonster instances on the same page.
  const sheet = new CSSStyleSheet(); //create CSSStyleSheet object
  setTimeout(() => {
    for (let node of lists[0].childNodes) //iterate over elements of the first list and find the dummy one
      if (node.childNodes[1].innerText == "Dummy")
        sheet.insertRule(`${getUniqueSelector(node)} { display: none !important; }`); //get unique CSS selector of the found element and apply required styling
    for (let node of lists[1].childNodes) //iterate over elements of the second list and find the dummy one
      if (node.childNodes[0].innerText == "Dummy")
        sheet.insertRule(`${getUniqueSelector(node)} { display: none !important; }`); //get unique CSS selector of the found element and apply required styling
  });
  document.adoptedStyleSheets = [sheet]; //complement styles of the page with generated rules
});

 
The code snippet above uses the getUniqueSelector function. This function serves to retrieve the unique CSS selector of the element. Please see its implementation below:

function getUniqueSelector(node) {
  let selector = "";
  while (node.parentElement) {
    const siblings = Array.from(node.parentElement.children).filter(
      sibling => sibling.tagName === node.tagName
    );
    let attributes = "";
    for (let attribute of node.attributes)
      if (attribute.name != "id")
        attributes += `[${attribute.name}="${attribute.value}"]`;
    selector = (siblings.indexOf(node) ?
      `${node.tagName}:nth-child(${siblings.indexOf(node) + 1})` :
      `${node.tagName}${attributes}`) + `${selector ? " > " : ""}${selector}`;
    node = node.parentElement;
  }
  return `html > ${selector.toLowerCase()}`;
}

You are welcome to either use this function or replace it with your custom analog if needed.
 
Please let us know if it works for you.
Our team is looking forward to your feedback.
 
Best regards,
Illia

Public
Marc Faber October 26, 2020

Hi,
thank you for pointing me in the right direction and providing a working example directly with it.
I think we can surely go with this solution so I can mark this question as answered.
Best regards,
Marc

Please login or Register to Submit Answer