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.

bob.mazzo
  • 5,183
  • 23
  • 80
  • 149
  • 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}"` – floribon Apr 01 '15 at 21:33
  • I'm just being an idiot, as usual. It's not `widget.contentStyle.maximized` . It's just `widget.maximized` – bob.mazzo Apr 01 '15 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. – bob.mazzo Apr 01 '15 at 21:54

1 Answers1

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>
Mason Mize
  • 211
  • 1
  • 5
  • @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. – Mason Mize Apr 01 '15 at 22:18
  • @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 – Mason Mize Apr 01 '15 at 22:21
  • @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 http://stackoverflow.com/questions/12506329/how-to-dynamically-change-header-based-on-angularjs-partial-view – Mason Mize Apr 01 '15 at 22:23
  • Sorry, I meant the span title. What I mean is this `` as opposed to `` – bob.mazzo Apr 01 '15 at 22:26
  • 1
    You would do something such as `title="{{widget.contentStyle.maximized ? 'collapse' : 'maximize'}}"` – Mason Mize Apr 01 '15 at 22:29
  • Awesome ! I tried something like that, but I was using the ng-class format - and not the proper ternary expression. THANKS. – bob.mazzo Apr 01 '15 at 22:33