Making front end with uibuilder+bootstrap

Hi, everyone
I am making project with uibuilder for develop front end user, but data from node-red will be lost if refreshing page.
Can somebode help me ?

node-red-contrib-uibuilder

2 Likes

Check the wiki pages: caching

1 Like

oke thx,
now i try to sending data message from node red to front end is work. But, if i sending data more than one for the same time this not work. can u explain this ?


Hi, can you please explain this a little more? I am not clear what you are sending more than one of? Are you sending multiple messages very quickly? Two properties in a single message?

BTW, sorry for the late reply, been rather busy this week.

yes i want to send multitape message very quickly,
because i am making project to monitoring machine, and i have more than 100 machines, and 1 machine have 2 variable time respon and time working.
I appreciate your taking the time to answer my question. It has really helped me, thank you

[{"id":"36af6ffb.4d4c8","type":"uibuilder","z":"788fc792.d1a41","name":"garmet","topic":"","url":"garmet","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"debugFE":false,"copyIndex":false,"template":"","x":920,"y":1120,"wires":[["166bc15a.7989e7"],[]]},{"id":"166bc15a.7989e7","type":"function","z":"788fc792.d1a41","name":"payload.message","func":"msg.payload = msg.payload.message\nreturn msg;","outputs":1,"noerr":0,"x":1090,"y":1120,"wires":[["710087c4.61e42"]]},{"id":"1aa3cfa7.f31d78","type":"function","z":"788fc792.d1a41","name":"[s] to [hh:mm:ss]","func":"// Message from preceeding node is in seconds - should be less than 24 hours (86400 seconds).\nvar time = (new Date(msg.payload * 1000)).toUTCString().match(/(\\d\\d:\\d\\d:\\d\\d)/)[0];\n// Pass on the string to the next node, what ever that may be. (groov Data Store for example).\nmsg.timeResp = time;\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":1080,"wires":[["a20b145e.e4595","36af6ffb.4d4c8"]]},{"id":"60956c9b.8faaec","type":"function","z":"788fc792.d1a41","name":"[s] to [hh:mm:ss]","func":"// Message from preceeding node is in seconds - should be less than 24 hours (86400 seconds).\nvar time = (new Date(msg.payload * 1000)).toUTCString().match(/(\\d\\d:\\d\\d:\\d\\d)/)[0];\n// Pass on the string to the next node, what ever that may be. (groov Data Store for example).\nmsg.timeWork = time;\nreturn msg;","outputs":1,"noerr":0,"x":700,"y":1200,"wires":[["36af6ffb.4d4c8"]]},{"id":"710087c4.61e42","type":"debug","z":"788fc792.d1a41","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1310,"y":1120,"wires":[]},{"id":"a20b145e.e4595","type":"debug","z":"788fc792.d1a41","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":910,"y":1020,"wires":[]},{"id":"4023c8f.334d138","type":"function","z":"788fc792.d1a41","name":"not-1","func":"msg.payload=(msg.payload-1);\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":1080,"wires":[["1aa3cfa7.f31d78"]]},{"id":"b1be5716.d35f68","type":"function","z":"788fc792.d1a41","name":"not-1","func":"msg.payload=(msg.payload-1);\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":1200,"wires":[["60956c9b.8faaec"]]},{"id":"ebbb6f6f.9ded58","type":"counter","z":"788fc792.d1a41","name":"","init":"1","step":"1","lower":"-1","upper":null,"mode":"increment","outputs":2,"x":400,"y":1080,"wires":[["4023c8f.334d138"],[]]},{"id":"f1cef891.0d368","type":"counter","z":"788fc792.d1a41","name":"","init":"0","step":"1","lower":null,"upper":null,"mode":"increment","outputs":2,"x":420,"y":1200,"wires":[["b1be5716.d35f68"],[]]},{"id":"d4f9ad3a.879e68","type":"inject","z":"788fc792.d1a41","name":"Increment Time","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1080,"wires":[["ebbb6f6f.9ded58"]]},{"id":"7214d475.e15e7c","type":"function","z":"788fc792.d1a41","name":"Reset","func":"msg.reset = 1;\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":1120,"wires":[["ebbb6f6f.9ded58"]]},{"id":"15a0e636.461c0a","type":"inject","z":"788fc792.d1a41","name":"Increment Time","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1200,"wires":[["f1cef891.0d368"]]},{"id":"98fcefc3.dd12c","type":"function","z":"788fc792.d1a41","name":"Reset","func":"msg.reset = 1;\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":1240,"wires":[["f1cef891.0d368"]]},{"id":"75e373b4.9a19e4","type":"inject","z":"788fc792.d1a41","name":"Reset Time","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1120,"wires":[["7214d475.e15e7c"]]},{"id":"70fe972b.99914","type":"inject","z":"788fc792.d1a41","name":"Reset Time","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1240,"wires":[["98fcefc3.dd12c"]]}]

Can you share the front-end code as well?

index.html

<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>EWS</title>

  <!-- Custom fonts-->
  <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles-->
  <link href="css/sb-admin-2.min.css" rel="stylesheet">
  <link href="scc/style.css" rel="stylesheet">

</head>

<body id="page-top">
    <!-- Page Wrapper -->
  <div id="wrapper">

    <!-- Sidebar -->
    <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">

      <!-- Sidebar - Brand -->
      <a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
        <div class="sidebar-brand-icon">
          <i class="fas fa-cubes"></i>
        </div>
        <div class="sidebar-brand-text mx-3">EWS</div>
      </a>

      <!-- Divider -->
      <hr class="sidebar-divider my-0">

      <!-- Nav Item - Dashboard -->
      <li class="nav-item">
        <a class="nav-link" href="index.html">
          <i class="fas fa-fw fa-tachometer-alt"></i>
          <span>Dashboard</span></a>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Heading -->
      <div class="sidebar-heading">
        GM 1
      </div>

      <!-- Nav Item - Pages Collapse Menu -->
      <li class="nav-item active">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseMn" aria-expanded="true" aria-controls="collapseTwo">
          <i class="fas fa-fw fa-cog"></i>
          <span>Maintenance</span>
        </a>
        <div id="collapseMn" class="collapse show" aria-labelledby="headingTwo" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <a class="collapse-item active" href="maintenance.html">Bolt Forming 1</a>
            <a class="collapse-item" href="#">Bolt Forming 2</a>
            <a class="collapse-item" href="#">Machining</a>
            <a class="collapse-item" href="#">Rolling</a>
          </div>
        </div>
      </li>

      <!-- Nav Item - Utilities Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseLab" aria-expanded="true" aria-controls="collapseUtilities">
          <i class="fas fa-flask"></i>
          <span>QC Lab</span>
        </a>
        <div id="collapseLab" class="collapse" aria-labelledby="headingUtilities" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <a class="collapse-item" href="#">Bolt Forming 1</a>
            <a class="collapse-item" href="#">Bolt Forming 2</a>
            <a class="collapse-item" href="#">Machining</a>
            <a class="collapse-item" href="#">Rolling</a>
          </div>
        </div>
      </li>

      <!-- Nav Item - Utilities Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseGbb" aria-expanded="true" aria-controls="collapseUtilities">
          <i class="fas fa-boxes"></i>
          <span>Gudang Bahan Baku</span>
        </a>
        <div id="collapseGbb" class="collapse" aria-labelledby="headingUtilities" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <a class="collapse-item" href="#">Bolt Forming 1</a>
            <a class="collapse-item" href="#">Bolt Forming 2</a>
          </div>
        </div>
      </li>

      <!-- Nav Item - Utilities Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#tooling" aria-expanded="true" aria-controls="collapseUtilities">
          <i class="fas fa-cogs"></i>
          <span>Technical Engineering</span>
        </a>
        <div id="tooling" class="collapse" aria-labelledby="headingUtilities" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <a class="collapse-item" href="#">Bolt Forming 1</a>
            <a class="collapse-item" href="#">Bolt Forming 2</a>
          </div>
        </div>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Sidebar Toggler (Sidebar) -->
      <div class="text-center d-none d-md-inline">
        <button class="rounded-circle border-0" id="sidebarToggle"></button>
      </div>

    </ul>
    <!-- End of Sidebar -->

    <!-- Content Wrapper -->
    <div id="content-wrapper" class="d-flex flex-column">

      <!-- Main Content -->
      <div id="content">

        <!-- Topbar -->
        <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">

          <!-- Sidebar Toggle (Topbar) -->
          <button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
            <i class="fa fa-bars"></i>
          </button>

          <!-- Topbar Search -->
          <form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
            <div class="input-group">
              <input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
              <div class="input-group-append">
                <button class="btn btn-primary" type="button">
                  <i class="fas fa-search fa-sm"></i>
                </button>
              </div>
            </div>
          </form>

          <!-- Topbar Navbar -->
          <ul class="navbar-nav ml-auto">

            <!-- Nav Item - Search Dropdown (Visible Only XS) -->
            <li class="nav-item dropdown no-arrow d-sm-none">
              <a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="fas fa-search fa-fw"></i>
              </a>
              <!-- Dropdown - Messages -->
              <div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown">
                <form class="form-inline mr-auto w-100 navbar-search">
                  <div class="input-group">
                    <input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
                    <div class="input-group-append">
                      <button class="btn btn-primary" type="button">
                        <i class="fas fa-search fa-sm"></i>
                      </button>
                    </div>
                  </div>
                </form>
              </div>
            </li>

 
            <div class="topbar-divider d-none d-sm-block"></div>

            <!-- Nav Item - User Information -->
            <li class="nav-item dropdown no-arrow">
              <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <span class="mr-2 d-none d-lg-inline text-gray-600 small">Admin</span>
                <i class="fas fa-user-shield"></i>
              </a>
              <!-- Dropdown - User Information -->
              <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
                <a class="dropdown-item" href="#">
                  <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
                  Profile
                </a>
                <a class="dropdown-item" href="#">
                  <i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i>
                  Settings
                </a>
                <a class="dropdown-item" href="#">
                  <i class="fas fa-list fa-sm fa-fw mr-2 text-gray-400"></i>
                  Activity Log
                </a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">
                  <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
                  Logout
                </a>
              </div>
            </li>

          </ul>

        </nav>
        <!-- End of Topbar -->

        <!-- Begin Page Content -->
        <div class="container-fluid" id="app">

          <!-- Page Heading -->
          <div class="d-sm-flex align-items-center justify-content-between mb-4">
            <h1 class="h3 mb-0 text-gray-800">Dashboard</h1>
            <a href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-download fa-sm text-white-50"></i> Generate Report</a>
          </div>
           
          <!-- Content Row -->
          <div class="row">

            <!-- Content Column -->
            <div class="col-lg-3 mb-2">

              <!-- Project Card -->
              <div class="card shadow mb-2">
                <div class="card-header py-3">
                  <h6 class="m-0 font-weight-bold text-primary">BF-12412</h6>
                </div>
                <!-- Content of Card Body -->
                <div class="card-body">
                  <h4 class="small font-weight-bold" >Time Respon <span class="float-right" v-html="timeResp" id="output">0:00:00:00</span></h4> 


                  <h4 class="small font-weight-bold">Time Working <span class="float-right" v-html="timeWork" id="output1">0:00:00:00</span></h4>

                  <!-- Content of Dropdown -->
                  <div class="dropdown mb-4"  >
                    <select class="btn border-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"  aria-expanded="false" style="width: 100%">

                        <option selected = "selected" value="0" >Breakdown</option>
                        <option value="1">Spare Part</option>
                        <option value="2">Electrical</option>
                        <option value="3">Mechanical</option>
                        <option value="4">Periodical</option>
                        <option value="5">Utility</option>
                        <option value="6">Trouble Machine</option>  
                    </select>
                  </div>
                  <!-- End Content of Dropdown -->      

                  <!-- Content of Button -->
                  <div class="mb-2" >  
                    <div class="btn-group btn-group-toggle" data-toggle="buttons">
                      <label class="btn  btn-outline-danger" id="startPause"  v-on:click="kirim('Danger')">
                        <input type="radio" name="options"  autocomplete="off">Report
                      </label>
                      <label class="btn  btn-outline-warning" v-on:click="kirim('Warning')">
                        <input type="radio" name="options" id="option2"  autocomplete="off">Start
                      </label>
                      <label class="btn  btn-outline-success"  id="reset" v-on:click="kirim('Success')">
                        <input type="radio" name="options"  autocomplete="off">Finish
                      </label>
                    </div>
                  </div> 
                  <!-- EndContent of Button --> 
                </div>
                <!-- End Content of Card Body -->
              </div>
              <!-- End of Project Card Example -->             
            </div>
            <!-- End of Content Column -->


            <!-- Content Column -->
            <div class="col-lg-3 mb-2">

              <!-- Project Card -->
              <div class="card shadow mb-2">
                <div class="card-header py-3">
                  <h6 class="m-0 font-weight-bold text-primary">BF-12413</h6>
                </div>
                <!-- Content of Card Body -->
                <div class="card-body container stopwatch">
                  <h4 class="small font-weight-bold">Time Respon 
                    <div class="clock inactive z-depth-1 float-right">
                      <span class="clock inactive z-depth-1 float-right">0:00:00.0</span>
                      <div class="overlay waves-effect"></div>
                    </div>
                  </h4>               

                  <h4 class="small font-weight-bold">Time Working 
                    <div class="clock inactive z-depth-1 float-right">
                      <span class="clock inactive z-depth-1 float-right">0:00:00.0</span>
                      <div class="overlay waves-effect"></div>
                    </div>
                  </h4>

                  <!-- Content of Dropdown -->
                  <div class="dropdown mb-4"  >
                    <select class="btn border-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"  aria-expanded="false" style="width: 100%">

                        <option selected = "selected" value="0">Breakdown</option>
                        <option value="1">Spare Part</option>
                        <option value="2">Electrical</option>
                        <option value="3">Mechanical</option>
                        <option value="4">Periodical</option>
                        <option value="5">Utility</option>
                        <option value="6">Trouble Machine</option>                   
                    </select>
                  </div>
                  <!-- End Content of Dropdown -->      

                  <!-- Content of Button -->
                  <div class="mb-2" >  
                    <div class="btn-group btn-group-toggle" data-toggle="buttons">
                      <label class="btn  btn-outline-danger" id="startPause" onclick="startStopwatch()" >
                        <input type="radio" name="options"  autocomplete="off">Report
                      </label>
                      <label class="btn  btn-outline-warning" onclick="pauseStopwatch()">
                        <input type="radio" name="options" id="option2"  autocomplete="off">Start
                      </label>
                      <label class="btn  btn-outline-success"  id="reset" onclick="resetStopwatch()">
                        <input type="radio" name="options"  autocomplete="off">Finish
                      </label>
                    </div>
                  </div> 
                  <!-- EndContent of Button --> 
                </div>
                <!-- End Content of Card Body -->
              </div>
              <!-- End of Project Card Example -->             
            </div>
            <!-- End of Content Column -->



          </div>
          <!-- End of Content Row -->
        </div>
        <!-- /.container-fluid -->
      </div>
      <!-- End of Main Content -->

      <!-- Footer -->
      <footer class="sticky-footer bg-white">
        <div class="container my-auto">
          <div class="copyright text-center my-auto">
            <span>Copyright &copy; IoT Team v0.91 </span>
          </div>
        </div>
      </footer>
      <!-- End of Footer -->

    </div>
    <!-- End of Content Wrapper -->

  </div>
  <!-- End of Page Wrapper -->

  <!-- Scroll to Top Button-->
  <a class="scroll-to-top rounded" href="#page-top">
    <i class="fas fa-angle-up"></i>
  </a>

  <!-- Logout Modal-->
  <div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
          <button class="close" type="button" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">Ă—</span>
          </button>
        </div>
        <div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
        <div class="modal-footer">
          <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
          <a class="btn btn-primary" href="login.html">Logout</a>
        </div>
      </div>
    </div>
  </div>

 
  <!-- Bootstrap core JavaScript-->
  <script src="vendor/jquery/jquery.min.js"></script>
  <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="js/sb-admin-2.min.js"></script>

  <!-- Dropdown JavaScript-->
  <script src="js/dropdown-admin.js"></script>

  <!-- Timer JavaScript-->
  <script src="js/stopwatch.js"></script>


    <!-- These MUST be in the right order. Note no leading / -->
    <!-- REQUIRED: Socket.IO is loaded only once for all instances
                   Without this, you don't get a websocket connection -->
    <script src="/uibuilder/socket.io/socket.io.js"></script>
    <!-- Note no leading / -->
    <!-- OPTIONAL: JQuery can be removed if not required -->
    <!-- <script src="vendor/jquery/dist/jquery.min.js"></script> -->

    <script src="vendor/vue/dist/vue.js"></script>    <!-- //dev version -->
    <!-- <script src="vendor/moonjs/dist/vue.runtime.min.js"></script>   //prod version -->

    <!-- REQUIRED: Sets up Socket listeners and the msg object -->
    <!-- <script src="uibuilderfe.js"></script>   //dev version -->
    <script src="uibuilderfe.min.js"></script> <!--    //prod version -->
    <!-- OPTIONAL: You probably want this. Put your custom code here -->
    <script src="index.js"></script>


</body>

</html>

index.js

const app1 = new Vue({
    el: "#app",
    data: {
        startMsg    : "Vue has started, waiting for messages",
        feVersion   : '',
        counterBtn  : 0,
        msgsReceived: 0,
        msgsControl : 0,
        msgsSent    : 0,
        msgsTerima  : 0,
        msgRecvd    : '',
        msgResp     : '',
        msgWork     : '',
        msgSent     : '[Nothing]',
        msgCtrl     : '[Nothing]',
        inputText   : ''
    }, // --- End of data --- //
    computed: {
        timeResp2: function() {
            const msgResp = this.msgResp
            if (typeof msgResp === 'string') return msgResp
            else return  this.syntaxHighlight(msgResp.timeResp)
        },

        timeWork: function() {
            const msgWork = this.msgWork
            if (typeof msgWork === 'string') return  msgWork
            else return  this.syntaxHighlight2(msgWork.timeWork)
        },


        hLastSent: function() {
            const msgSent = this.msgSent
            if (typeof msgSent === 'string') return 'Last Message Sent = ' + msgSent
            else return 'Last Message Sent = ' + this.syntaxHighlight(msgSent)
        },
        hMsgCtrl: function() {
            const msgCtrl = this.msgCtrl
            if (typeof msgCtrl === 'string') return 'Last Message Sent = ' + msgCtrl
           //else return 'Last Message Sent = ' + this.callMethod('syntaxHighlight', [msgCtrl])
            else return 'Last Message Sent = ' + JSON.stringify(msgCtrl)
        }
    }, // --- End of computed --- //



    methods: {
        increment: function() {
            // Increment the count by one
            this.counterBtn = this.counterBtn + 1
            let topic = this.msgRecvd.topic || 'uibuilder/vue'
            uibuilder.send( { 'topic': topic, 'payload': { 'type': 'counterBtn', 'btnCount': this.counterBtn, 'message': this.inputText } } )
        },

           //kirim
            kirim: function(kode_mesin){
            let topic = this.msgRecvd.topic || 'uibuilder/vue'
            uibuilder.send({'topic':topic,'payload':{'message':kode_mesin}})
       },

        // return formatted HTML version of JSON object
        syntaxHighlight: function(json) {
            json = JSON.stringify(json, undefined, 4)
            json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
                var cls = 'number'
                if (/^"/.test(match)) {
                    if (/:$/.test(match)) {
                        cls = 'key'
                    } else {
                      cls='string'
                    }
                } else if (/true|false/.test(match)) {
                    cls = 'boolean'
                } else if (/null/.test(match)) {
                    cls = 'null'
                }
                return '<span class="' + cls + '">' + match + '</span>'
            })
        } // --- End of syntaxHighlight --- //


   }, // --- End of methods --- //


    // Available hooks: init,mounted,updated,destroyed
    mounted: function(){
        console.debug('app mounted - setting up uibuilder watchers')

        vueApp = this


        vueApp.feVersion = uibuilder.get('version')

        // If msg changes - msg is updated when a standard msg is received from Node-RED over Socket.IO
        // Note that you can also listen for 'msgsReceived' as they are updated at the same time
        // but newVal relates to the attribute being listened to.
        uibuilder.onChange('msg', function(newVal){
            console.info('property msg changed!', newVal)
            vueApp.msgRecvd = newVal
        })

        uibuilder.onChange('msg', function(newVal){
            console.info('property msg changed!', newVal)
            vueApp.msgResp = newVal
        })

         uibuilder.onChange('msg', function(newVal){
            console.info('property msg changed!', newVal)
            vueApp.msgWork = newVal
        })



        // As noted, we could get the msg here too
        uibuilder.onChange('msgsReceived', function(newVal){
            console.info('New msg sent FROM Node-RED over Socket.IO. Total Count: ', newVal)
            vueApp.msgsReceived = newVal
        })

        // If a message is sent back to Node-RED
        uibuilder.onChange('sentMsg', function(newVal){
            console.info('property sentMsg changed!', newVal)
            vueApp.msgSent = newVal
        })
        uibuilder.onChange('msgsSent', function(newVal){
            console.info('New msg sent TO Node-RED over Socket.IO. Total Count: ', newVal)
            vueApp.msgsSent = newVal
        })

        // If we receive a control message from Node-RED
        uibuilder.onChange('ctrlMsg', function(newVal){
          vueApp.msgCtrl = newVal
        })
        uibuilder.onChange('msgsCtrl', function(newVal){
            console.info('New CONTROL msg sent FROM Node-RED over Socket.IO. Total Count: ', newVal)
            vueApp.msgsControl = newVal
        })

        // If Socket.IO connects/disconnects
        uibuilder.onChange('ioConnected', function(newVal){
            console.info('Socket.IO Connection Status Changed: ', newVal)
            vueApp.socketConnectedState = newVal
        })

    } // --- End of mounted hook --- //

}) // --- End of app1 --- //

