Skip to content

Commit

Permalink
support 1/2 ratings
Browse files Browse the repository at this point in the history
  • Loading branch information
Daryl Lau committed Mar 9, 2014
1 parent 2c77d01 commit 6530cba
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 28 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A react component for simple straightforward rating manipulation

gif:

![gif](http://i.imgur.com/4fjlj5h.gif)
![gif](http://i.imgur.com/wXPHAul.gif)

###Installation
---
Expand All @@ -24,12 +24,13 @@ Font-Awesome 4:

`<IconRating toggledClassName="fa fa-star" untoggledClassName="fa fa-star-o"/>`

Half stars with Font-Awesome 4:
`<IconRating toggledClassName="fa fa-star" untoggledClassName="fa fa-star-o" halfClassName="fa fa-star-half-o" />`

Glyphicons:

`<IconRating toggledClassName="glyphicon glyphicon-star" untoggledClassName="glyphicon glyphicon-star-empty"/>`


Others:
The component assumes the icon is contained inside an <i> tag, fill the class names in accordingly.
Do note, that you can pass additional classes to the IconRating for styling purposes.
Expand All @@ -41,5 +42,9 @@ Pass an `onChange` property to the component. It takes a function of with parame
//number is the rating the user has clicked
}

###Browser Compatibility
---
Out of the box, shouldn't have issues with an exception of the half stars. Calculation for div quadrant may not work in some browsers. Please file an issue!

###License
MIT
34 changes: 21 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ var Icon = React.createClass({displayName: 'Icon',
var iStyle = {
cursor : 'pointer'
};
var className =
(this.props.className ? this.props.className + ' ' : '') +
(this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName)
;
var className = this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName;
return (
React.DOM.i( {className:className, onMouseEnter:this.props.onMouseEnter, style:iStyle, onClick:this.props.onClickRating})
React.DOM.i( {className:className, onMouseMove:this.props.onMouseEnter, style:iStyle, onClick:this.props.onClickRating})
);
}
});
Expand All @@ -26,8 +23,12 @@ var IconRating = React.createClass({displayName: 'IconRating',
};
},
onMouseEnter : function(currentRating, e, id){
var rating = currentRating;
if((e.nativeEvent.clientX) < (e.target.offsetLeft + (e.target.offsetWidth / 2))){
rating -= .5;
}
this.setState({
currentRating_hover : currentRating,
currentRating_hover : rating,
hovering : true
});
},
Expand All @@ -38,24 +39,31 @@ var IconRating = React.createClass({displayName: 'IconRating',
},
onClickRating : function(currentRating, e, id){
this.setState({
currentRating : currentRating
currentRating : this.state.currentRating_hover
});
if(this.props.onChange){
this.props.onChange(currentRating);
}
},
render: function() {
var currentRating = [];
var toggled = false;
var ratings = [];
var toggled = false, rating, halfClassName;
for(var i=1;i<=this.state.max;++i){
toggled = i <= this.state['currentRating' + (this.state.hovering ? '_hover':'')] ? true : false;
currentRating.push(
Icon( {key:i, toggledClassName:this.props.toggledClassName, untoggledClassName:this.props.untoggledClassName, onMouseEnter:this.onMouseEnter.bind(this,i), onClickRating:this.onClickRating.bind(this,i), toggled:toggled} )
rating = this.state['currentRating' + (this.state.hovering ? '_hover':'')];
toggled = i <= Math.round(rating) ? true : false;
halfClassName = null;
if(this.props.halfClassName &&
Math.round(rating) == i &&
Math.floor(rating) != rating){
halfClassName = this.props.halfClassName;
}
ratings.push(
Icon( {key:i, toggledClassName:halfClassName || this.props.toggledClassName, untoggledClassName:this.props.untoggledClassName, onMouseEnter:this.onMouseEnter.bind(this,i), onClickRating:this.onClickRating.bind(this,i), toggled:toggled})
);
}
return (
React.DOM.div( {onMouseLeave:this.onMouseLeave},
currentRating
ratings
)
);
}
Expand Down
34 changes: 21 additions & 13 deletions index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ var Icon = React.createClass({
var iStyle = {
cursor : 'pointer'
};
var className =
(this.props.className ? this.props.className + ' ' : '') +
(this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName)
;
var className = this.props.toggled ? this.props.toggledClassName : this.props.untoggledClassName;
return (
<i className={className} onMouseEnter={this.props.onMouseEnter} style={iStyle} onClick={this.props.onClickRating}/>
<i className={className} onMouseMove={this.props.onMouseEnter} style={iStyle} onClick={this.props.onClickRating}/>
);
}
});
Expand All @@ -26,8 +23,12 @@ var IconRating = React.createClass({
};
},
onMouseEnter : function(currentRating, e, id){
var rating = currentRating;
if((e.nativeEvent.clientX) < (e.target.offsetLeft + (e.target.offsetWidth / 2))){
rating -= .5;
}
this.setState({
currentRating_hover : currentRating,
currentRating_hover : rating,
hovering : true
});
},
Expand All @@ -38,24 +39,31 @@ var IconRating = React.createClass({
},
onClickRating : function(currentRating, e, id){
this.setState({
currentRating : currentRating
currentRating : this.state.currentRating_hover
});
if(this.props.onChange){
this.props.onChange(currentRating);
}
},
render: function() {
var currentRating = [];
var toggled = false;
var ratings = [];
var toggled = false, rating, halfClassName;
for(var i=1;i<=this.state.max;++i){
toggled = i <= this.state['currentRating' + (this.state.hovering ? '_hover':'')] ? true : false;
currentRating.push(
<Icon key={i} toggledClassName={this.props.toggledClassName} untoggledClassName={this.props.untoggledClassName} onMouseEnter={this.onMouseEnter.bind(this,i)} onClickRating={this.onClickRating.bind(this,i)} toggled={toggled} />
rating = this.state['currentRating' + (this.state.hovering ? '_hover':'')];
toggled = i <= Math.round(rating) ? true : false;
halfClassName = null;
if(this.props.halfClassName &&
Math.round(rating) == i &&
Math.floor(rating) != rating){
halfClassName = this.props.halfClassName;
}
ratings.push(
<Icon key={i} toggledClassName={halfClassName || this.props.toggledClassName} untoggledClassName={this.props.untoggledClassName} onMouseEnter={this.onMouseEnter.bind(this,i)} onClickRating={this.onClickRating.bind(this,i)} toggled={toggled}/>
);
}
return (
<div onMouseLeave={this.onMouseLeave}>
{currentRating}
{ratings}
</div>
);
}
Expand Down

0 comments on commit 6530cba

Please sign in to comment.