How to select class names with spaces and using wild card - jquery-selectors

In the below html snippet I am trying to create a JQuery Expression to select all a tags with class zz1_TopNavigationMenu_1 Napa1-topnav zz1_TopNavigationMenu_*"
I am confused about constructing the select syntax that contains spaces in the class name. I also want a wild card at the end which is depicted above by the '*' char at the end.
<table class="Napa1-topnav zz1_TopNavigationMenu_4" border="0" cellSpacing="0" cellPadding="0">
<tbody>
<tr>
<td style="white-space: nowrap;">
<a class="zz1_TopNavigationMenu_1 Napa1-topnav zz1_TopNavigationMenu_3" style="border-bottom-style: none; border-right-style: none; border-top-style: none; font-size: 1em; border-left-style: none;" href="/sites/Brand1/SubSite

the space character is not valid in a class name; it's a delimiter. A tag may contain multiple class names. For example, <a id="foobar" class="foo bar"> has two classes: foo and bar, hence $('#foobar').getClasses() will have two class names.
So, if you want to select elements with a single class you do:
$('.foo')
If you want to select elements with multiple classes, you do:
$('.foo.bar')

If those are the only 3 classes, and you're certain they will appear in that order, you could use a attribute-starts-with selector.
Try this:
$('a[class^=zz1_TopNavigationMenu_1 Napa1-topnav zz1_TopNavigationMenu_]')
This will select <a> elements where the class attribute starts with zz1_TopNavigationMenu_1 Napa1-topnav zz1_TopNavigationMenu_.
http://api.jquery.com/attribute-starts-with-selector/
Alternatively, you could get elements with the first two classes, and use a filter to make sure it ends with the third class. The way it is written, it assumes your "wildcard" character will be a number or numbers.
$('a.zz1_TopNavigationMenu_1.Napa1-topnav').filter(function() {
return /zz1_TopNavigationMenu_\d+$/.test($(this).attr('class'));
});
http://api.jquery.com/filter/

.zz1_TopNavigationMenu_1.Napa1-topnav.zz1_TopNavigationMenu_whatever
Will get you elements that have all 3 of those classes. The wildcard doesnt work - there is no facility for this using CSS selectors. I would add a class of something like: zz1_TopNavigationMenu and then anything that was also zz1_TopNavigationMenu_whatever would get thsi grouping class. OR if possible you could use ID's or elements to get them all. For instance if its a menu id expect them all to be li elements so you could use: .zz1_TopNavigationMenu_1.Napa1-topnav li or something similar.
Take a look at the docs on css selectors for use with jQuery.

Related

Find and Replace with Visual Studio Code to replace cell alignment with a class

Since the align attribute is considered obselete I am cleaning up code to remove it and replace with a CSS class. I'm trying to determine if there is a way to do this using find and replace (or something else) in VS Code.
As an example, I might have some html that looks like this:
<table>
<tr>
<td align="left" class="someclass" id="mainTitleCell" title="Title1">Title1</td>
<td align="center" title="Title2">Title2</td>
<td class="someclass" align="right" title="Title3">Title3</td> <!-- attributes are not always in the same order -->
</tr>
<tr>
<td align="left">Title</td>
<td align="center">Title</td>
<td align="right">Title</td>
</tr>
</table>
which I would like to change to
<table>
<tr>
<td class="left someclass" id="mainTitleCell" title="Title1">Title1</td>
<td class="center" title="Title2">Title2</td>
<td class="right someclass" title="Title3">Title3</td>
</tr>
<tr>
<td class="left">Content</td>
<td class="center">Content</td>
<td class="right">Content</td>
</tr>
</table>
Basically removing the align attribute and either adding a class attribute with a specific value OR adding a specific value to an existing class attribute. Is there a way to do this with the Edit...Replace option in VS Code? I know I can find based on a regex but not sure how I would go about the replace since this becomes
Find the align tag
Remove it
Find a class attribute in the <td> or <th> tag and add the appropriate class
If there is no class attribute, add one with the appropriate class.
Obviously step #1 & 2 are easy, it's #3 & 4 that I'm not sure of. I'd be totally happy with having to run 3 separate find and replace commands (one for left, center and right).
Do I have any options here (I am open to extensions)?
UPDATE:
#Mark had the right answer and I was able to chain together several find and replace commands using the Replace Rules extension. With that I can open a file, run a single keystroke to find and replace everything and clean up the extra spaces in the class attribute.
Try this:
Find: align="(.*?)"(.*?) class="(.*?)"|class="(.*?)"(.*?) align="(.*?)"|align="(.*?)"
Replace: class="$7$1$6 $3$4"$2$5
See regex101 demo.
I'm a little surprised this works as well as it does (I included a couple of other test cases you didn't). The only issue (thus far...) is that it can result in one stray space, as in:
<td class="left ">Title</td> // only happens when there is no class attribute
as you can see in the demo page. You could then search for " and replace with just ". It could be handled by a conditional replacement but vscode find/replace doesn't allow those.
To some degree attributes will be re-ordered so that the class attribute is first, but not always - you didn't mention that as a concern - any attribute that occurs before either the first class or align attribute will not be moved. Otherwise, attributes like id or title if they are between class<->attribute (in any order) will be put last.

