views:

401

answers:

1

I've already looked at this, which was helpful to a point.

Here's the problem. I have a list of users propagated into an element via user click; something like this:

<div id="box">
    joe-user
    page-joe-user
    someone-else
    page-someone-else
</div>

On click, I want to make sure that the user has not already been clicked into the div. So, I'm doing something like:

if ( ! $('#box').html().match(rcpt) )
{
   update_div();
}
else
{
   alert(rcpt+' already exists.');
}

However, with existing lack of interpolation that javascript has for regular expressions, is causing my alert to trigger in the use-case where page-joe-user is selected and then the user selects joe-user, which are clearly not exactly the same.

In Perl I would do something like:

if ( $rcpt =~ /^\Qrcpt\E/ )
{
    # code
}

All I want to do is change my match() to be:

if ( ! $('#box').html().match(/^rcpt/) )
{
    # code
}

if ( ! $('#box').html().match(rcpt) ) seemed a little promising but it, too, fails. Using new RegExp() also does not work using concatenation of complex RE syntax within the function IE $('#box').html().match(new RegExp('^'+rcpt)). I also tried $('#box').html().match('/^'+rcpt'/'). I can only imagine that I'm missing something. I'm pretty new to javascript.

I don't seem to be able to find anything that really addresses such a use-case, here on this site.

TIA

+1  A: 

The match function only works on strings, not jQuery objects.

The best way to do this is to put each username into a separate HTML tag.

For example:

<ul id="users">
    <li>joe-user</li>
    <li>page-joe-user</li>
    <li>someone-else</li>
    <li>page-someone-else</li>
</ul>

You can then write the following:

if($('#users li').is(function () { return $(this).text() === rcpt; }))

If you want to do it your way, you should call text() to get the string inside the element. ($('#box').text().match(...))


EDIT: The best way to do this using your HTML would be to split the string.

For example:

var userExists = false;
var users = $('#box').text().split(/\r?\n/);

for(var i = 0; i < users.length; i++) {   //IE doesn't have indexOf
    if (users[i] == rcpt) {
        userExists = true;
        break;
    }
}
if (userExists) {
    //Do something
}

This has the added benefit of not being vulnerable to regex-injection.

SLaks
`rcpt` isn't actually an object in my code. It's just a variable. However, I'm considering your response as a way to work around this.
Jim
If `rcpt` is a variable, just remove the quotes. Note that this is case sensitive. If you don't want that, call `toUpperCase`.
SLaks
Well, see, that is exactly what I did. However, the problem is that match() is confusing `joe-user` with `page-joe-user`. So, to replicate the problem...Using `page-joe-user` and `joe-user` for example:`$('#element').html().match(rcpt)` mostly works but if I click in `page-joe-user` first and then try and click in `joe-user` then match() triggers a match when they are, in fact, not (or don't want them to be). If I click them in the reverse order then all works well. So, to mitigate, I want to anchor my regex since this looks like typical regex greediness.
Jim
And I want to apologize. I see that I confused a crucial point that I'm match()'ing html.
Jim
There we go. That is a better solution and I've implemented it. Works well. Thank you.
Jim