custom templates master
custom templates

--- a/assets/js/iotcc.js
+++ b/assets/js/iotcc.js
@@ -98,7 +98,7 @@
             logger.log('Received Topic:= ' + topic + '\n\tMessage:= ' + message.toString());
 
             if (topicPath[4] == 'config') {
-                var page = {'pageId': json.pageId, 'pageName': json.pageName, 'icon': json.icon};
+                var page = {'pageId': json.pageId, 'pageName': json.pageName, 'icon': json.icon, 'order': json.pageOrder};
                 iotCC.addPage(page);
                 var publishTopic = json.publishTopic ? json.publishTopic : json.topic + '/data';
                 if (json.widget == 'toggle') {
@@ -165,7 +165,7 @@
                     if ($('span[name="' + widgetId + '"]').exists() == false) {
                         html = '';
                         if (json.widget == 'data-control') html += '<button name="' + widgetId + '" data-widget="' + json.widget + '" data-action="-" class="button button--material btn-xs {class10}">-</button> ';
-                        html += '<span name="' + widgetId + '" data-widget="' + json.widget + '" data-value="' + json.value + '" class="text {class11}">' + json.value + '</span> ' + (json.valuedescription?'<span class="text {class12}">' + json.valuedescription + '</span>':'') + '';
+                        html += (json.valueprepend?'<span class="text {class12}">' + json.valueprepend + '</span>':'') + ' <span name="' + widgetId + '" data-widget="' + json.widget + '" data-value="' + json.value + '" class="text {class11}">' + json.value + '</span> ' + (json.valueappend?'<span class="text {class13}">' + json.valueappend + '</span>':'');
                         if (json.widget == 'data-control') html += ' <button name="' + widgetId + '" data-widget="' + json.widget + '" data-action="+" class="button button--material btn-xs {class13}">+</button>';
                         json.content = html;
                         json.widgetId = widgetId;
@@ -173,7 +173,7 @@
                         json.callback = function() {
                             var action = $(this).data('action');
                             var value = $('span[name="' + $(this).attr('name') + '"]').data('value');
-                            value = action == '+' ? iotCC.formatData(value, json.format) + 1 : iotCC.formatData(value, json.format) - 1;
+                            value = action == '+' ? (iotCC.formatData(value, json.format) + 1) : (iotCC.formatData(value, json.format) - 1);
                             var message = '{"value":"' + value + '"}';
                             iotCC.mqttClient.publish(publishTopic, message, {qos: 1, retained: false});
                             if (iotCC.mqttConfig.debug) {
@@ -280,6 +280,7 @@
         }
     },
     addHtml: function(json, html) {
+        html = '<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}" data-template="{template}">' + html + '</div>';
         html = this.parseTemplate(json, html);
         var section = $('section.content').filter('[data-section="dashboard"]');
         // TODO: add after sort ?
@@ -304,7 +305,7 @@
     },
     addPage: function(page) {
         $('label').filter('[data-pagination="0"]').parent().removeClass('hide');
-        if ($('div').filter('[data-page="' + page.pageId + '"]').exists() == false) {
+        if (page.pageId && $('div').filter('[data-page="' + page.pageId + '"]').exists() == false) {
             var html = '<div class="row page" data-page="' + page.pageId + '" data-order="' + page.order + '"></div>';
             var hidePageContainer = false;
             if ($('label').filter('[data-pagination="0"]').find('input').prop('checked') == false) {
@@ -332,7 +333,7 @@
                 }).appendTo('section.content[data-section="dashboard"]');
             }
         }
-        if ($('div.pagination').find('label').filter('[data-pagination="' + page.pageId + '"]').exists() == false) {
+        if (page.pageId && $('div.pagination').find('label').filter('[data-pagination="' + page.pageId + '"]').exists() == false) {
             var html = '<label class="tab-bar__item tab-bar--material__item" data-pagination="' + page.pageId + '" data-order="' + page.order + '">';
             html += '<input type="radio" name="tab-bar-material-a">';
             html += '<button class="tab-bar__button tab-bar--material__button">';
@@ -412,12 +413,13 @@
     animate: function(element) {
         element.fadeTo("fast", 0.33 ).fadeTo("fast", 1);
     },
-    formatData: function(v, f, d) {
+    formatData: function(v, f, d = 2) {
         if (f == 'int') {
             return parseInt(v);
         } else if (f == 'float') {
             return parseFloat(v).toFixed(d);
         }
+        return parseInt(v);
     },
     parseTemplate: function(json, html, debug) {
         html = html.replace('{content}', json.content);
@@ -435,6 +437,7 @@
         $('.subscriptions-table').find('tr').remove();
         for (i in config.customSubscriptions) {
             var subscription = config.customSubscriptions[i];
+            if (subscription == null) continue;
             var html = '<tr>';
             html += '<td><a href="#" class="btn fa fa-edit"></a><a href="#" class="btn fa fa-remove"></a></td>';
             html += '<td>' + i + '</td>';
@@ -483,6 +486,8 @@
         $('.templates-table').find('tr').remove();
         for (i in config.customTemplates) {
             var template = config.customTemplates[i];
+            iotCC.templates[template.title] = template.templateHtml;
+            if (template == null) continue;
             var html = '<tr>';
             html += '<td><a href="#" class="btn fa fa-edit"></a><a href="#" class="btn fa fa-remove"></a></td>';
             html += '<td>' + i + '</td>';
@@ -490,6 +495,7 @@
             html += '<td>' + template.active + '</td>';
             html += '</tr>';
             $('.templates-table').append(html);
+            $('#subscriptionTemplate').append('<option value="' + i + '">' + template.title + '</option>');
         }
         $('.templates-table').find('a.fa-edit').click(function(e) {
             e.preventDefault();
@@ -500,6 +506,7 @@
             var config = JSON.parse(localStorage.getItem('iotCCConfig')) || {};
             var data = config.customTemplates || [];
             $('textarea[name="templateHtml"]').val( data[$(tr).find('td:eq(1)').html()].templateHtml );
+            $('textarea[name="templateCallback"]').val( data[$(tr).find('td:eq(1)').html()].templateCallback );
             $("#templateHtml").trigger('keyup');
             iotCC.clearSession();
         });
@@ -681,6 +688,10 @@
         }
     });
 
+    $('#subscriptionTemplate').change(function(){
+        $('#widgetJson').trigger('keyup');
+    });
+
     $('#widgetJson').keyup(function() {
         $('.subscriptionWidgetJson-html').remove();
         var val = $('#widgetJson').val();
@@ -693,7 +704,7 @@
         } else {
             return;
         }
-        if (json.template) {
+        /*if (json.template) {
             $.ajaxSetup({ cache: false });
             $.get('assets/template/' + json.template + '.html', function(html) {
                 html = iotCC.parseTemplate(json, html, true);
@@ -702,7 +713,16 @@
                 $('.box-body.widget-preview').find('.widgetcontainer').replaceWith(template);
                 $('#widgetCodePreview').val(template.trim());
             });
-        }
+        }*/
+        var config = JSON.parse(localStorage.getItem('iotCCConfig')) || {};
+        var data = config.customTemplates || [];
+        config.customTemplates = data;
+        var html = config.customTemplates[$('#subscriptionTemplate').val()].templateHtml;
+        html = iotCC.parseTemplate(json, html, true);
+        $('.box-body.widget-preview').html(html);
+        var template = $('.box-body.widget-preview').find('.widgetcontainer').html();
+        $('.box-body.widget-preview').find('.widgetcontainer').replaceWith(template);
+        $('#widgetCodePreview').val(template.trim());
     });
 
     $('button.beautify').click(function() {

--- a/assets/template/template-1.html
+++ b/assets/template/template-1.html
@@ -1,11 +1,10 @@
-<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}" data-template="{template}">
-    <div class="info-box {class}">
-        <span class="info-box-icon {class4}"><i class="{icon}"></i></span>
-        <div class="info-box-content {class2}">
-            <span class="info-box-text {class1}">{title}</span>
-            <span class="{class3}">
-                {content}
-            </span>
-        </div>
+<div class="info-box {class}">
+    <span class="info-box-icon {class4}"><i class="{icon}"></i></span>
+    <div class="info-box-content {class2}">
+        <span class="info-box-text {class1}">{title}</span>
+        <span class="{class3}">
+            {content}
+        </span>
     </div>
 </div>
+

--- a/assets/template/template-2.html
+++ b/assets/template/template-2.html
@@ -1,10 +1,9 @@
-<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}" data-template="{template}">
-    <div class="box box-solid {class}">
-        <div class="box-header {class3}">
-            <h3 class="box-title {class1}">{title}</h3>
-        </div>
-        <div class="box-body {class2}">
-            {content}
-        </div>
+<div class="box box-solid {class}">
+    <div class="box-header {class3}">
+        <h3 class="box-title {class1}">{title}</h3>
+    </div>
+    <div class="box-body {class2}">
+        {content}
     </div>
 </div>
+

--- a/assets/template/template-3.html
+++ b/assets/template/template-3.html
@@ -1,11 +1,10 @@
-<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}" data-template="{template}">
-    <div class="small-box {class}">
-        <div class="inner {class3}">
-            <h3 class="{class1}">{title}</h3>
-            <p class="{class2}">{content}</p>
-        </div>
-        <div class="icon">
-            <i class="{icon}"></i>
-        </div>
+<div class="small-box {class}">
+    <div class="inner {class3}">
+        <h3 class="{class1}">{title}</h3>
+        <p class="{class2}">{content}</p>
+    </div>
+    <div class="icon">
+        <i class="{icon}"></i>
     </div>
 </div>
+

--- a/assets/template/template-4.html
+++ b/assets/template/template-4.html
@@ -1,11 +1,10 @@
-<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}" data-template="{template}">
-    <div class="box {class}">
-        <div class="box-header with-border {class3}">
-            <h3 class="box-title {class1}">{title}</h3>
-            <div class="box-tools pull-right {icon}"></div>
-        </div>
-        <div class="box-body {class2}">
-            {content}
-        </div>
+<div class="box {class}">
+    <div class="box-header with-border {class3}">
+        <h3 class="box-title {class1}">{title}</h3>
+        <div class="box-tools pull-right {icon}"></div>
+    </div>
+    <div class="box-body {class2}">
+        {content}
     </div>
 </div>
+

file:a/index.html -> file:b/index.html
--- a/index.html
+++ b/index.html
@@ -51,12 +51,12 @@
                 </li>
                 <li>
                     <a href="#" class="navigation" data-section="custom-subscriptions">
-                        <i class="fa fa-list"></i> <span>Custom subscriptions</span>
+                        <i class="fa fa-list"></i> <span>Subscriptions</span>
                     </a>
                 </li>
                 <li>
                     <a href="#" class="navigation" data-section="custom-templates">
-                        <i class="fa fa-code"></i> <span>Custom templates</span>
+                        <i class="fa fa-code"></i> <span>Templates</span>
                     </a>
                 </li>
                 <li>
@@ -83,16 +83,16 @@
         </section>
 
         <section class="content-header hide" data-section="custom-subscriptions">
-            <h1>Custom subscriptions</h1>
+            <h1>Subscriptions</h1>
             <ol class="breadcrumb">
-                <li class="active"><i class="fa fa-list"></i> Custom subscriptions</li>
+                <li class="active"><i class="fa fa-list"></i> Subscriptions</li>
             </ol>
         </section>
 
         <section class="content-header hide" data-section="custom-templates">
-            <h1>Custom templates</h1>
+            <h1>Templates</h1>
             <ol class="breadcrumb">
-                <li class="active"><i class="fa fa-code"></i> Custom templates</li>
+                <li class="active"><i class="fa fa-code"></i> Templates</li>
             </ol>
         </section>
 
@@ -177,11 +177,27 @@
                                         <option value="doughnut" data-action="on">Doughnut chart</option>
                                     </select>
                                 </div>
+                                <div class="form-group">
+                                    <label for="subscriptionTemplate">Template</label>
+                                    <select class="form-control" name="subscriptionTemplate" id="subscriptionTemplate">
+                                        <option>-- select template --</option>
+                                    </select>
+                                </div>
                                 <div class="form-group subscriptionWidgetJson">
-                                    <label for="widgetJson">IoTCC Config</label>
+                                    <label for="widgetJson">Widget JSON</label>
                                     <textarea class="form-control" id="widgetJson" name="widgetJson" placeholder="Widget JSON" rows="10"></textarea>
                                     <button type="button" class="btn btn-primary beautify">Beautify JSON</button>
                                     <span class="help-block widgetJson"></span>
+                                    <span class="help-block widgetJson2">This is the JSON object the IoT device will send to IoT Control Center</span>
+                                </div>
+                                <div class="form-group subscriptionCallback">
+                                    <label for="subscriptionCallback">Callback</label>
+                                    <textarea class="form-control" id="subscriptionCallback" name="subscriptionCallback" placeholder="Subscription callback" rows="10">
+
+
+return json;
+                                    </textarea>
+                                    <span class="help-block subscriptionCallback">This callback is called after receiving a message and is json decoded. You have to `return json;` variabile</span>
                                 </div>
                                 <div class="form-group subscriptionAction hide">
                                     <label for="publishTopic">Widget publish topic</label>
@@ -282,6 +298,11 @@
                                     <textarea class="form-control" id="templateHtml" name="templateHtml" placeholder="Template HTML" rows="10"></textarea>
                                     <span class="help-block templateHtml"></span>
                                 </div>
+                                <div class="form-group templateCallback">
+                                    <label for="templateCallback">Callback</label>
+                                    <textarea class="form-control" id="templateCallback" name="templateCallback" placeholder="Template Callback" rows="10"></textarea>
+                                    <span class="help-block templateCallback">This callback is called after the widget is rendered. You can use json, widgetId variables and also jQuery to interact with the template<br />You don't have to return anything.</span>
+                                </div>
                                 <div class="checkbox">
                                     <label for="active2">
                                     <input type="checkbox" id="active2" name="active" /> Activate
@@ -456,9 +477,9 @@
 
     <footer class="main-footer">
         <div class="pull-right hidden-xs">
-            <b>Version</b> 0.3
+            <b>Version</b> 0.5
         </div>
-        <strong>Copyright &copy; 2017 <a href="http://www.razvi.ro">Razvan Stanga</a>.</strong> All rights reserved.
+        <strong>Copyright &copy; 2019 <a href="http://www.razvi.ro">Razvan Stanga</a>.</strong> All rights reserved.
     </footer>
 
     <aside class="control-sidebar control-sidebar-dark">
@@ -514,3 +535,4 @@
 
 </body>
 </html>
+

comments