// EOF



Thanks, I'll try and take a look later on.

oke thanks

For starters, have you checked that all of your resources are actually loading? Secondly, you are not loading the resources in the recommended order which may also have an impact.

For uibuilder v1, this is the standard set of js resources, please note that some start with / and some with ./

        <!-- These MUST be in the right order. -->
        <script src="/uibuilder/socket.io/socket.io.js"></script>
        <script src="./uibuilderfe.min.js"></script>
        <!-- --- Vendor Libraries - Load in the right order --- -->
        <script src="https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js"></script>
        <script src="./vendor/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
        <script src="./vendor/bootstrap-vue/dist/bootstrap-vue.js"></script>
        <!-- <script src="./vendor/bootstrap-vue/dist/bootstrap-vue.min.js"></script> -->
        <!-- --- Custom code goes in here --- -->
        <script src="./index.js"></script>

Load your other scripts after these (except additional vendor scripts that you probably want to go before index.js), not before. Check your head as well to make sure that the css files are in the right order and all loading.

Also, are you sure you really need jQuery as well as vue? That seems rather overkill.

When I did sort that out - bearing in mind that I don't have all of your scripts - your page killed my browse completely! Haven't had a chance to work out what is going wrong. You might want to temporarily strip out all the extras and just get your timing script working with some really simple html first then we can work out what is happening.

