Input filter/mask/length restrictions

HTML

<input   id="inputEmail" placeholder="Email" type="email">

CSS

input {
    width: 300px;
}

JavaScript

var nthOccurrence = function(string, selector, n) {
    var positions = [];
    string.replace(new RegExp(selector, 'g'), function(match, pos) {
        positions.push(pos);
    });
    return typeof positions[n - 1] !== 'undefined' ? positions[n - 1] : -1;
}

$('input').on('input', function() {
    if (!$(this).data('filter') && !$(this).data('mask') && !$(this).data('length')) return;
    
    var val = [
        $(this).val().substr(0, this.selectionStart),
        $(this).val().substr(this.selectionEnd)
    ];
    var caretPos = val[0].length;
    
    if ($(this).data('filter')) {    
        var filter = new RegExp('[^' + $(this).data('filter') + ']', 'g');
        for (var i = 0; i < val.length; i++) {
            val[i] = val[i].replace(filter, '');
        }
        if ($(this).data('mask')) caretPos = val[0].length;
    }
    val = val.join('');
    
    if ($(this).data('mask')) {
        var mask = $(this).data('mask');
        var newVal = mask;
        for (var i = 0; i < val.length; i++) {
            newVal = newVal.replace('_', val[i]);
        }
        caretPos = (nthOccurrence(mask, '_', caretPos) > -1 ? nthOccurrence(mask, '_', caretPos) + 1 : mask.length);
        if (!val) caretPos = mask.indexOf('_');
        val = newVal;
    }
    
    if ($(this).data('length')) {
        val = val.substr(0, $(this).data('length'));
    }
    $(this).val(val)[0].setSelectionRange(caretPos, caretPos);
});