我正在使用angular-rating-icons生成恒星系统。
<div class="rating-filter">
<h4>{{'Rating: '|translate}} {{filter.ratings}}</h4>
<div data-angular-rating-icons
ng-model="filter.ratings" color-base="orange"
on-change="fn()"></div>
</div>
我希望获得关于每颗星星的工具提示,类似于uib-tooltip
中的实现方法。
<div class="btn-group">
<button type="button" class="btn btn-price" uib-tooltip="₹0 - ₹500" ng-click="applyFilter(1)">$</button>
<button type="button" class="btn btn-price" uib-tooltip="₹500 - ₹1000" ng-click="applyFilter(2)">$$</button>
<button type="button" class="btn btn-price" uib-tooltip="₹1000 - ₹5000" ng-click="applyFilter(3)">$$$</button>
<button type="button" class="btn btn-price" uib-tooltip="₹5000+" ng-click="applyFilter(4)">$$$$</button>
</div>
我似乎无法弄清楚这一点,因为angular-rating-icons
接受String
以确定哪个图标用于评级系统,即icon-full="fa-star"
而不是传递{{1} }对象。而且我似乎无法针对单个恒星,因为它们被生成为最小CSS。
我尝试覆盖<div>
的CSS,但这似乎也不是很好。有没有办法在每个按钮的悬停上显示工具提示?
JSFiddle:https://jsfiddle.net/y4b1skdw/1/
您可能必须将代码段的.fa-star
击至Load Type
才能加载插件。
答案 0 :(得分:1)
问:有没有办法在每个按钮的悬停上显示工具提示?
A :是-我们将工具提示类添加到<li ng-repeat="icon in icons track by $index">
...,并且此<li>
元素重复了10次,每颗星重复两次
以下是您的工具提示的代码段,并在CSS中添加了工具提示类
var app = angular.module("myApp", []);
app.directive('angularRating', function() {
return {
replace: true,
require: 'ngModel',
scope: {
ngModel: '=',
onChangeFunction: '&onChange'
},
template: '' +
'<ul ng-class="[listClass, decimal]">' +
'<li ng-repeat="icon in icons track by $index" class="tooltip"' +
'ng-style="getListItemStyle($index)" ' +
'ng-click="setValue($index)" ' +
'ng-mouseenter="paintIcons($index)" ' +
'ng-mouseleave="resetIcons()" ' +
'>' +
'<span class="tooltiptext">sample Tooltip text for {{$index}}</span>' +
'<i ng-class="getClass($index)" ng-style="getIconStyle($index)"></i>' +
'</li>' +
'</ul>',
link: function(scope, element, attrs, controller) {
// Settings
scope.icons = new Array(+attrs.max || 5);
scope.value = controller.$viewValue || (+attrs.defaultValue || 0);
scope.size = +attrs.iconSize || 20;
scope.spacing = +attrs.iconSpacing || 5;
scope.listClass = 'angular-rating-icons';
scope.readOnly = !(attrs.readonly === undefined);
scope.decimal = !(attrs.decimal === undefined) ? 'angular-rating-icons-decimal' : undefined;
// Colors
var colorBase = attrs.colorBase || 'black';
var colorSelected = attrs.colorSelected || 'orange';
var colorHover = attrs.colorHover || 'orange';
// Different states
var iconBase = attrs.iconBase || 'fa';
var iconEmpty = attrs.iconEmpty || 'fa-star-o';
var iconFull = attrs.iconFull || 'fa-star';
var iconHover = attrs.iconHover || 'fa-star';
// Model
controller.$render = function() {
scope.value = controller.$viewValue === 0 ? 0 : controller.$viewValue || scope.value;
// update model safeguard/fallback should it not be initialized before
controller.$setViewValue(scope.value);
};
/**
* Returns the appropriate class for the icon.
* Changes if it's meant to be full or empty.
* All indexes above the given value will be empty, all bellow or equal will be full.
*
* @param {int} index - the icon's index
* @return {string} - the icon class to use
*/
scope.getClass = function(index) {
return iconBase + ' ' + (index >= scope.value ? iconEmpty : iconFull);
};
/**
* Returns the appropriate style for the icon's color.
* Changes if it's meant to be full or empty.
* If it's decimal type, modifies the style to reduce the icon size by 2px, and move the odd index icons
* half of their size minus 2, to the left.
*
* @param {int} index - the icon's index
* @return {Object} - the icon style to use
*/
scope.getIconStyle = function(index) {
var css = {
color: index >= scope.value ? colorBase : colorSelected
};
if (!scope.decimal) {
return css;
}
css.height = scope.size - 2 + 'px';
css.width = scope.size - 2 + 'px';
css.left = index % 2 ? '-' + (scope.size - 2) / 2 + 'px' : '';
return css;
};
/**
* Returns the appropriate style fo the list item's font-size and padding-right.
* If it's decimal type, modifies the style to reduce the height and width by 2 px, and the only the width
* by half of that result. Also for every even index it removes the right padding.
*
* @param {int} index - the list item's index
* @return {object} - the list item's style to use
*/
scope.getListItemStyle = function(index) {
var css = {
'font-size': scope.size + 'px',
'padding-right': index !== scope.icons.length - 1 ? scope.spacing + 'px' : '0'
};
if (!scope.decimal) {
return css;
}
css.height = scope.size - 2 + 'px';
css.width = (scope.size - 2) / 2 + 'px';
if (!(index % 2)) {
css['padding-right'] = '0';
}
return css;
};
/**
* Doesn't run if set to readonly.
* Sets the directive's scope value to the clicked icon plus 1.
* List item's indexes go from 0 to 9, whilst real values should go from 1 to 10.
* Sets the model's value to the directive's scope value.
* Runs the onChangeFunction function.
*
* @param {int} index - the clicked icon's index
*/
scope.setValue = function(index) {
if (scope.readOnly) {
return;
}
controller.$setViewValue(scope.value = index + 1);
scope.onChangeFunction();
};
/**
* Runs the paintIcon function to paint the icons only up to the current scope value - 1,
* since the indexes range from 0 to 9 but the real values range from 1 to 10.
*/
scope.resetIcons = function() {
scope.paintIcons(scope.value - 1, true);
};
/**
* Doesn't run if set to readonly.
* Changes the icon's classes accordingly to their index.
* Cycles all the icons, and if the current index is smaller than the cycle number, it gives the icon the
* empty class, otherwise gives it the hover class and sets the color to the hover color.
* If reset is true, the above first case scenario also sets the color to the base color, and the second
* adds the class full and paints with the selected color instead.
*
* @param {int} index - the clicked icon's index
* @param {boolean} reset - if icon's paint should be reset
*/
scope.paintIcons = function(index, reset) {
if (scope.readOnly) {
return;
}
var items = element.find('li').find('i');
for (var i = 0; i < items.length; i++) {
var icon = angular.element(items[i]);
if (index >= i) {
icon.removeClass(iconEmpty)
.addClass(reset ? iconFull : iconHover)
.css('color', reset ? colorSelected : colorHover);
} else {
icon.removeClass(iconFull)
.addClass(iconEmpty)
.css('color', reset ? colorBase : icon.css('color'));
}
if (reset && iconHover !== iconFull) {
icon.removeClass(iconHover);
}
}
};
}
};
});
app.controller("MyCtrl", ['$scope', function($scope) {
$scope.maxValue = 10;
$scope.fn = function() {
if ($scope.rating.value === 10) {
$scope.callbackText = 'This text was changed through the callback function! ' +
'And it was validated to say "YOU\'RE AWESOME" ' +
'if the value was 10!';
return;
}
$scope.callbackText = 'The new rating is ' + $scope.rating.value + '. ' +
'This text was changed through a callback function! ' +
'Try hitting the max value star!';
}
}]);
.angular-rating-icons {
text-align: left;
display: inline-block;
padding: 0;
list-style: none;
}
.angular-rating-icons>li {
display: inline-block;
padding: 0;
cursor: pointer;
}
.angular-rating-icons-decimal>li {
overflow: hidden;
position: relative;
}
.angular-rating-icons-decimal>li>i {
position: absolute;
}
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
/* Position the tooltip */
position: fixed;
font-size: 14px;
margin-top: 45px;
z-index: 1;
}
.tooltip:hover .tooltiptext {
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://use.fontawesome.com/2bd9c462bc.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<h3>Hello, Superhero!</h3>
<div>Rating: {{rating.value}}</div>
<div data-angular-rating ng-model='rating.value' max={{maxValue}} default-value=2 icon-empty="fa-star-o" icon-full="fa-star" icon-hover="fa-star" color-base="black" color-selected="orange" color-hover="orange" icon-size="50" on-change="fn()" decimal></div>
<div>{{callbackText}}</div>
</div>
</div>