sorry, but my page work well with jQuery.

but i'm still confused with method of .msg
can i get multiple msg.payload from node red?

uibuilder: The main global object containing the following...
 *     Methods:
 *       .onChange(attribute, callbackFn) - listen for changes to attribute and execute callback when it changes
 *       .get(attribute)        - Get any available attribute
 *       .set(attribute, value) - Set any available attribute (can't overwrite internal attributes)
 *       .msg                   - Shortcut to get the latest value of msg. Equivalent to uibuilder.get('msg')
 *       .send(msg)             - Shortcut to send a msg back to Node-RED manually
 *       .debug(true/false)     - Turn on/off debugging
 *       .uiDebug(type,msg)     - Utility function: Send debug msg to console (type=[log,info,warn,error,dir])
 *     Attributes with change events (only accessible via .get method except for msg)
 *       .msg          - Copy of the last msg sent from Node-RED over Socket.IO
 *       .send         - Copy of the last msg sent by us to Node-RED
 *       .ctrlMsg      - Copy of the last control msg received by us from Node-RED (Types: ['shutdown','server connected'])
 *       .msgsReceived - How many standard messages have we received
 *       .msgsSent     - How many messages have we sent
 *       .msgsCtrl     - How many control messages have we received
 *       .ioConnected  - Is Socket.IO connected right now? (true/false)
 *     Attributes without change events
 *           (only accessible via .get method, reload page to get changes, don't change unless you know what you are doing)
 *       .debug       - true/false, controls debug console logging output
 *       ---- You are not likely to need any of these ----
 *       .version     - check the current version of the uibuilder code
 *       .ioChannels  - List of the channel names in use [uiBuilderControl, uiBuilderClient, uiBuilder]
 *       .retryMs     - starting retry ms period for manual socket reconnections workaround
 *       .retryFactor - starting delay factor for subsequent reconnect attempts
 *       .ioNamespace - Get the namespace from the current URL
 *       .ioPath      - make sure client uses Socket.IO version from the uibuilder module (using path)
 *       .ioTransport - ['polling', 'websocket']

You can subscribe to listen for incoming msg's.

For Vue, you do that in the mounted function in your Vue app:

        uibuilder.onChange('msg', function(newVal){
            console.info('[uibuilder.onChange] property msg changed!', newVal)
            vueApp.msgRecvd = newVal
        })

Then inside that listening function, you can check for other properties on the msg object (newVal is the new value of the msg object in the example above) if you are wanting to take different actions depending on the content of the msg received.

So you can feed in as many messages of any number of different types that you like

In addition, there is another special msg type recognised by uibuilder which is a control msg, this is differentiated by the msg.uibuilderCtrl property being set to true (see the inputHandler function in uiblib.js).

        // If we receive a control message from Node-RED
        uibuilder.onChange('ctrlMsg', function(newVal){
            console.info('[uibuilder.onChange] property msgCtrl changed!', newVal)
            vueApp.msgCtrl = newVal
        })

That is used internally by uibuilder but you can also use it, as described in the WIKI, to make sure that new (or reloaded/reconnected) client connections receive some historic or initialisation data from, for example, a cache of data.

To do the same things using jQuery, you - as usual - have to wait for jQuery to be ready and then:

    uibuilder.onChange('msg', function(newVal){
        console.info('property msg changed!')
        console.dir(newVal)
        $('#showMsg').text(JSON.stringify(newVal))
        //uibuilder.set('msgCopy', newVal)
    })

But you really don't need both jQuery and VueJS. I would pick one or the other as it is entirely probable that they are fighting over the same parts of the DOM. If what you need to do works fine with jQuery and that is what you are familiar with, I would strip out the VueJS parts and stick with jQuery. You can add bootstrap to that.

Final part of the answer is that uibuilder.msg isn't generally accessed directly as indicated in the descriptive text. You access it via the listener which fires a function whenever the uibuilder.msg property changes as shown above. uibuilder.msg is there as a convenience in case you need the current value of the msg elsewhere in your processing, it saves you having to manually create a reference to it.

How can I extract the only payload from the full message?

Last Message Received = {
    "_msgid": "e0f4f64c.d2a048",
    "topic": "uibuilder",
    "payload": 1571305017394
}

I don't need to show topic or _msgid. Please help on that. Thanks

object object2

write in function node after uibuilder node (msg.payload.[yourobject])

I really appreciate your replay. Can you please give me an example flow? I will be really grateful.
Thanks again.
Or you can just modify this flow:

[{"id":"6480930b.81c24c","type":"uibuilder","z":"39ebd91b.6a6e86","name":"","topic":"","url":"moon","fwdInMessages":false,"allowScripts":true,"allowStyles":false,"copyIndex":true,"showfolder":true,"x":730,"y":1300,"wires":[["2ee545ff.33f96a"],["db51f281.e5059"]]},{"id":"b554d170.3d245","type":"inject","z":"39ebd91b.6a6e86","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":1300,"wires":[["e02feac7.807d98"]]},{"id":"2ee545ff.33f96a","type":"debug","z":"39ebd91b.6a6e86","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":950,"y":1280,"wires":[]},{"id":"db51f281.e5059","type":"debug","z":"39ebd91b.6a6e86","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":930,"y":1340,"wires":[]},{"id":"e02feac7.807d98","type":"function","z":"39ebd91b.6a6e86","name":"","func":"var mesin = msg.payload;\nvar status = 1;\nvar breakdown = 1;\nflow.set(\"qc\"+mesin+status, \"storeInFile\");\nmsg.payload = mesin;\nreturn msg;","outputs":1,"noerr":0,"x":570,"y":1300,"wires":[["6480930b.81c24c"]]}]

This example flow to get spesific value object..

Open your uibuilder, click button Increment

this is uibuilder v.2.05

[{"id":"56fbe7c3.bd02b8","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"83160795.d1d578","type":"debug","z":"56fbe7c3.bd02b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":513,"y":258,"wires":[]},{"id":"71a70acb.7cd904","type":"uibuilder","z":"56fbe7c3.bd02b8","name":"","topic":"","url":"uibuilder","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"showfolder":false,"x":330,"y":307,"wires":[["83160795.d1d578","c616cba4.122338","80d63263.6408d"],[]]},{"id":"c616cba4.122338","type":"function","z":"56fbe7c3.bd02b8","name":"get spesific value","func":"var x =  msg.payload.type;\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":535.5,"y":322,"wires":[["61c4ba50.a642d4"]]},{"id":"61c4ba50.a642d4","type":"debug","z":"56fbe7c3.bd02b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":748,"y":325,"wires":[]},{"id":"80d63263.6408d","type":"function","z":"56fbe7c3.bd02b8","name":"get spesific value","func":"var x =  msg.payload.btnCount;\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":375,"wires":[["b446d8b8.832998"]]},{"id":"b446d8b8.832998","type":"debug","z":"56fbe7c3.bd02b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":751,"y":376,"wires":[]}]

Please spend some time playing with Node-RED and JavaScript so that you know how to deal with the basics. There are a number of good tutorials around that don't take long to go through but will give you a good understanding of how to work with variables, objects, etc.

3 Likes

Thanks for your kind advice. I am really new in javascript.
I will follow your advice.
I have created a webpage using Dashboard:


it's working fine. But I just want to switch from Dashboard to uibuilder.
For this, I actually need to display some sensors value dynamically in the webpage. and also insert and retrieve data from the database.
I have tried webchocked but only one data I can send(the same problem, I don't know much about javascript).
By the way, thanks again.