I don't like select
elements with the multiple
attribute, the ones with prop('type')
of select-multiple
. One is always forced to combine keyboard keys together with mouse clicks in order to select options. Plus, it's not easy to make selections on a mobile device.
However, there's this one Vendor's product that uses this form field with so many options that represent user's roles in the system. I thought of making the use of this control easier by adding undo and redo features to it, otherwise user have to refresh the page to load the default values before making and saving their changes. And what better way to manage the state of the select
than to use data attributes.
I added minimal HTML to the page and attached a JavaScript file. Is there a way to simplify the JavaScript?
<select name="userRole" class="user-role" multiple="multiple">
<option>administrator</option>
<option>staff</option>
<option>faculty</option>
<option>angel</option>
<option>moodle</option>
<option>user</option>
</select>
<button class="undo">UNDO</button>
<button class="redo">REDO</button>
And the JavaScript:
var sel = $('select.user-role'),
changeRole = function() {
var that = $(this),
curValue = that.val(),
curUndo = that.data('undo');
curUndo.push( curValue );
that.data( 'undo', curUndo );
},
undo = function() {
var curUndo = sel.data( 'undo' ),
curRedo = sel.data( 'redo' );
if( curUndo.length > 0 ) {
curRedo.push( curUndo.pop() );
sel.data({undo:curUndo,redo:curRedo});
sel.val( curUndo.length ? curUndo.slice(-1)[0] : [] );
}
},
redo = function() {
var curUndo = sel.data( 'undo' ),
curRedo = sel.data( 'redo' );
if( curRedo.length > 0 ) {
curUndo.push( curRedo.pop() );
sel.data({undo:curUndo,redo:curRedo});
sel.val( curUndo.length ? curUndo.slice(-1)[0] : [] );
}
};
sel.on('change', changeRole).change();
$('button.undo').on('click', undo);
$('button.redo').on('click', redo);