MySQL Editor in NodeJS ~ Part Three

Andrew Bone - Sep 28 '18 - - Dev Community

MySQL Editor in NodeJS

I missed a week, sorry about that, but now I'm back. I didn't do too much this time. I've made a JS Router, or at least I think that's what you'd call it, to handle different 'states' also I've started making the actual editor with a way to select your Database and table.

If you'd like to follow along with my journey here is my post index.

GitHub logo ignis-pwa / nodetree

A MySQL Browser written in NodeJS

nodetree

A MySQL Browser written in NodeJS

Read about this project on dev.to

Try out the demo the password is demopassword




Interface update

interface

As you can, hopefully, see I've added a new 'state' this pulls in some more HTML to overwrite what's there already, but I'll go into that later.

The space over to the right will have a table of results and the query input box.

Here's a close look at the selection menu

menu

JS Router

I'm still not sure this qualifies as a router. It has a state and depending on the state will load a different HTML file into the body of the page.

class SimpleStateRouter {
    constructor() {
      this.body = document.body;
      this.stateList = ['connection', 'database'];
      this.event = new CustomEvent('state-changed');
      this.req = new XMLHttpRequest();
      this.body.addEventListener('state-changed', res => { this._getFragment() });
      this.req.addEventListener('load', res => { this._setFragment(res) });

      this.body.dataset.state || this.setState('connection');
    }
    //// PRIVATE ////
    /* Private method to get fragment */
    _getFragment() {
      for (let state of this.stateList) this._unloadScript(`/scripts/${state}.js`);
      this.req.open("GET", `/fragment/${this.state}`);
      this.req.send();
    }
    /* Private method to load external JS file */
    _loadScript(url) {
      const head = document.getElementsByTagName('head')[0];
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = url;
      head.appendChild(script);
    }
    /* Private method to remove external JS file */
    _unloadScript(url) {
      for (let tag of document.querySelectorAll(`script`)) tag.getAttribute('src') == url && tag.parentNode.removeChild(tag)
    }
    /* Private method to update the dom */
    _setFragment(res) {
      document.body.innerHTML = res.srcElement.response;
      this._loadScript(`/scripts/${this.state}.js`);
    }
    //// PUBLIC ////
    /* Public setter method to update current state */
    setState(state = "") {
      if (this.state == state || this.stateList.indexOf(state) == -1) return
      this.state = state;
      this.body.dataset.state = this.state;
      this.body.dispatchEvent(this.event);
    }
  }
Enter fullscreen mode Exit fullscreen mode

I have no idea if this is a good idea, it seems fast enough I've been keeping an eye on my lighthouse score, again no idea if that's useful, and it's all green at the moment.

lighthouse

The idea behind this state router is to change the page without updating it, I know this means the back button is now defunct so I might look into that next week.

The syntax is quite simple I just have to call setState with the state name as the argument and class deals with the rest.

const stateHelper = new SimpleStateRouter();
stateHelper.setState('database');
Enter fullscreen mode Exit fullscreen mode

Other little bits

I've done a couple of other little bits like adding a material toast class and the styling for it. My git repository is up to date now so feel free to take a look and leave issues with suggestions if you like.

End of post

Thanks for reading, please don't be shy to comment, even if it's just to tell me I'm doing it all wrong 😅

Thanks again 🦄🦄🦄

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .