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'}}"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.