Project

General

Profile

How to interact with JavaScript variables, methods & events?

Added by Stefan Bn about 4 years ago

Hi all,

I do understand on how to import a JavaScript using WApplication::require and execute it using WWidget::doJavaScript.

But from the Wt documention/forums it is still not quite clear to me on how to interact with a running JavaScript, especially on how to access data being generated by a JavaScript and stored in JS variables, react on events or to subsequently call certain methods in that script.

I'd like to integrate this "simple" JavaScript library that uses the system webcam to detect and return QR-Codes:

https://github.com/jbialobr/JsQRScanner

The API seems not very complex, but how do I call the methods (.stopScanning(), .resumeScanning()) in that API from Wt and foward calls to the event/function onQRCodeScanned(scannedText) to my Wt application?

Any hints or pseudo code are really appreciated!

Thanks,

Stefan


Replies (3)

RE: How to interact with JavaScript variables, methods & events? - Added by Stefan Bn about 4 years ago

I figured it out - the basic concept that answers the above questions is Wt's examples\javascript.

Just in case someone needs it or needs a cool WebApp based QR code scanner, here the are essentials:

WtView Header:

class MainView : public WContainerWidget
{
public:
    MainView(WApplication *a);

    // JavaScript Communication
    JSignal<std::string>                jsQRCodeDetectedSignal;
    void                                onQRCodeDetected(std::string qrCode);
[...]

WtView Source

MainView::MainView(WApplication *a) :
    WContainerWidget (),
    jsQRCodeDetectedSignal(this, "onQRCodeDetected_Signal")
{
    this->setId("MainViewCpp");      // For JavaScript interaction

[...]

    this->jsQRCodeDetectedSignal.connect(std::bind(&MainView::onQRCodeDetected, this, std::placeholders::_1));

    auto resultTxt = qrContainer->addNew<WLineEdit>("Scanning ...");
    resultTxt->setId("WtResultTxt");

    auto jsTxt = qrContainer->addNew<WText>(
                        Wt::utf8("<div class id='scanner' style='border:1px solid black;'> </div>"),
                        TextFormat::UnsafeXHTML);

    jsTxt->setStyleClass("qrscanner");

    jsTxt->doJavaScript("JsQRScannerReady()");

    scanOnCheck->changed().connect([=] ()
    {
        if (!scanOnCheck->isChecked())
            jsTxt->doJavaScript("StopQrScanner()");
        else
            jsTxt->doJavaScript("ResumeQrScanner()");
    });

[...]

JavaScript implementation and library

https://github.com/jbialobr/JsQRScanner

both imported using WApplication->require

var jbScanner;

function onQRCodeScanned(scannedText)
{
    var textarea  = document.getElementById("WtResultTxt");
    if(textarea)
    {
        textarea .value = scannedText;
    }

    Wt.emit('MainViewCpp', 'onQRCodeDetected_Signal', scannedText)
}

function StopQrScanner()
{
    jbScanner.stopScanning();
}

function ResumeQrScanner()
{
    jbScanner.resumeScanning();
}

//this function will be called when JsQRScanner is ready to use
function JsQRScannerReady()
{
    //create a new scanner passing to it a callback function that will be invoked when
    //the scanner succesfully scan a QR code
    jbScanner = new JsQRScanner(onQRCodeScanned);
    //reduce the size of analyzed images to increase performance on mobile devices
    jbScanner.setSnapImageMaxSize(300);
    var scannerParentElement = document.getElementById("scanner");
    if(scannerParentElement)
    {
        //append the jbScanner to an existing DOM element
        jbScanner.appendTo(scannerParentElement);
    }

    console.log('JsQRScannerReady Initialized');
}

The size of the video streaming output is being controled using CSS:

.qrscanner video
{
  max-width: 300px;
  max-height: 300px;
}

That simple :-) But a little hard for me to find the way into Wt <> JS interaction.

And lesson learned: Firefox caches javascript files, so making changes to javascript files requires some browser clean up before re-starting

RE: How to interact with JavaScript variables, methods & events? - Added by Emeric Poupon about 4 years ago

And lesson learned: Firefox caches javascript files, so making changes to javascript files requires some browser clean up before re-starting

Chrome cache css files too on Android devices.

One simple workaround is to open the site in private navigation mode (and close/reopen the tab in order to refresh the files)

RE: How to interact with JavaScript variables, methods & events? - Added by Stefan Bn almost 4 years ago

Emeric Poupon wrote:

One simple workaround is to open the site in private navigation mode (and close/reopen the tab in order to refresh the files)

This didn't work for me. But this is great:

https://nicholasbering.ca/tools/2016/10/09/devtools-disable-caching/

    (1-3/3)