0

I have a dashboard-style widget container, which contains a header panel. I have several icons in the header panel which implements the following features:

1) collapse widget 2) maximize widget 3) launch widget settings 4) close widget

Item #2 is the one where I'm having trouble. I need to swap out the Maximize icon with a Restore icon when it's clicked.

Using the Collapse behavior as a guide, I can use ng-class to switch icons, however my ng-click will be different because I call a method within the directive.

<div class="widget-header panel-heading">
	<h3 class="panel-title">
		<span class="widget-title" ng-dblclick="editTitle(widget)" ng-hide="widget.editingTitle">{{widget.title}}</span>
		<form action="" class="widget-title" ng-show="widget.editingTitle" ng-submit="saveTitleEdit(widget)">
			<input type="text" ng-model="widget.title" class="form-control">
		</form>
		<span class="label label-primary" ng-if="!options.hideWidgetName">{{widget.name}}</span>
		<span ng-click="removeWidget(widget);" class="glyphicon glyphicon-remove" ng-if="!options.hideWidgetClose"></span>
		<span title="config" ng-click="openWidgetSettings(widget);" class="glyphicon glyphicon-cog" ng-if="!options.hideWidgetSettings"></span>

		<span title="maximize" ng-show="widget.gadgetConfigured" ng-click="maxResizer($event)" class="glyphicon" ng-class="{'glyphicon-resize-full': !widget.maximized, 'glyphicon-plus': widget.maximized}" ></span>

		<span title="collapse" ng-show="widget.gadgetConfigured" ng-click="widget.contentStyle.display = (widget.contentStyle.display === 'none' ? 'block' : 'none')" class="glyphicon" ng-class="{'glyphicon-plus': widget.contentStyle.display === 'none', 'glyphicon-minus': widget.contentStyle.display !== 'none' }"></span>
	</h3>
</div>     

and here is the directive's method to handle Maximize:

      $scope.maxResizer = function (e) {
            // TODO: properly restore the window to original position..      

            var widget = $scope.widget;
            var widgetElm = $element.find('.widget');
            
            var ht_diff = 200;  // height differential            

            widget.setWidth(window.innerWidth);
            $scope.widget.setHeight(window.innerHeight-ht_diff);

            $scope.$emit('widgetChanged', widget);            
            $scope.$apply();
            
            $scope.$broadcast('widgetResized', {
                width: window.innerWidth,
                height: window.innerHeight-ht_diff
            });
            // this will refresh the chart width within the container - 03/30/2015 BM:  
            kendo.resize($(".k-chart"));
                                    
            var pixelHeight = widgetElm.height();

            // kendo chart - refreshes chart height within the container - 03/30/2015 B
            var chart = widgetElm.find('.k-chart').data("kendoChart");
            if (chart != undefined) {
                chart.setOptions({ chartArea: { height: pixelHeight - (pixelHeight * .10) } });
                chart.resize($(".k-chart"));
            }
            widget.maximized = true;
        }

As you can see, I have a property set to true/false widget.contentStyle.maximized.

Can someone help me figure out where I'm going wrong ? That is, the Maximize icon remains, and therefore doesn't change to the plus icon.

3
  • 1
    Where do you set widget.contentStyle.maximized? If that's a boolean, you cannot match it against "true" and "false" as strings, just remove these double quotes. Or better, change your ng-class by a truthy/falthy check: ng-class="{'glyphicon-resize-full': !widget.contentStyle.maximized, 'glyphicon-plus': widget.contentStyle.maximized}" Commented Apr 1, 2015 at 21:33
  • I'm just being an idiot, as usual. It's not widget.contentStyle.maximized . It's just widget.maximized Commented Apr 1, 2015 at 21:52
  • @floribon - your truthy statement makes more sense for angular. that wasn't the final answer, but very helpful. My problem was a real bug. Thank you again for your guidance, as it always helps when i get your opinion. Commented Apr 1, 2015 at 21:54

1 Answer 1

3

I built a simple solution to handle the same UI feature regarding toggling icons depending on state. I didn't use any javascript to handle the actual resized, I used CSS classes to change around positioning styles.

Regarding the $parent part, I had to use it to reference the controller scope because my checks were withing ng-hide and ng-if which creates $scopes, using $parent allows me to make sure I am referencing the controller $scope variables.

In your case, ng-click="maxResizer($event); $parent.ifFullscreen" for example, could make your existing code and the class toggle logic work together.

<a ng-click="$parent.isFullscreen = !$parent.isFullscreen;">
    <i class="glyphicon"
        ng-class="'glyphicon-resize-' + ($parent.fullscreenTable ? 'small' : 'full')"
        tooltip="{{$parent.fullscreenTable ?  'restore' :'fullscreen'}}"
        tooltip-placement="{{$parent.fullscreenTable ? 'left' : 'top'}}"></i>
</a>

I have taken your example code and applied my suggestion to it to give you a live working example. http://plnkr.co/edit/zYq5MtwP54rr2L5IGw4k?p=preview

This is the only line I actually changed

<span title="maximize" ng-show="widget.gadgetConfigured" ng-click="maxResizer($event); widget.contentStyle.maximized = !widget.contentStyle.maximized" class="glyphicon" ng-class="'glyphicon-resize-' + (widget.contentStyle.maximized ? 'small' : 'full')" ></span>
Sign up to request clarification or add additional context in comments.

6 Comments

@bob can you check the Plunker in my updated. Let me know if this gives you any insight into a solution for your UX design. I left out the actual resizing because I believe you have that working. I focused on toggling the icon.
@bob Just seen your comment about updating the browsers Title value while maximized. In this case I think either a simple Controller $scope method or even a directive could handle this. What you would do is store all the state in the "widget" $scope variable, which I assume is in a ng-repeat. You would use this object in the method that handles updating the UI in the way you desire. Let me know if you would like to see a demo of each
@bob I always recommend KISS, with that to handle the title, I would add $rootScope into your controller, and within your maxResizer method change the variable inside $rootScope for the title, sample can be expressed here stackoverflow.com/questions/12506329/…
Sorry, I meant the span title. What I mean is this <span title="collapse" ... > as opposed to <span title="restore" ...>
You would do something such as title="{{widget.contentStyle.maximized ? 'collapse' : 'maximize'}}"
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.