A Modal using µHTML
Tags: webdev, javascript, ux
Published: 2021-01-05 13:44:15

I have posted an article on implementing a Modal in pure Javascript here : [VanillaModal](https://dev.to/artydev/simple-modal-in-pure-javascript-3336).

But I don't like to have functions pollute global namespace.

With [<em>µ</em>html](https://github.com/WebReflection/uhtml) you can wrap your code in an IIFE and it just works.

You can test it here : [UHTMLModal](https://flems.io/#0=N4IgtglgJlA2CmIBcA2ADAOgBwBYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAJoAXgA64PlFqxlAPjEB6SVM2LqRidMPUZMsSwCMmgLKr1ciwAcArgCd4MgFIBlXVtzSyNLU1kFZTZPCABzOPhPRzUNEBDLKwAjdzY2ARkwJ1glEAQ49WUZTVCLTMsAGXgKjTrwnRy8gQzwzvyLItTS6ngAd1Iqmpkw+pkAOTGJtqsO3P6e7LWCwuLS2iy+XMmZ+oBBA6Pl3T7umd19c3uzIyNuEFJ4BB42CAFyJgArEgbDYALRAgBMAGYQABfPA0eiMZgAK3IvAEQhETAgYFcfE8bBkwG81CgSTwMnYnFhMkInj4YBkAHJ3NTYMyANwvagACkI7mo31+Fl5AEpiTMZggiQBhTHCNikGTySXLZTlSogGRIKkcWAAA2sdiaLSCdgNeBO0xAI3GVR1es4RuCC3G5s0lutyn2hzYVV17JddnOfo9BpmsKldRlMn8bFoQhVavq-EEit1ymUVuWEFIAHlXMJdYR1B8c-U+EXqAARCDqPhxEuC4UCcXAa2WeOJ+AYNNYomqtgsPN9hWCbnLLsJoQYPOF4TJmLueCT2YyKQQMbiteZeHWniwPgfOsNpt0ls-NtijtTuMz3vz6vJ0uwD67+qb7dij8yKN1f8ZgFIUrwsL9RhkcUU0yKRaE8HZUllN9k3vHs5wLZ9OxkAB+G1BmcfDYFBUgWD4UZjG1aY70zFRUgQ9RQRHGBhCqLDSXJTxeUIykgyw8J9DkKBk2UVw4MVKpD1oUhSFKAASYBCKQ0go21PjMgEQ8IB4ABrZN5N5eAJXkGpgF7BNPESNg5yE+RbJtUTSX9bUADJnNQ2dD2PeBTyPOJxVhWENnXCIZEk6TSkI0F+3E9IqPXYKBNINgAE8EFKIQAA82FBdR4moJBYjidgqg02AtN01V5O7DyjxPetfMC2p4visRSFEiwwpk5RIs8j4tCQrzdDa2hqCClq9GeO9gtcTQqofMd00EWFdBmtT2geNSngMTsDTFSMeUsGJ4kSZJigwWgYAAUSkRUGjzLEkl5ZRNJ07MLxAkVIMM6DLFjQi5iRSxVTMuDLIwSzTjyWJOngJ7aK1H9rWq3tosEZN5UWpUKH+pEAF1fxxhgZFc9zeyrYQfMbLjikRgC9uMahYTFcUeVZhm3n4PESCSUQsn2T43g+L5QP+EAoTQJAARwOEEVtJFRD7aSOfHNgFcikiyIsW9LEkNrYFoZLdSyI8dMnQDqAwSKmPJLWZl11x9cNmRqAEVcjHNy3ih+mR8VICBQJLCAMvgKBOTizIAC9QQgMl4Ay3UbDD61RJgGO4lBfJXF1CE0DQVwMt-BBCDYXU0CT5ZM9L39RmgYcE9zgBScv6hYeB4nYeu0Cb8PLD4G7PEII9Rl1Whcj4ZvMj5nS4gZQUoCivgj08XULKyXkIQ3vA0C32n6in7SZ8OMkF6Xle4j59et6vzAAR-KjzYOmQdAAKhkFJnAxgcZGfnQjE91IF6Y29vvQ+c8T4El1AAYkIPAGBMCCagxjiPMev4U6SGoOeHO+dfwHE8BxBO+cZCkEXtAGQkCsAUOrrXFguosBdwQRlUENcoB1xkAATnQNg5Ox5-YigKp8RM0g3bLBGriQRAgkCiIYJnGQmAcBLHNgAAW0vAZK9IkTKikfATO2s6QMjAMASuoJxZ5wLlWWgPB-aGzQLSGY+RdGHSrEgMu1pzGWJSsCXc-4PY9Vqj4XRPAvDEOXj7PgMchCeF3IVDuLjGY8n-gxXq8AkCkX7tBA4jCSIXTIqXWRMgASENXrQXk29SlbwwDgWmsJBafHgK2agosIQ2GcXCXGBA6AMFEGyfUhE4RAA)

```html
<div id="modal"></div>

<div>
  <h1>Modal with UHTML</h1>
  
  <div id="triggerModal">
    <button modal="legal" >  
      Legal
    </button>
    <button modal="news" >  
      News
    </button>
    <button  modal="about" >
      About
    </button>
  </div>
</div>
```

```css
#modal{
}

.modal-shown {
  display: block;
}

.modal-hidden {
  display: none;
}

.modal {
    position: fixed; 
    z-index: 1; 
    padding-top: 100px;
    left: 0;
    top: 0;
    width: 100%; 
    height: 100%; 
    overflow: auto; 
    background-color: rgb(222,0,0);
    background-color: rgba(2,0,0,0.5); 
}

  /* Modal Content */
.modal-content {
    background-color: #fefefe;
    margin: auto;
    padding: 20px;
    border: 1px solid #888;
    width: 80%;
    max-width: 960px;
    position:relative;
    animation:animetop 0.4s
}

@keyframes animetop{
  from{top:-300px;opacity:0} 
  to{top:0;opacity:1
  }
}

.modal-close {
  
  cursor: pointer;
  right:0;
}

.modal-close:hover {
  box-shadow: 0 0 5px rgba(0,0,0,0.4);
}
```


```js
import {render, html} from 'uhtml';

(function () {
  
  let Contents = {
    "legal" : html`<h1>Legal</h1>`,
    "news"  : html`<h1>News</h1>`,
    "about" : html`<h1>About</h1>`
  }
  
  let State = {
    content: "",
    isOpen: false,
    openDialog () {
      State.content = this.content
      State.isOpen = true;
      view()
    },
    closeDialog () {
      State.isOpen = false;
      view();
    }
  }

  function view () {
    var modalCls =  State.isOpen 
      ? "modal modal-shown"  
      : "modal modal-hidden"
        render(modal, html`
          <div class="${modalCls}">
            <div class="modal-content">
              <div style="text-align:right" onclick = ${State.closeDialog}> 
                <span class="modal-close">Close</span>
              </div>
              <p>${State.content}</p>
            </div>
          </div>
     `)
  }

  triggerModal.addEventListener("click", function (e) {
    let modalName  = e.target.getAttribute("modal")
    State.content = Contents[modalName]
    modalName && State.openDialog(modal)
  })
})()






```