@@ -3200,7 +3200,8 @@ angular.module('patternfly.validation', []).directive('pfValidation', ["$timeout
32003200 * Directive for rendering a data list.
32013201 * <br><br>
32023202 *
3203- * @param {object } config configuration settings for the data list:<br/>
3203+ * @param {array } items Array of items to display in the list
3204+ * @param {object } config Configuration settings for the data list:
32043205 * <ul style='list-style-type: none'>
32053206 * <li>.showSelectBox - (boolean) Show item selection boxes for each item, default is true
32063207 * <li>.selectItems - (boolean) Allow row selection, default is false
@@ -3216,28 +3217,35 @@ angular.module('patternfly.validation', []).directive('pfValidation', ["$timeout
32163217 * <li>.onClick - ( function(item, event) ) Called to notify when an item is clicked, default is none
32173218 * <li>.onDblClick - ( function(item, event) ) Called to notify when an item is double clicked, default is none
32183219 * </ul>
3219- *
3220- * @param {Array } items the data to be shown in the data list<br/>
3221- *
3220+ * @param {array } actions List of actions for dropdown menu in each row
3221+ * <ul style='list-style-type: none'>
3222+ * <li>.name - (String) The name of the action, displayed on the button
3223+ * <li>.title - (String) Optional title, used for the tooltip
3224+ * <li>.actionFn - (function(action)) Function to invoke when the action selected
3225+ * <li>.isVisible - (Boolean) set to true to disable the action
3226+ * <li>.isDisabled - (Boolean) set to true to disable the action
3227+ * <li>.isSeparator - (Boolean) set to true if this is a placeholder for a separator rather than an action
3228+ * </ul>
3229+ * @param {function (action, item)) } updateActionForItemFn function(action, item) Used to update an action based on the current item
32223230 * @example
32233231<example module="patternfly.views" deps="patternfly.utils">
32243232 <file name="index.html">
3225- <div ng-controller="ViewCtrl" class="row" style="display:inline-block; width: 100%; ">
3226- <div class="col-md-12">
3227- <div pf-data-list id="exampleDataList" config="config" items="items">
3228- <div class="col-md-12 cfme- row-column ">
3229- <div class="col-lg-3 col- md-3 col-sm-3 col-xs-3 list-column ">
3230- <span>{{item.name}}</span>
3231- </div>
3232- <div class="col-lg-3 col- md-3 col-sm-3 col-xs-3 list-column ">
3233- <span>{{item.address}}</span>
3234- </div>
3235- <div class="col-lg-3 col- md-3 col-sm-3 col-xs-3 list-column ">
3236- <span>{{item.city}}</span>
3237- </div>
3238- <div class="col-lg-3 col- md-3 col-sm-3 col-xs-3 list-column ">
3239- <span>{{item.state}}</span>
3240- </div>
3233+ <div ng-controller="ViewCtrl" class="row example-container ">
3234+ <div class="col-md-12 list-view-container ">
3235+ <div pf-data-list class="example-data-list" id="exampleDataList" config="config" items="items" actions="actions ">
3236+ <div class="row">
3237+ <div class="col-md-3">
3238+ <span>{{item.name}}</span>
3239+ </div>
3240+ <div class="col-md-3">
3241+ <span>{{item.address}}</span>
3242+ </div>
3243+ <div class="col-md-3">
3244+ <span>{{item.city}}</span>
3245+ </div>
3246+ <div class="col-md-3">
3247+ <span>{{item.state}}</span>
3248+ </div>
32413249 </div>
32423250 </div>
32433251 </div>
@@ -3369,36 +3377,144 @@ angular.module('patternfly.validation', []).directive('pfValidation', ["$timeout
33693377 state: "Pennsylvania"
33703378 },
33713379 {
3372- name: "Judy Green",
3373- address: "2 Apple Boulevard",
3374- city: "Cincinatti",
3375- state: "Ohio"
3380+ name: "Linda McGovern",
3381+ address: "22 Oak Street",
3382+ city: "Denver",
3383+ state: "Colorado"
3384+ },
3385+ {
3386+ name: "Jim Beam",
3387+ address: "72 Bourbon Way",
3388+ city: "Nashville",
3389+ state: "Tennessee"
3390+ },
3391+ {
3392+ name: "Holly Nichols",
3393+ address: "21 Jump Street",
3394+ city: "Hollywood",
3395+ state: "California"
3396+ },
3397+ {
3398+ name: "Marie Edwards",
3399+ address: "17 Cross Street",
3400+ city: "Boston",
3401+ state: "Massachusetts"
33763402 },
33773403 {
33783404 name: "Pat Thomas",
33793405 address: "50 Second Street",
33803406 city: "New York",
33813407 state: "New York"
33823408 },
3383- ]
3409+ ];
3410+
3411+ var performAction = function (action, item) {
3412+ $scope.eventText = item.name + " : " + action.name + "\n" + $scope.eventText;
3413+ };
3414+
3415+ $scope.actions = [
3416+ {
3417+ name: 'Action',
3418+ title: 'Perform an action',
3419+ actionFn: performAction
3420+ },
3421+ {
3422+ name: 'Another Action',
3423+ title: 'Do something else',
3424+ actionFn: performAction
3425+ },
3426+ {
3427+ name: 'Disabled Action',
3428+ title: 'Unavailable action',
3429+ actionFn: performAction,
3430+ isDisabled: true
3431+ },
3432+ {
3433+ name: 'Something Else',
3434+ title: '',
3435+ actionFn: performAction
3436+ },
3437+ {
3438+ isSeparator: true
3439+ },
3440+ {
3441+ name: 'Grouped Action 1',
3442+ title: 'Do something',
3443+ actionFn: performAction
3444+ },
3445+ {
3446+ name: 'Grouped Action 2',
3447+ title: 'Do something similar',
3448+ actionFn: performAction
3449+ }
3450+ ];
33843451 }
33853452 ]);
33863453 </file>
33873454</example>
33883455 */
3389- angular . module ( 'patternfly.views' ) . directive ( 'pfDataList' , [ "pfUtils" , function ( pfUtils ) {
3456+ angular . module ( 'patternfly.views' ) . directive ( 'pfDataList' ,
3457+ [ "$timeout" , "$window" , "pfUtils" , function ( $timeout , $window , pfUtils ) {
33903458 'use strict' ;
33913459 return {
33923460 restrict : 'A' ,
33933461 scope : {
33943462 config : '=?' ,
33953463 items : '=' ,
3396- eventId : '@id'
3464+ actions : '=?' ,
3465+ updateActionForItemFn : '=?'
33973466 } ,
33983467 transclude : true ,
33993468 templateUrl : 'views/datalist/data-list.html' ,
3400- controller : [ '$scope' ,
3401- function ( $scope ) {
3469+ controller :
3470+ [ "$scope" , "$element" , function ( $scope , $element ) {
3471+ var setDropMenuLocation = function ( parentDiv ) {
3472+ var dropButton = parentDiv . querySelector ( '.dropdown-toggle' ) ;
3473+ var dropMenu = parentDiv . querySelector ( '.dropdown-menu' ) ;
3474+ var buttonRect = dropButton . getBoundingClientRect ( ) ;
3475+ var menuRect = dropMenu . getBoundingClientRect ( ) ;
3476+ var top = buttonRect . top + buttonRect . height ;
3477+ var left = buttonRect . left + buttonRect . width - menuRect . width ;
3478+ var docHeight = $window . innerHeight ;
3479+
3480+ if ( top + menuRect . height > docHeight ) {
3481+ top = docHeight - menuRect . height ;
3482+ }
3483+
3484+ dropMenu . style . top = top + "px" ;
3485+ dropMenu . style . left = left + "px" ;
3486+ } ;
3487+
3488+ var hideOnScroll = function ( ) {
3489+ $scope . prevMenuItem . showMenu = false ;
3490+ angular . element ( angular . element ( $element ) . find ( '.data-list-pf' ) [ 0 ] ) . unbind ( "scroll" , hideOnScroll ) ;
3491+ angular . element ( $window ) . unbind ( "scroll" , hideOnScroll ) ;
3492+ $scope . $apply ( ) ;
3493+ } ;
3494+
3495+ var showActionMenu = function ( item , event ) {
3496+ item . showMenu = true ;
3497+ $scope . prevMenuItem = item ;
3498+
3499+ $timeout ( function ( ) {
3500+ var parentDiv = undefined ;
3501+ var nextElement ;
3502+
3503+ nextElement = event . toElement ;
3504+ while ( nextElement && ! parentDiv ) {
3505+ if ( nextElement . className . indexOf ( 'list-menu' ) === 0 ) {
3506+ parentDiv = nextElement ;
3507+ setDropMenuLocation ( parentDiv ) ;
3508+ }
3509+ nextElement = nextElement . parentElement ;
3510+ }
3511+
3512+ angular . element ( angular . element ( $element ) . find ( '.data-list-pf' ) [ 0 ] ) . bind ( "scroll" , hideOnScroll ) ;
3513+ angular . element ( $window ) . bind ( "scroll" , hideOnScroll ) ;
3514+ } ) ;
3515+
3516+ } ;
3517+
34023518 $scope . defaultConfig = {
34033519 selectItems : false ,
34043520 multiSelect : false ,
@@ -3421,8 +3537,40 @@ angular.module('patternfly.views').directive('pfDataList', ["pfUtils", function
34213537 'Illegal use of pfDataList directive! ' +
34223538 'Cannot allow both select box and click selection in the same data list.' ) ;
34233539 }
3424- }
3425- ] ,
3540+
3541+ $scope . handleAction = function ( action , item ) {
3542+ if ( action && action . actionFn && ( action . isDisabled !== true ) ) {
3543+ action . actionFn ( action , item ) ;
3544+ }
3545+ } ;
3546+
3547+ $scope . updateActions = function ( item ) {
3548+ $scope . actionItem = item ;
3549+ if ( typeof $scope . updateActionForItemFn === 'function' ) {
3550+ $scope . actions . forEach ( function ( action ) {
3551+ $scope . updateActionForItemFn ( action , item ) ;
3552+ } ) ;
3553+ }
3554+ } ;
3555+
3556+ $scope . setupActions = function ( item , event ) {
3557+ if ( $scope . prevMenuItem ) {
3558+ $scope . prevMenuItem . showMenu = false ;
3559+ $scope . prevMenuItem = undefined ;
3560+ }
3561+
3562+ // Ignore disabled items completely
3563+ if ( $scope . checkDisabled ( item ) ) {
3564+ return ;
3565+ }
3566+
3567+ // update the actions based on the current item
3568+ $scope . updateActions ( item ) ;
3569+
3570+ // Show the action menu for the item
3571+ showActionMenu ( item , event ) ;
3572+ } ;
3573+ } ] ,
34263574
34273575 link : function ( scope , element , attrs ) {
34283576 attrs . $observe ( 'config' , function ( ) {
@@ -3713,7 +3861,8 @@ angular.module('patternfly.views').directive('pfDataList', ["pfUtils", function
37133861 </file>
37143862 </example>
37153863 */
3716- angular . module ( 'patternfly.views' ) . directive ( 'pfDataTiles' , [ "pfUtils" , function ( pfUtils ) {
3864+ angular . module ( 'patternfly.views' ) . directive ( 'pfDataTiles' ,
3865+ [ "pfUtils" , function ( pfUtils ) {
37173866 'use strict' ;
37183867 return {
37193868 restrict : 'A' ,
@@ -3902,8 +4051,8 @@ angular.module('patternfly.views').directive('pfDataTiles', ["pfUtils", function
39024051 <label class="events-label">Valid Items: </label>
39034052 </div>
39044053 <div class="col-md-12 list-view-container" ng-if="viewType == 'listView'">
3905- <div pf-data-list class="row" config="listConfig" items="items">
3906- <div class="row list-row ">
4054+ <div pf-data-list config="listConfig" items="items">
4055+ <div class="row">
39074056 <div class="col-md-3">
39084057 <span>{{item.name}}</span>
39094058 </div>
@@ -4423,7 +4572,7 @@ angular.module('patternfly.views').directive('pfDataToolbar',
44234572 'use strict' ;
44244573
44254574 $templateCache . put ( 'views/datalist/data-list.html' ,
4426- "<div class=data-list-pf><div class=list-group-item ng-repeat=\"item in items track by $index\" ng-class=\"{'pf-selectable': selectItems, 'active': isSelected(item), 'disabled': checkDisabled(item)}\"><div class=\"row list-row\"><div pf-transclude=parent class=list-content ng-class=\"{'with-check-box': config.showSelectBox, 'with-menu':config.showActionMenus}\" ng-click=\"itemClick($event, item)\" ng-dblclick=\"dblClick($event, item)\"></div><div class=list-check-box ng-if=config.showSelectBox style=\"padding-top: {{(config.rowHeight - 32) / 2}}px\"><input type=checkbox value=item.selected ng-model=item.selected ng-disabled=checkDisabled(item) ng-change=\"checkBoxChange(item)\"></div></div></div></div>"
4575+ "<div class=data-list-pf><div class=list-group-item ng-repeat=\"item in items track by $index\" ng-class=\"{'pf-selectable': selectItems, 'active': isSelected(item), 'disabled': checkDisabled(item)}\"><div class=list-row><div pf-transclude=parent class=list-content ng-class=\"{'with-check-box': config.showSelectBox, 'with-menu':actions && actions.length > 0}\" ng-click=\"itemClick($event, item)\" ng-dblclick=\"dblClick($event, item)\"></div><div class=list-check-box ng-if=config.showSelectBox style=\"padding-top: {{(config.rowHeight - 32) / 2}}px\"><input type=checkbox value=item.selected ng-model=item.selected ng-disabled=checkDisabled(item) ng-change=\"checkBoxChange(item)\"></div><div class=\"list-menu dropdown btn-group {{$index}}\" ng-if=\"actions && actions.length > 0\" ng-class=\"{'disabled': checkDisabled(item)}\"><button type=button class=\"btn btn-link dropdown-toggle\" data-toggle=dropdown aria-haspopup=true aria-expanded=false ng-click=\"setupActions(item, $event)\"><span class=\"fa fa-ellipsis-v\"></span></button><ul class=dropdown-menu ng-if=item.showMenu><li ng-repeat=\"action in actions\" ng-if=\"action.isVisible !== false\" role=\"{{action.isSeparator === true ? 'separator' : 'menuitem'}}\" ng-class=\"{'divider': (action.isSeparator === true), 'disabled': (action.isDisabled === true)}\"><a ng-if=\"action.isSeparator !== true\" href=# title={{action.title}} ng-click=\"handleAction(action, item)\">{{action.name}}</a></li></ul></div></div></div></div>"
44274576 ) ;
44284577
44294578
0 commit comments