Selecting more that one class in css 3 [duplicate]

This question already has answers here:
What does the "+" (plus sign) CSS selector mean?
(9 answers)
Closed 8 years ago.
Today I was looking at some sample code I found and noticed that the developer used a "+" instead of a "," to select two classes.
.region + .region{
border-left: 1px solid lightgray;
padding-left: 3.5%;
margin-left: 4%;
}
What does the "+" sign do that the "," doesn't? Why would you use it? curiously the same class was selected twice here. Why?
Here is a link to the code pen... http://codepen.io/adobe/pen/vKixh
Im just learning CSS3 and any help would be appreciated. Thanks
They are NOT the same!
+ is the adjacency selector, e.g. selects .region elements following .region elements.
A comma separated list simply allows you to apply one block of styling to multiple classes, thus:
.region, .region{}
Wouldn't actually perform any action that just .region{} wouldnt by itself.
Adjacency selector (MDN article)
(+) This is referred to as an adjacent selector. It will select only the
specified element that immediately follows the former specified
element.
This in mind, .region + .region{} would only apply the styling to a .region after another one, and NOT one in isolation, or the first.
+s and ~s Are Siblings
<div>
<div class="c"></div>
<div class="x"></div>
<div class="y"></div>
</div>
using .c + div {} will style "x" CSS ONLY WORKS DOWNWARDS!
,s Are Multiple Classes
<div>
<div class="c"></div>
<div class="x"></div>
</div>
using .c, .x {} will style both "c" and "x" the same way.
No Space Means More Conditions
<div>
<div class="c x"></div>
<div class="c"></div>
<div class="x"></div>
</div>
using .c.x {} will style "c x"
This is not an alternative notation to , (comma): the + has a totally different meaning, because it is the immediate sibling selector (or adjacent selector), so your rule matches a .region element only when it's adjacent to another previous .region element.
If you have several sibling .region elements, like this
<div class="region">...</div>
<div class="region">...</div>
<div class="region">...</div>
<div class="region">...</div>
.region + .region will match every .region element except the first one.
Since this a CSS2 selector, an equivalent CSS3 selector would be .region:nth-child(n+1)

Selenium-Webdriver JAVA:- i am getting error ""org.openqa.selenium.NoSuchElementException: no such element""" but Appointment Icon is present

I want to verify the tool tip but getting error no such element. I have confirmed that element is exist.
Java Code:
String toolTipTextAppointment = driver
.findElement(By
.id("//*[#id='EditView_NOTE_POPUP']/table/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/table/tbody/tr/td[1]/a/img")).getAttribute("title");
System.out.println(toolTipTextAppointment);
HTML Code:
<td nowrap="nowrap" style="border:0px;">
<a class="" href="javascript:void(0);" onclick="showPopupActivity('Meetings','activityPopupFormAraContent',440,600);">
<img style="border: 6px none;" title="Appointment" src="themes/AutoAccelerator/images/calender_icon.gif"/>
</a>
</td>
Try
driver.findElement(By.cssSelector("img[src*='calender_icon.gif']")).getAttribute("title")
you have used findElement(By.id("")) but you passed xpath in it that is why it is not working
String toolTipTextAppointment = driver.findElement(By.xpath("/html/body/table/tbody/tr/td/a/img")).getAttribute("title");
System.out.println(toolTipTextAppointment);
The problem is visibility. There are two different concepts, existence and visibility (reachable to click or see).
You need to check if the element is visible, not sure about the syntax as I use the clojure library (clj-webdriver) but as far as I know should be shomething like this
e=driver.findElement(By.id("idOfElement")).isDisplayed();
Take into account that the driver will find hidden element but they are not visible. In this particular case you may need to scroll down the page to make the element visible, I suggest retrieve its e.location and use the coordinates with a javascript snippet
((JavascriptExecutor)driver).executeScript("window.scrollTo(" + e.location + ")");
Then the element will be visible and you will be able to interact with it, I usually have this code embedded in a helper function as it's a quite common issue.
Disclaimer: code is just an orientation, I don't know the syntax as I don't use Java. Hope it helps

Span inside text input field?

Is it somehow possible to place a span as the value of a text input field?
I am making a mailing system for a website and want a nice looking receivers input field, where added receivers are contained and added to the value of input text field. At the moment i use a separate "adding field" while showing added receivers in a span-container. I want to merge these to fields together. Just like any input field in regular e-mail software.
Help would be most appreciated! Thanks in advance!
Short answer: no, you cannot include a <span /> within an <input />.
You have a few options. You could use javascript to emulate behaviour like the email To: field. E.g. listen to key presses and handle actions like backspace after a ;.
Another option would be to make a list appear (css styled) like a textbox. Have the last <li /> contain a textbox with cleared styles. Every time the user adds a new email then insert a new <li /> before the textbox.
E.G.
html:
<ul class="email-textbox">
<li>bob#email.com;</li>
<li>jane#email.com;</li>
<li><input type="text" /></li>
</ul>
css:
.email-textbox {
background-color: #fff;
border: 1px solid #ccc;
padding: 2px 4px;
}
.email-textbox li {
display: inline-block;
list-style: none;
margin-left: 5px;
}
.email-textbox input {
background: none;
border: none;
}
javascript (jQuery, can change to vanilla)
$(function () {
$('.email-textbox').find('input').focus();
});
You will need to extend this javascript to include a keypress handler etc, but it gives the general idea.
Demo: http://jsfiddle.net/UeTDw/1/
Any option will require some javascript however.
If you can use jQuery, you could check out jQuery UI autocomplete
One way to do it would be to layer a text input on top of a div that is styled to look like a text input.
<div id="fake-input">
<span class="input-item">John Doe</span>
<span class="input-item">Jane Deere</span>
<input id="receiver-input" type="text" />
</div>
You can strip all styling off of receiver-input, and add borders, background colors, and such to fake-input so that it appears to be a text field. When a receiver is added, you can create a new input-item span and append it to the list.
Input text fields are typically used to accept raw text input. Attempting to wrap input text inside of a text field opens you to user error and potential difficulties with parsing data if the person is able to manipulate the tags.
Personally I would suggest keeping your current method but enabling some form of AJAX support to make things more dynamic and less error-prone to the user.
(My $0.02)
TextExtjs is probably what you want. It's a jquery plugin for allowing removable tags with autocompletion etc in a textarea.
And here is a related SO discussion - where I found this plugin - on mimicking the similar behavior found in some inputs on facebook.

Nesting dynamically displayed components in wicket

I have a need to create following kind of markup with wicket using ajax:
<table>
<tr>
<td><a>first</a></td>
<tr>
<tr>
<td>displayed/closed if first is clicked <a>open</a></td>
</tr>
<tr><td>this and following displayed/closed if above open is clicked</td></tr>
<tr><td>there may be any number of these</td></tr>
<tr>
<td>there may be any number of these as well <a>open</a></td>
</tr>
<tr>
<td>any number of these as well <a>second</a></td>
</tr>
</table>
How to use ListViews or some other wicket element to individually toggle open "inner" rows of the table. I don't want to resort to render everything and toggling visibility but really create the rows in server side only when expand is requested. The markup should also be valid xhtml (rules out arbitrary container for row groups). I know I can put multiple tbodys, but it's good enough only for one level of nesting (no .... allowed).
From Lord Torgamus' comment, the ajax tree sounds appropriate..