使本机 Web 组件对话框显示在另一个本机 Web 组件对话框之上

问题描述 投票:0回答:1

在此代码片段中,我有一个

wc-notifier
组件来显示错误。显示现有错误 (
Oh no existing error!
)。

然后显示“表单模式”(

wc-modal-form
),其中包含供用户填写的输入。目前,它错误地出现在错误消息前面(错误消息应该位于顶部)。如果单击下面的“验证”按钮,附加错误消息也会错误地显示在表单模式下方(错误消息应位于顶部)。我不知道如何使错误通知器(对话框)出现在表单模式(对话框)的顶部。

如何改变浏览器中元素的顺序

Top-layer

我已经尝试了所有可以使用的技巧,包括定义组件的顺序、创建组件的顺序、打开对话框的顺序。

class NotifierComponent extends HTMLElement {
  constructor() {
      super().attachShadow({mode:'open'});
      const template = document.getElementById("TEMPLATE_notifier");
      this.shadowRoot.appendChild(template.content.cloneNode(true));
  }
  error(msg) {
      const errorEl = document.createElement('div');
      errorEl.innerText = msg;
      this.appendChild(errorEl)
  }
}
window.customElements.define('wc-notifier', NotifierComponent);

document.getElementById("NOTIFIER").error("Oh no existing error!")

class FormModalComponent extends HTMLElement {
  constructor() {
      super().attachShadow({mode:'open'});
      const template = document.getElementById("TEMPLATE_modalform");
      this.shadowRoot.appendChild(template.content.cloneNode(true));
  }
  showModal() {
      this.shadowRoot.getElementById("MODAL").showModal();
  }
}
window.customElements.define('wc-modal-form', FormModalComponent);

const modalFormEl = document.createElement('wc-modal-form');
document.body.appendChild(modalFormEl)
modalFormEl.showModal();
<template id="TEMPLATE_notifier">
  <style>
      dialog {
         display: flex;
         gap: 16px;
         flex-direction: column;         
         border: none;
         background: none;
         top: 0;
         margin-left: auto;
         margin-right: 0;
      }
      ::slotted(*) {
         background: red;
         padding: 16px 8px;
      }
      </style>
  <dialog>
     <slot></slot>
  </dialog>
</template>

<wc-notifier id="NOTIFIER"></wc-notifier>

<template id="TEMPLATE_modalform">
  <style>
      dialog {
          background: cream;
          padding: 64px;
          width: 100%;
      }
  </style>
  <dialog id="MODAL">
      <div>This is the FORM MODAL. It should appear below the errors</div>
      <button id="VALIDATE" type="button" onclick="document.getElementById('NOTIFIER').error('Please fill out all the required form fields')">Validate Form</button> 
  </dialog>
</template>

html web-component native-web-component
1个回答
0
投票

关键在于在正确的时间申请

.showModal()

请阅读:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

这是一个(不完美的)游乐场:

https://jsfiddle.net/WebComponents/gtn86p5c/

<template id="WC-NOTIFIER">
  <style>
    dialog {
      display: block;
      width: 50vh;
      height: 50vh;
      background: lightcoral;
    }
    ::slotted(*) {
      /* doesn't work on TEXT nodes only */
      background: red;
      height: 100%;
    }
  </style>
  <dialog>
    <slot></slot>
  </dialog>
</template>

<wc-notifier id="NOTIFIER">EXISTING ERROR</wc-notifier>

<template id="WC-MODAL-FORM">
  <style>
    dialog {
      width: 100%;
      text-align:center;
    }
  </style>
  <dialog>
    <div>This is the FORM MODAL. It should appear below the errors</div>
    <button id="VALIDATE" type="button" onclick="this.getRootNode().host.validate()">Validate Form</button>
  </dialog>
</template>

<script>
  class BaseClass extends HTMLElement {
    constructor() {
      super()
        .attachShadow({mode:'open'})
        .append(document.getElementById(this.nodeName).content.cloneNode(true));
    }
    get dialog(){
        return this.shadowRoot.querySelector("dialog");
    }
    showModal(){
        this.close(); /* can not re-open <dialog> as modal */
      this.dialog.showModal();    
    }
    close(){
        this.dialog.close();
    }
    open(){
        this.dialog.open();
    }
    connectedCallback() {
      this.showModal();
      console.log("connected", this.nodeName);
    }
  }
  customElements.define('wc-notifier', class extends BaseClass {
    set error(innerText) {
      this.innerHTML = "";
      this.append(Object.assign(document.createElement('div'), {
        innerText,
        onclick: evt => this.close()
      }));
      this.showModal();
    }
  });
  customElements.define('wc-modal-form', class extends BaseClass {
    validate() {
      // This is tight coupling!! Should do this with Events!!
      document.getElementById("NOTIFIER").error = "VERIFY INPUTS!";
    }
  });
  
  // executed BEFORE <wc-modal-form> !! so NOT stacked at the top!
  document.getElementById("NOTIFIER").error = "NEW ERROR";

</script>

<wc-modal-form></wc-modal-form>

© www.soinside.com 2019 - 2024. All rights reserved.