Need something simple, light and elegant
Often developers need controls that help to do 5 point(or fixed scale) rating for feedback activities. While smart looking controls are available none are ready-to-use. Pagination controls are good substitute but they end up being just buttons stacked horizontal, clobbering your design. Bending progress bars to do this job is also a freaky idea but it would eventually fall apart when you need to load too many of these or perhaps you need the bar to show controlled animation.
“Makeshifts” fall apart, cracks begin to show when all you need is a lightweight control that can let the user rate on a fixed scale. User having clicked on the option scale, the control should respond by altering the rating and with also a geometrical plot that indicates the rating given.
Argument then could be , Why not have “plain vanilla ice cream” radio boxes and close the issue ?
Radio boxes are a good lightweight option, but then vanilla ice creams not very elegant are they ?
D3.js to the rescue
Why not hand roll a control to make it do exactly what we want. After all D3 offers the lowest of all functions that can help us generate basic geometrical elements. Angular can support us on packing that as a directive.
scope.$apply() for where you are binding variables from outside Angular
D3 would create the geometrical elements on suitable scale, including the clickable options (text most probably). Result is the change in the selected rating would happen outside Angular’s purview. As such cases can be easily handled with .$apply() . The digest cycle needs to run through the entire scope chain to see that there is change on the variable attached to the scope.
scope.$watch() for handling the graphics change
The $watch( ) is a nice place where you can handle any alteration of the selected rating. Here is the flow of action
- User clicks on the d3 geometrical element(mostly text)
- d3 event delegates handle the click and send the index , content of the element being clicked [Refer to this line in the code Reference to the line of code
- Index of the clicked element helps to change the value of the selected rating. .. here $apply() would help the scope to be aware of the change
- Watch fires with newValue and oldValue respectively that can then in turn make the animated change to the rating bar.
- Styling changes for the option text element also can follow.