Firstly, I must apologize if the title is poorly constructed. I'm struggling to try to consolidate all the valid points into a brief enough title. If you can think of a better alternative, please feel free to edit.
The Problem
I've created a JavaScript/jQuery alternative to the poorly supported <datalist>
HTML5 element and for the most part I'm happy with how it has turned out.
It all works, but one problem I have with special RegExp
characters, is that I'm not too sure how I can escape them so that I'm not being given errors in the console.
Characters in particular that I want to escape are (
, )
and /
. I know that in JavaScript regular expressions, you should use a backslash to escape these characters, but of the attempts I've tried thus far, the code stops working completely so clearly I'm not doing something right.
I am just wondering how I could implement the escaping into my current code? You can see from the commented-out lines some other methods I've tried.
The Error
The input works and displays the games correctly. However, if you select one of the Grand Theft Auto V
options from the jsFiddle and then go to backspace on the parentheses, the console will throw this error:
Uncaught SyntaxError: Invalid regular expression: /Grand Theft Auto V (PC/: Unterminated group
The Code
Live preview: jsFiddle
JavaScript/jQuery:
$('#game-name').keyup( function() {
var input = $('#game-search');
var offset = input.offset();
var game_name = $("#game-search").val();
// List
function show() {
$('#game-list').css({
'display': 'inline-block',
'left': offset.left,
'min-width': input.outerWidth(),
'top': offset.top + input.outerHeight()
});
}
function hide() {
$('#game-list').css({
'display': 'none',
'left': offset.left,
'min-width': input.outerWidth(),
'top': offset.top + input.outerHeight()
});
}
if (game_name.length >= 1) {
show();
}
else {
hide();
}
// Filter
var regexp = new RegExp( game_name, "i" );
//var regexp = new RegExp(/[A-Za-z0-9_()\/]/, "i");
// [A-Za-z0-9_()\/]
$("#game-list ul").children("li").each(function(index) {
if (game_name.length < 1) {
$(this).addClass('reset').removeClass('match no-match');
}
else {
//if (/[A-Za-z0-9_()\/]/i.test( $(this).html() )) {
if (regexp.test( $(this).html() )) {
$(this).addClass('match').removeClass('no-match reset');
} else {
$(this).addClass('no-match').removeClass('match reset');
}
}
});
// Apply
$('#game-list ul li').click( function() {
$('#game-search').val( $(this).attr('value') );
$('#game-list').css('display', 'none');
});
});
HTML:
<input type="text" id="game-search">
<div id="game-list">
<ul>
<li class="" value="BeamNG.drive" data-series="BeamNG.drive">BeamNG.drive</li>
<li class="" value="Crash Bandicoot: N. Sane Trilogy" data-series="Crash Bandicoot">Crash Bandicoot: N. Sane Trilogy</li>
<li class="" value="Grand Theft Auto V (PC)" data-series="Grand Theft Auto">Grand Theft Auto V (PC)</li>
<li class="" value="Grand Theft Auto V (PS3/PS4)" data-series="Grand Theft Auto">Grand Theft Auto V (PS3/PS4)</li>
<li class="" value="Grand Theft Auto V (X360/XBO)" data-series="Grand Theft Auto">Grand Theft Auto V (X360/XBO)</li>
<li class="" value="Project CARS" data-series="Project CARS">Project CARS</li>
<li class="" value="Project CARS 2" data-series="Project CARS">Project CARS 2</li>
<li class="" value="Subnautica" data-series="Subnautica">Subnautica</li>
</ul>
</div>
Thank you.