1

My goal is to create custom form component using custom web elements. I need to add styling for the form component.

So I am using materializecss package. I need to import CSS and JavaScript file. I cannot able to work with the external JS file. I am using WebPack to bundle the files.

In the code i am trying to load Materialize JS file but it's not working. I don't know how to load Js files in custom web elements. Please somebody assist me.

const template = document.createElement('template');
template.innerHTML = `
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
  <div class="container">
  <div class="center-align">
      <h3 class="blue-text text-darken-4">Company-Form</h3>
      <h5 class="blue-text text-darken-2 title"></h5>
      <div class="row">
      <div class="col s12">
      <div class="card-content">
      <div class="row form-content">
      </div>
      </div>
      <div class="card-action btn-action">
      </div>
      </div>
      </div>
      </div>
    </div>
`;

export default class MyForm extends HTMLElement {
  constructor() {
    super();
    // shadow dom
    const shadowDOM = this.attachShadow({ mode: 'open' });

    // Render the template
    shadowDOM.appendChild(template.content.cloneNode(true));

  }
 }
Abinesh Joyel
  • 2,043
  • 2
  • 13
  • 18

1 Answers1

1

Yes you can. I am not tested your code, but I think problem is in webcomponents encapsulation.

  1. All js libs are placing variables and functions into window by default, not in webcomponent.So you better need to load js libs on main page before all components loadng
  2. When lib is loaded, lib is waiting domcontent loading event, for starting init components wrappers. And I think it should work.
  3. The reason that you code is not working, is that lib is searching elements in document, and can't see any webcomponents inner childs because of encapsulation.

Conclusion:

export default class SodisysForm extends HTMLElement {
  constructor() {
    super();
    // shadow dom
    const shadowDOM = this.attachShadow({ mode: 'open' });

    // Render the template
    shadowDOM.appendChild(template.content.cloneNode(true));

    var elems = shadowDOM.querySelectorAll('select');
    var instances = M.FormSelect.init(elems, []); //example of select init
  }
 }

You need manually init each component that you are using.

P.S.

  1. each webcomponent is a small document.
  2. in web component is better to use requirejs, if you are loading external js, in that case you know when lib is loaded. Or dynamic import if you can.
  3. I don't worked with pure webcomponents, I was working with Polymer lib, try it)

Polymer element get statrted

Alex Nikulin
  • 8,194
  • 4
  • 35
  • 37