Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[habpanel] Sliders in modals disappear, then appear again later #218

Closed
eikowagenknecht opened this issue Apr 14, 2020 · 8 comments
Closed

Comments

@eikowagenknecht
Copy link
Contributor

eikowagenknecht commented Apr 14, 2020

Mostly a follow-up to openhab/org.openhab.ui.habpanel#244 and may also be connected to openhab/org.openhab.ui.habpanel#353. But since the repo seems to have moved I'm opening a new issue here.

How to reproduce:
Create a custom widget with @ghys demo code from: https://community.openhab.org/t/habpanel-development-advanced-features-start-here/30755

<script type="text/ng-template" id="myModalContent.html">
    <div class="container" style="padding: 30px; border: 1px solid #456;">
      <a ng-click="$close()" class="pull-right btn btn-danger">X</a>
      <h3 style="color: white">All Lights</h3>
        <ul ng-repeat="light in itemsInGroup('Lights')" ng-init="models={}">
            <li class="col-md-4"
                ng-init="models[light.name] = { name: light.label, item: light.name, step: 1 }">
                <div class="box" style="height: 150px; margin: 10px">
                    <widget-slider ng-model="models[light.name]"></widget-slider>
                </div>
            </li>
        </ul>
    </div>
</script>
<button class="btn btn-default btn-lg"
        ng-click="openModal('myModalContent.html', true, 'lg')">
  Open Modal
</button>

Click the button.

Expected: Slider appears and stays there.

What happens: Slider appears for some milliseconds, then disappears and after quite some time (varies from seconds to minutes). The reappearing seems to happen the instant any event (of some unrelated item) is fired.

@eikowagenknecht
Copy link
Contributor Author

As a workaround I'm using this:

Template:

<div oc-lazy-load="[
                   '/static/matrix-theme/js/lights.js',
                   ]">

lights.js:

(function() {
	"use strict";

	angular.module('app', [])
	.controller('myController', ['$scope', '$timeout', 'OHService', function($scope, $timeout, OHService) {
		
		// Needed to refresh slider after showing parent element (popup)
		$scope.refreshSlider = function () {
			console.log("Refreshing slider");
			$timeout(function () {
				$scope.$broadcast('rzSliderForceRender');
				//$scope.$broadcast('openhab-update'); // Seems to do nothing in this context
				OHService.sendCmd("Dummy_Switch", OHService.getItem("Dummy_Switch").state === "ON" ? "OFF" : "ON");
			});
		};
	}]); 
})();

Dummy.items:
Switch Dummy_Switch "Switch needed to trigger HABPanel update"

Widget template:
ng-click="<...>; refreshSlider()"

This is obviously a horrible and very hacky workaround, but at least I can dim my lights for now.

@ghys
Copy link
Member

ghys commented Apr 14, 2020

Thank you for investigating; it's true that openhab-update doesn't necessarily refresh now.
Then I suppose it's a matter of adding $scope.$broadcast('rzSliderForceRender'); around there:

$timeout(function () {
$rootScope.$broadcast('openhab-update');
OHService.reloadItems();
});
});
}

Can you do a PR?

@eikowagenknecht
Copy link
Contributor Author

I'd like to try if this works. How can I modify my local installation to test this before I do a PR? Unfortunately I haven't come to setting up an OH build environment (yet).

@ghys
Copy link
Member

ghys commented Apr 14, 2020

@eikowagenknecht
Copy link
Contributor Author

Great post, thanks! For the official modal, adding $scope.$broadcast('rzSliderForceRender') does not help unfortunately. What does help is removing the line OHService.reloadItems(). But I'm not sure if that has any side effects. What do you think?

@eikowagenknecht
Copy link
Contributor Author

On a side note, my originally intended use case was a bit different. I'm using a custom popup instead of the official modal:

<div class="widget" ng-if="light.type==='Group' && light.groupType==='Dimmer' && getLightState(light)==='OFF'" >
          <div class="icon off" ng-click="sendCmd(light.name, 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
              </div>
            </div>
          </div>
        </div>

There implementing this helped (see onclick event where the popup is shown):

		// Needed to refresh slider after showing parent element (popup)
		$scope.refreshSlider = function () {
			//console.log("Refreshing slider");
			$timeout(function () {
				//$scope.$broadcast('openhab-update'); // Does not work
				$scope.$emit('openhab-update'); // Seems to work
			});
		};

@ghys
Copy link
Member

ghys commented Apr 19, 2020

$scope.$emit('openhab-update'); // Seems to work

If you're positive then we can probably add this to the openModal function in template.widget.js instead of OHService.reloadItems().

@eikowagenknecht
Copy link
Contributor Author

I think $scope.$emit('openhab-update') is not even needed there, just removing OHService.reloadItems() is enough. I created a PR for this (#236). $scope.$emit('openhab-update') is only needed in a custom controller.

ghys pushed a commit that referenced this issue Apr 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants