0

I am using jquery 1.11.1 with Flask/jinja2 templates

While attempting to remove row based on class, I used

$("table#success tr[class=" + sale_id.rowclass  +"]").remove();

The "sale_id.rowclass" variable is passed in from my jinja template. When the variable is single valued(eg."n133") the statement works perfectly however when the variable holds a double value eg. "danger n133"

I get:

"Error: Syntax error, unrecognized expression: table#success tr[class=danger n133]"

Any ideas on what I am doing wrong?

SOLVED:

Thanks all posters, I am new to jquery and javascript and you guys taught me a lot.

To be able to delete a row containing class " danger n123" OR containing class "n123", I did the following. Thanks to Kevin Grabher and Grundy I got separate values from sale_id.rowclass by using the .split() function

var clsvalues = sale_id.rowclass.split(" ");

Then

$("table#success tr[class~='" + sale_id.rowclass + "'],[class~='" + clsvalues[1] + "']").remove();

The placement of quotes sent me crazy though. If there are more elegant solutions I would welcome it.

To newbies like me the comma between the indexes allowed for an "or". https://stackoverflow.com/a/2263976/4154955

Community
  • 1
  • 1
John Boyd
  • 3
  • 1
  • 4
  • Can we get a code example of how sale_id.rowclass is being generated? – justacoder Mar 05 '15 at 14:12
  • you need add quotes around attribute value like `class='" + sale_id.rowclass +"']` from doc:[_value: An attribute value. Can be either an unquoted single word or a quoted string._](http://api.jquery.com/attribute-equals-selector/) – Grundy Mar 05 '15 at 14:19
  • @AngrySpartan I am trying Grundy's recommendation first(because it is shorter). – John Boyd Mar 05 '15 at 14:28
  • @Grundy, I did as you recommended, it worked to remove the row with the two class values, however I really wanted to be to remove rows which had both the two class values or a row which had the last value. – John Boyd Mar 05 '15 at 14:30
  • @JohnBoyd can you explain what you really want and add it in your post? – Grundy Mar 05 '15 at 15:06
  • @Grundy, my apologies, you are correct, my post should have focused on what I really wanted to do, however I ended up with tunnel vision on my error message. proper quoting did remove the error but did not really solve my bigger issue. – John Boyd Mar 05 '15 at 15:45
  • @JohnBoyd after split your class name without spaces, so you not need add quotes around it :-) – Grundy Mar 05 '15 at 15:48
  • @Grundy, sorry to be a pest, can you give me an example of that, is it different from what Kevin Grabher said. – John Boyd Mar 05 '15 at 15:59
  • @JohnBoyd i mean: if you have `sale_id.rowclass="danger n133"` then after splitting you have array `['danger', 'n133']`, so each element is _single word_ and as say in doc: An attribute value. Can be either an _unquoted single word_ or a quoted string. So you can use it without quotes :-) – Grundy Mar 05 '15 at 20:07
  • @JohnBoyd, as all your classes that you are searching for include `n123` you should simply search for `$("table#success tr." + clsvalues[1] + "')` - class selectors are much faster than attribute selectors – Pete Mar 06 '15 at 13:18
  • 1
    @Pete, Thanks Pete, not only solves my issue, it makes my code much easier to read, and updates my understanding of jquery selection mechanics. I changed the line to `$("table#success tr." + clsvalues[1]).remove();` Grundy's last comment saved me fiddling with those quotes again : ) I am going to edit my post to show the update. I was able to reach to this point thanks to the efforts of you, Grundy and Kevin Grabher. Stackoverflow does not seem to give a means to thanking all of you at the same time. – John Boyd Mar 06 '15 at 14:53
  • Haha, nice one. glad you spotted the typo above too! – Pete Mar 06 '15 at 14:58
  • @Pete, OOPs , further testing, did not work as required, when rowclass only has one value, that is "n123" ,clsvalues[1] is now "undefined", so does not work for table rows with class value of only "n123". As extra information, I am adding rows to a page, if a value was already entered then a table row is added with the "danger" class to take advantage of bootstrap css, that renders a row in red. If value was not already entered, the row will only have the second class value thereby no special rendering. I will have to edit post to the previous. – John Boyd Mar 06 '15 at 15:43
  • you can do a test for the length of the array: `var className = clsvalues.length > 1 ? clsvalues[1] : clsvalues[0]` – Pete Mar 06 '15 at 15:58
  • @Pete, yes this works, it does add an extra line of code, but it cuts down on the quote gymnastics. In your experience is this better than the existing solution ?, or should I add it as an alternative solution ? – John Boyd Mar 06 '15 at 16:19
  • I would say it's be better as it will be more readable, although you don't need to declare the variable, you can just place the bit after the = directly where your variable is (but this can become unreadable). One question I would ask though is if you know the classname of the things you want to remove, why not hard code it? What would happen in the event that `sale_id.rowclass` contained something other than `danger n133` or `n133`? As you are using the code to set the class, say `sale_id.rowclass` was `blah blah1`, everything with `blah1` class would be removed as well – Pete Mar 06 '15 at 16:27
  • @Pete, I hope I understand you correctly, imagine this scenario: User imputs new value in form, database is updated, a row is added to page showing new value, sometime later user inputs same value, another row is added to page notifying user that database already has the info, this new row has an extra class prepended with "danger" so it is red. The user can choose to continue adding other data and come back later to edit or delete data. Edit opens form which just allows for updating data, delete removes data from database and also removes both red row and original entry row from table. – John Boyd Mar 06 '15 at 16:55
  • The site recommended I move to chat ( but I don't have the credentials to do so), or add extra info to post. Note I am using ajax so page is updated with rows dynamically. – John Boyd Mar 06 '15 at 16:59

3 Answers3

1

The class value needs to be wrapped in quotes.

Steven Edison
  • 487
  • 4
  • 17
1

Your problem is the space between the classes, you need to add quotes around your selector:

$("table#success tr[class='" + sale_id.rowclass  +"']").remove();

Please note that if your rows have both these classes but not in that order, they will not be selected - see this fiddle, what I would do is use a selector like the following to remove rows with both classes:

var selector = '.' + sale_id.rowclass.replace(/ /g, '.');
$('table#success tr' + selector).remove();

Example

if you want to remove any row with either class you need to do something live this:

var selector = 'table#success tr.' + sale_id.rowclass.replace(/ /g, ', table#success tr.');
$(selector).remove();

Just noticed you are searching for everything with both selectors or anything with the last selector. As both selectors include the last selector, you can simply just search for that:

var splitClasses = sale_id.rowclass.split(" ");
if (splitClasses.length > 1) {
    $("table#success tr." + splitClasses[1]).remove();
}

Note I have used a class selector as it is much faster than an attribute selector

Pete
  • 57,112
  • 28
  • 117
  • 166
1

When one element has multiple classes they need to be written together with just the dot separating them. So the way the selection should work is

table#success tr.classA.classB

Or by attribute style:

table#success tr[class~="value1"][class~="value2"]

You can get separate values from sale_id.rowclass by using the .split() function

example: var anArray = aString.split(" ");

Kevin Grabher
  • 399
  • 1
  • 4
  • 18