diff --git a/README.md b/README.md index 9c979cb..9a7313b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A react component for simple straightforward rating manipulation gif: - + ###Installation --- @@ -24,12 +24,13 @@ Font-Awesome 4: `` +Half stars with Font-Awesome 4: +`` Glyphicons: `` - Others: The component assumes the icon is contained inside an tag, fill the class names in accordingly. Do note, that you can pass additional classes to the IconRating for styling purposes. @@ -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 diff --git a/index.js b/index.js index 34c5a6d..63eadec 100644 --- a/index.js +++ b/index.js @@ -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}) ); } }); @@ -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 }); }, @@ -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 ) ); } diff --git a/index.jsx b/index.jsx index 9b068a4..e5d2419 100644 --- a/index.jsx +++ b/index.jsx @@ -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 ( - + ); } }); @@ -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 }); }, @@ -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( - + 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( + ); } return ( - {currentRating} + {ratings} ); }