Need some help with developing of Custom Widgets


#1

Hello.
I need some help with the CustomWidget in makeblock. I can’t find any fresh documentation (if you know where is the fresh developer docs for the mblock v5 share the link please), and I’ve just found two options to make the dialog, but both do not work, here they are:

  1. This code is from the ‘Custom widgets’

    (widget) => {
    widget.setContent = (text, value) => {
    // TODO YOUR CODE
    widget.setValue([text, value]);
    console.log(“setContent t”, text);
    console.log(“setContent v”, value);
    }
    widget.showEditor_ = async () => {
    // TODO YOUR CODE
    console.log(“showEditor_”);
    DialogWidget(widget, ‘helloDialog’, ‘hey’, getOptions);
    }
    };

it prints “showEditor_” and then give me : “DialogWidget is not defined”

  1. Second option:

    (widget) => {
    widget.setContent = (text, value) => {
    // TODO YOUR CODE
    widget.setValue([text, value]);
    console.log(“setContent t”, text);
    console.log(“setContent v”, value);
    }
    widget.showEditor_ = async () => {
    // TODO YOUR CODE
    console.log(“showEditor_”);
    const service = window[’_appContext’].getService(‘system.ui’);
    return await service.dialog(‘test’, { title: ‘hello’, width: ‘340px’ });
    }
    };

it prints “howEditor” and then give me : “Cannot read properties of undefined (reading ‘getService’)” , so the window[’_appContext’] - is undefined.

Any ideas on how to make the dialog work?

Another way is using my own UI solution, linking some JS library(materializecss or similar), and getting the values back and forth.

PS: ChatGPT did not help as well…


#2

:slight_smile: ChatGPT knows nothing about mBlock Coding, really. It also lies a lot. mBlock does not have very good documentation about making custom widgets in blocks, but if you want to see how it is done in an extension, I can give you the link to download an mBlock extension that has a functioning Widget. (Such as Weather). If you would like the link, just mention so in your next reply.

Best Regards,
Best_Codes


#3

Thanks, @Best_codes it will be nice to have the link with your example.

So far, if someone else is interested, I’ve solved that like this:

How I solve the problem in short:

  1. Load the JS and CSS library for my UI (in my case materializecss).
  2. Made the dialog’s HTML shape and add that into the DOM
  3. Operate as expected.

Full description:

  1. Make the Sprite Extention.

  2. Make a block that calls Custom Widget.

  3. In the Common code settings of the Extention, add the loading code (the Add external JS library - does not work), so load that manually:

    // better to check that it loads once

    let scriptEle = document.createElement(“script”);
    scriptEle.setAttribute(“src”, “https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js”);
    document.body.appendChild(scriptEle);
    scriptEle.addEventListener(“load”, () => {
    console.log(“JS file loaded”)
    });

    scriptEle.addEventListener(“error”, (ev) => {
    console.log(“Error on loading JS file”, ev);
    });

     var head = document.getElementsByTagName('head')[0] 
     // Creating link element 
     var styleEle = document.createElement('link')  
     styleEle.href = 'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css'
     styleEle.type = 'text/css'
     styleEle.rel = 'stylesheet'
     head.append(styleEle); 
    

    styleEle.addEventListener(“load”, () => {
    console.log(“CSS file loaded”)
    });

    styleEle.addEventListener(“error”, (ev) => {
    console.log(“Error on loading CSS file”, ev);
    });

  4. Inside the Custom Widgets configuration, add this chank:

    widget.showEditor_ = () => {
    // TODO YOUR CODE
    console.log(“showEditor_”);

    // TODO: check that it loads once

     const modal1 = document.createElement("div");
         modal1.setAttribute('id', 'modal1');
         modal1.classList.add("modal");
    
         const modal_content = document.createElement("div");
         modal_content.classList.add("modal-content");
         modal_content.innerHTML = "Hello<br>Hello<br>Hello<br>";
    
         const modal_footer = document.createElement("div");
         modal_footer.classList.add("modal-footer");
    
         const a = document.createElement("a");
         a.innerHTML = "Close";
         a.classList.add("modal-close");
         a.classList.add("waves-effect");
         a.classList.add("waves-green");
         a.classList.add("btn-flat");
    
         modal_footer.appendChild(a);
         modal1.appendChild(modal_content);
         modal1.appendChild(modal_footer);
    
         document.body.appendChild(modal1);
         var instances = M.Modal.init(modal1, {});
         const i = M.Modal.getInstance(modal1);
         i.open();
         return;
     }
    

And all works as it should.


#4

Awesome! I’m so glad you resolved the issue! Here is the download link to the mBlock Weather extension:

https://ext-eu-res.makeblock.com/prod/weather_v1.2.6_54c92ad4.mext


#5

Are you using a grammar corrector that changes the " symbols? It messed up the code…

Here is the fixed version:


let scriptEle = document.createElement("script");
scriptEle.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js");
document.body.appendChild(scriptEle);
scriptEle.addEventListener("load", () => {
    console.log("JS file loaded");
});

scriptEle.addEventListener("error", (ev) => {
    console.log("Error on loading JS file", ev);
});

var head = document.getElementsByTagName('head')[0];
var styleEle = document.createElement('link');
styleEle.href = 'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css';
styleEle.type = 'text/css';
styleEle.rel = 'stylesheet';
head.append(styleEle);
styleEle.addEventListener("load", () => {
    console.log("CSS file loaded");
});

styleEle.addEventListener("error", (ev) => {
    console.log("Error on loading CSS file", ev);
});