0

This is a part of the HTML of my LWC:

<template>
  <div class="slds-grid slds-grid_vertical">
    ...
    <lightning-datatable ...>
    ...
  </div>
  <template if:true={openBackOrdersModal}>
    <section role="dialog" tabindex="-1" class="slds-modal slds-fade-in-open slds-modal_medium" aria-labelledby="modal-heading-bo" aria-modal="true" aria-describedby="modal-content-id-bo">
      <div class="slds-modal__container">
        <header class="slds-modal__header">
          <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title={label.ditVensterSluiten} onclick={closeBackOrdersModal}>
            <lightning-icon icon-name="utility:close" variant="inverse" size="small"></lightning-icon>
          </button>
          <h3 id="modal-heading-bo" class="slds-modal__title slds-hyphenate">{backOrdersModalTitle}</h3>
        </header>
        <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-bo">
          <lightning-datatable
            key-field="Id"
            data={backOrders}
            columns={backOrderColumns}
            is-loading={isLoading}
            hide-checkbox-column="true"
            suppress-bottom-bar="true">
          </lightning-datatable>
        </div>
      </div>
    </section>
    <div class="slds-backdrop slds-backdrop_open"></div>
  </template>
</template>

openBackOrdersModal is set to true when some button on the LWC is clicked. The modal is displayed, but the contents of the LWC, on top of which the modal is displayed, are scrolled all the way to the top.

The contents of the LWC, which itself is a modal window, are longer then the screen, so scrolling is necessary to see the bottom part. The LWC contains, amongst other things, a datatable where each row has a button. The contents of the modal are dependent on the button that is clicked. The users sometimes need to click several buttons to inspect details for each of the rows.

As it is now, the user scrolls down, clicks a button, modal is displayed, and the contents of the LWC are scrolled all the way to the top (this is instantaneous). So the user must scroll down once more, click another button, and so on and so on. This is very annoying for the user. I found the HTML code for the modal for the most part of it on the internets, the modal part I found here.

Some more googling let me to this general solution. It proposes:

When the modal is shown:

document.body.style.position = 'fixed';
document.body.style.top = `-${window.scrollY}px`;

When the modal is hidden:

const scrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
window.scrollTo(0, parseInt(scrollY || '0') * -1);

According to this question+answer, it should be possible to address document and window in this way, but in my case it doesn't appear to do anything.

1
  • I tried to move the template tag of the modal section outside of the main template tag, but that is not valid: error "Multiple roots found" Oct 1 '20 at 8:00
0

Try setting window.scrollTo(0, 500); when you close the modal pop up

Here is the link for your reference. https://www.w3schools.com/JSREF/met_win_scrollto.asp

4
  • I don't want to do any scrolling, the contents of the LWC should stay where they are. Sep 16 '20 at 11:29
  • But you gave me an idea: the function that sets openBackOrdersModal to true, should remember scrollTop. Then the close function can restore the scrolling to this position. Only problem: how to get scrollTop? For document.documentElement, document.body.parentNode and document.body, it is equal to 0. Sep 16 '20 at 13:20
  • Try using this property in JS file when you set modal flag 1. On click of openModal – a. document.body.setAttribute('style', 'overflow:hidden !important;'); 2. On click of closeModal or wherever you are having logic of closing modal – a. document.body.setAttribute('style', 'overflow:visible;'); Sep 17 '20 at 6:29
  • No, that doesn't help either. Sep 28 '20 at 13:07
0

The problem turned out to be a .focus() call for an element in the upper part of the window, in the renderedCallback.

Just making the .focus() call conditional solved the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.