Custom widget, events on div + background change [solved]


(Tom Pe) #1

I’m struggling to get a simple button to work. Since I need to send commands at mousedown and mouseup events I thought why not make my own. My web development skills are limited, but I assume it is just some simple mistakes in the html/css.

So I managed to get basic functionality to work even with js and a controller in the background. However, click events only work on the backdrop icon or a paragraph. How would I change the html to send click events clicking anywhere on the widget.

Secondly, setting the background color is a mess. If I hard code it, it only appears behind the text and if I try to connect it to a javascript variable it doesn’t do anything at all


This is my html:

<div oc-lazy-load="['/static/touchbutton-widget/touchbutton_ctrl.js']" >
	<div class="box-content switch" ng-controller="TouchbuttonCtrl as vm"
       ng-style="{ 'background-color': 'vm.background', color: 'vm.foreground' }"
       ng-click="vm.sendCommand_click()" ng-mousedown="vm.sendCommand_mousedown()" ng-mouseup="vm.sendCommand_mouseup()" >
    <widget-icon ng-if="config.backdrop_icon" backdrop="true" iconset="config.backdrop_icon_iconset" icon="config.backdrop_icon" center="config.backdrop_center"></widget-icon>
    <p>Debug: {{vm.message}}</p>
	</div>
</div>

And this is the javascript file:

(function() {
  'use strict';
  angular
    .module('app.widgets')
    .controller('TouchbuttonCtrl', touchbuttonCtrl);

  touchbuttonCtrl.$inject = ['$scope', 'OHService'];
  function touchbuttonCtrl($scope, OHService) {
    var vm = this;

    vm.background = $scope.config['background_inactive'];
    vm.foreground = $scope.config['foreground'];
    //$scope.message = "Hello World";
    vm.message = "Hello world";

    OHService.onUpdate($scope, $scope.config['item'], function() {
        var item = OHService.getItem($scope.config['item']);
        if (item.state == 'ON') {
            vm.background = $scope.config['background_active'];
        } else if (item.state = 'OFF'){
            vm.background = $scope.config['background_inactive'];
        } else {
            vm.message = "State unknown";
        }
    });

    vm.sendCommand_click = function() {
        var item = OHService.getItem($scope.config['item']);
        //OHService.sendCmd(item.name, "Clicked");
    }
    vm.sendCommand_mousedown = function() {
        var item = OHService.getItem($scope.config['item']);
        OHService.sendCmd(item.name, 'ON');
    }
    vm.sendCommand_mouseup = function() {
        var item = OHService.getItem($scope.config['item']);
        OHService.sendCmd(item.name, 'OFF');
    }
  }
})();

(Tom Pe) #2

Ok, after lots of try and error I finally figured it out myself.
The div on the lazy-load shrunk the size/area, this had effect on both the event and the background problem.
Following a working example, make sure you have all config set up: name [string], background_active [color], background_inactive [color], foreground [color], backdrop_icon [icon], backdrop_center [checkbox], item [item].
The javascript file needs to be placed in /etc/openhab2/html/touchbutton-widget/touchbutton_ctrl.js, then in Habpanel edit a dashboard and instead of inserting a widget click on custom widgets and create a new one. Copy paste the html and setup all config variables. You should now have a small working example of a custom widget with an angularjs controller.

HTML

<style>
  .box-full-size {
  	width: 100%;
  	height: 100%;
  }
  .box-list {
  	vertical-align: middle;
    padding-left: 0;
  }
</style>

<div class="box-full-size" oc-lazy-load="['/static/touchbutton-widget/touchbutton_ctrl.js']" >
  <div class="box-content switch" ng-controller="TouchbuttonCtrl as vm"
       ng-style="{ 'background-color': vm.background, color: vm.foreground }"
       ng-click="vm.sendCommand_click()" ng-mousedown="vm.sendCommand_mousedown()" ng-mouseup="vm.sendCommand_mouseup()" >
    <widget-icon ng-if="config.backdrop_icon" backdrop="true" iconset="config.backdrop_icon_iconset" icon="config.backdrop_icon" center="config.backdrop_center"></widget-icon>
    <ul class="box-list switch-content">
      <li><p>Debug: {{vm.message}}</p></li>
    	<li><div class="switch-content ng-scope">
    		<span class="ng-binding" ng-style="{ 'font-size': vm.font_size + 'pt' }" style="font-size: 20pt;">{{vm.name}}</span>
    	</div></li>
    </ul>
	</div>
</div>

Javascript

(function() {
  'use strict';
  angular
    .module('app.widgets')
    .controller('TouchbuttonCtrl', touchbuttonCtrl);

  touchbuttonCtrl.$inject = ['$scope', 'OHService'];
  function touchbuttonCtrl($scope, OHService) {
    var vm = this;

    vm.name = $scope.config['name'];
    vm.background = $scope.config['background_inactive'];
    vm.foreground = $scope.config['foreground'];
    //$scope.message = "Hello World";
    vm.message = "Hello world";

    // Register callback for changes on our item state
    OHService.onUpdate($scope, $scope.config['item'], function() {
        var item = OHService.getItem($scope.config['item']);
        if (item.state == 'ON') {
            vm.background = $scope.config['background_active'];
        } else if (item.state = 'OFF'){
            vm.background = $scope.config['background_inactive'];
        } else {
            vm.message = "State unknown";
        }
    });

    vm.sendCommand_click = function() {
        var item = OHService.getItem($scope.config['item']);
        //OHService.sendCmd(item.name, "Clicked");
    }

    vm.sendCommand_mousedown = function() {
        var item = OHService.getItem($scope.config['item']);
        OHService.sendCmd(item.name, 'ON');
        vm.message = "Mousedown";
    }

    vm.sendCommand_mouseup = function() {
        var item = OHService.getItem($scope.config['item']);
        OHService.sendCmd(item.name, 'OFF');
        vm.message = "Mouseup";
    }
  }
})();