0

I am implementing jQuery chaining - using Mika Tuupola's Chained plugin - in my rails project (using nested form_for partials) and need to dynamically change the chaining attribute:

The code that works without substitution:

$(".employee_title_2").remoteChained({
  parents : ".employee_title_1",
  url : "titles/employee_title_2",
  loading : "Loading...",
  clear : true
});

The attributes being substituted are .employee_title_1 and .employee_title_2:

var t2 = new Date().getTime();
var A1 = ".employee_title_1A_" + t2;
var B2 = ".employee_title_2B_" + t2;

In ruby speak, I'm namespacing the variables by adding datetime.

Here's the code I'm using for on-the-fly substitution:

$(`"${B2}"`).remoteChained({
  parents : `"${A1}"`,
  url : "titles/employee_title_2",
  loading : "Loading...",
  clear : true
});

Which throws this error:

Uncaught Error: Syntax error, unrecognized expression: 
  ".employee_title_2B_1462463848339"

The issue appears to be the leading '.' How do I escape it, assuming that's the issue? Researching the error message Syntax error, unrecognized expression lead to SO question #14347611 - which suggests "a string is only considered to be HTML if it starts with a less-than ('<) character" Unfortunately, I don't understand how to implement the solution. My javascript skills are weak!

Incidentally, while new Date().getTime(); isn't in date format, it works for my purpose, i.e., it increments as new nested form fields are added to the page

Thanks in advance for your assistance.

2
  • Is the code that you're using for "on-the-fly" substitution in a .js file or a .js.erb template? Or something else altogether? Commented May 6, 2016 at 6:01
  • It's between <script><\script tags at the bottom of a html.erb (ROR) file Commented May 6, 2016 at 17:38

2 Answers 2

1
$(`"${B2b}"`).remoteChained({
// ^      ^
// These quotes should not be here

As it is evaluated to a string containing something like:

 ".my_class"

and to tie it together:

 $('".my_class"')...

Same goes for the other place you use backtick notation. In your case you could simply use:

$(B2).remoteChained({
  parents : A1,
  url : "titles/employee_title_2",
  loading : "Loading...",
  clear : true
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for responding. However, my code needs both the '.' and the " " (double quotes) to prevent to aforementioned error. Without the quotes, I get the error; without the period, chaining doesn't work. The chaining is initiated by <div><%= title_fields.select :employee_title_1, options_for_select(@employee_title_1s, title_fields.object.employee_title_1), {}, { class: "A1 form-control btn-default", code: "employee_title_1" } %></div> The class: A1 is the relevant code.
The '.' / class syntax is from Mika Tuupola's jQuery Chained plugin.
1

The back tick (``) syntax is new for Javascript, and provides a templating feature, similar to the way that Ruby provides interpolated strings. For instance, this Javascript code:

var who = "men";
var what = "country";
var famous_quote = `Now is the time for all good ${who} to come to the aid of their #{what}`;

is interpolated in exactly the same way as this Ruby code:

who = "men"
what = "country"
famous_quote = "Now is the time for all good #{who} to come to the aid of their #{what}"

In both cases, the quote ends up reading, "Now is the time for all good men to come to the aid of their country". Similar feature, slightly different syntax.

Moving on to jQuery selectors, you have some flexibility in how you specify them. For instance, this code:

$(".my_class").show();

is functionally equivalent to this code:

var my_class_name = ".my_class";
$(my_class_name).show();

This is a great thing, because that means that you can store the name of jQuery selectors in variables and use them instead of requiring string literals. You can also build them from components, as you will find in this example:

var mine_or_yours = (user_selection == "me") ? "my" : "your";
var my_class_name = "." + mine_or_yours + "_class";
$(my_class_name).show();

This is essentially the behavior that you're trying to get working. Using the two features together (interpolation and dynamic jQuery selectors), you have this:

$(`"${B2}"`).remote_chained(...);

which produces this code through string interpolation:

$("\".employee_title_2B_1462463848339\"").remote_chained(...);

which is not correct. and is actually the cause of the error message from jQuery, because of the embedded double quotes in the value of the string. jQuery is specifically complaining about the extra double quotes surrounding the value that you're passing to the selector.

What you actually want is the equivalent of this:

$(".employee_title_2B_1462463848339").remote_chained(...);

which could either be written this way:

$(`${B2}`).remote_chained(...);

or, much more simply and portably, like so:

$(B2).remote_chained(...);

Try this little sample code to prove the equivalence it to yourself:

if (`${B2}` == B2) {
    alert("The world continues to spin on its axis...");
} else if (`"${B2}"` == B2) {
    alert("Lucy, you've got some 'splain' to do!");
} else {
    alert("Well, back to the drawing board...");
}

So, we've established the equivalency of interpolation to the original strings. We've also established the equivalency of literal jQuery selectors to dynamic selectors. Now, it's time to put the techniques together in the original code context.

Try this instead of the interpolation version:

$(B2).remoteChained({
  parents : A1,
  url : "titles/employee_title_2",
  loading : "Loading...",
  clear : true
});

We already know that $(B2) is a perfectly acceptable dynamic jQuery selector, so that works. The value passed to the parents key in the remoteChained hash simply requires a string, and A1 already fits the bill, so there's no need to introduce interpolation in that case, either.

Realistically, nothing about this issue is related to Chained; it just happens to be included in the statement that's failing. So, that means that you can easily isolate the failing code (building and using the jQuery selectors), which makes it far easier to debug.

Note that the Javascript syntax was codified just last year with ECMAScript version 6, so the support for it is still a mixed bag. Check your browser support to make sure that you can use it reliably.

2 Comments

Thank you for the explanation and examples. I assume, though, that you didn't read my response to andirc (below). While your answer is correct re interpolation / substitution, it's not what I need to make chaining work with Mika Tuupola's jQuery Chained plugin.
I did read the comment before I posted this answer. You said that that your "code needs both the '.' and the " " (double quotes) to prevent to aforementioned error". My answer was focused on explaining why removing the Javascript interpolation would fix the jQuery error that you're receiving. The "Uncaught Error: Syntax error, unrecognized expression" error is happening within the jQuery selector, and it's easily reproducible. If you fix the selector as I described, you'll at least be further along with getting Chained working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.