check if custom attribute has specific value - jquery-selectors

My problem seemed easy at first but i got stuck.
I have some containers (divs) in my page with some custom attributes.
<div class="myclass" myattr1="blah" myattr2="text1-text2-text3-text4-"></div>
myattr1 and myattr2 are defined by me.
All divs are visible on page load.
Now, depending on user selection from a list, i want to show only the divs with myattrib1="blah" and hide the rest.
I tried the following code, with no success at all
$('#mySelectID').change(function()
{
var startName = $(this).val();
$(".myclass").not('[myattrib1!="+startName+"]').toggle();
});
The same approach will be used to filter results by attrib2, but there i will use myattrib2|="+startName+" ( i think this is correct - thats why i have the extra - on the end of myattr2="text1-text2-text3-text4-").
Can anyone advice me on how to properly achieve this kind of filtering?
thank you!

You are close, but as you can see form the syntax highlighting, your are not performing string concatenation. +startName+ will be taken literally. Fix the quotes and your fine:
.not('[myattrib1!="' + startName + '"]')
Note that you should be using data-* attributes instead of custom ones.

Related

How to clear a material-ui md-field component in Vuejs2?

I have a simple list component in Vue2 with the ability to add/delete items. My issue was that when I switched from a regular HTML element to material-ui (https://vuematerial.io/), my input-clearing functionality broke.
This is what it looked like:
With the regular HTML element, I was simply targeting the element by ID (from within the methods of my component script) and assigning it an empty string to clear it, as so:
if (input.value !== '') {
this.items.push({
text: input.value
})
input.value = ''
}
I found the solution, which I'll answer below, but again, my question was: How do I clear the field when using a material-ui element? And the bonus question, which I haven't fully answered for myself: Why did it break?
So, first the "how" to make it work:
I needed to set a "v-model" attribute on my element (I called it "inputField"), and then initialize it to empty within the component's data properties, and THEN in my component methods "addInput" function, I had to set "this.inputField = ''" instead of "input.value = ''".
To illustrate:
So, that works. Here's the result:
Now, that just leaves the question of exactly how this all works, and why the method which worked for a regular HTML failed on ? I'm not sure, and I'd welcome an explanation/education from anyone who can explain!
Vue DevTools for Chrome seems to give a hint:
"Mdclearable" seems intuitively to be related; this property is set to false. Is that something to do with it? I'm not sure.
Learning a bit more about Vue's "v-model" and reactivity was also helpful in solving this.
Again, additional comments welcome to help elucidate what is going on here! And I hope this Q&A will help someone else possibly avoid some frustrations in future.

Find CURRENTLY selected <option> with XPath

What's the correct XPath syntax to check if an option element is currently selected, or just to get the selected option element from a select element, on an open page with which the user, and JavaScript, may have interacted? Is this even possible with XPath, or does it lack the ability to look at DOM properties?
I can't find any documentation on this, and have (speculatively) tried:
//option[#selected=true]
//option[#selected="selected"]
//option[#selected]
but none of these work; they simply don't match any elements.
(In case it matters, I've tried this both using the $x function in the Chrome developer console, and using the find_elements_by_xpath method in Selenium for Python.)
Short answer: it's not possible.
Longer answer: XPath can look at HTML attributes, but it can't look at DOM properties. Selecting an <option> element in a <select> changes the selected property of the <option> to true, and also changes the value property of its parent <select> element, but it doesn't affect the attributes of either, so it is invisible to XPath.
To find <option> elements that have the selected attribute set, which is often how a page author might determine which option is initially selected, you can use //option[#selected]. But this does not find the currently selected <option>; changes that the user makes to the selection are invisible to XPath. There's no guarantee it will even find the initially selected option, since it's possible that the page author didn't put the selected attribute on any elements and either let the browser select the first option by default or had some JavaScript select the initial option via the selected property.
The multiple other answers here claiming that a selector like //option[#selected] can detect selection changes made by the user after the page loads are simply completely wrong.
Of course, if you're able to use CSS selectors instead of XPath selectors, then option:checked will do the job.
The problem could be the " (double quotes).
//select/option[#selected='selected'] - Will match the selected option, i am using this successfully.
//select/option[#selected='selected' and #value='specific value'] - Will only match the selected option if it has a 'specific value', i'm also using this.
If you are still having trouble, it could be an entirely different problem, perhaps there is no option node. I hope this helps.
I think we can use a knowledge from #Mark's answer and account that. Let's just find a node which HAS desired attribute:
tree.xpath('//select/option[#selected]/text()')[0].strip()
I tried "//option[#selected=''] and it has worked for me.
it is able to highlight the selected option within Page objects model.
I would try //option[#selected='true']
i.e. driver.findElements(By.xpath("//option[#selected='true']")).getText();

Disable escape in Zend Form Element Submit

I can't disable escaping in a Zend_Form_Element_Submit, so when the label has special characters it won't display it's value..
This is my actual Zend Form piece of code:
$this->submit = new Zend_Form_Element_Submit('submit');
$this->submit->setLabel('Iniciar Sesión');
$this->submit->setIgnore(true);
$this->addElement($this->submit);
I've tried $this->submit->getDecorator('Label')->setOption('escape', false); but I obtain an "non-object" error (maybe submit isn't using the "Label" Decorator)..
I've also tried as suggested $this->submit->setAttrib('escape', false); but no text will be shown either.. Any idea? Thanks
Should be as simple as doing this:
$element->addDecorator('Label', аrray('escape'=>false));
Or see setEscape(). http://framework.zend.com/manual/1.12/en/zend.form.standardDecorators.html
Regarding failure to retrieve named decorator... Try getDecorators() Do you see 'label' in the results?
There is no Label decorator for submit form element by default (this is why you get the error).
The $this->submit->setLabel('Iniciar Sesión'); value goes to Zend_View_Helper_FormSubmit, which always does escaping and uses the label as a value.
The helper used by the Submit element escapes by default. Unlike with the label decorator, submit labels are included in a HTML attribute so they need to be escaped.
Your label - Iniciar Sesión - is a perfectly valid UTF-8 string, so the escaped version of it will be the same. If your label is not appearing then something else is going wrong. I'd guess that your page is being served using a charset that doesn't match what Zend View is using (UTF-8 by default).
View the page source to see what actually gets output - that might give you some more clues. Alternatively if the page this form is on is public, if you can provide a URL we might be able to spot the issue.
I ran into a similar issue. In my instance, I added both a label and a description to a text field element. This line of code allowed me to turn off the html escaping for the description attached to that field element:
$form->getElement('txtUPC')->getDecorator('description')->setOption('escape', false);
In my testing, the setEscape() was not recognized by the form elements or their decorators.

Need to print out all links on a sidebar in selenium (xpath?)

I need to find any extra links and print them out. I started by doing:
get_xpath_count('//li/a')
and comparing it to the size of an array that holds the name of all the links for the sidebar. When the count is too high/low, I need to print out all the extra/missing links. I would like to make a list of the names so I can compare it to the array. I've tried a few things like get_text('//li/a'), which returns the name of the first. get_text('//li/a[1]) does the same, but any other index returns nothing.
Any ideas? Also, I need the name that's displayed on the link, not the actual href.
Edit* Also, i'm pretty new to selenium and Xpath. Please let me know if there's info I let out that is needed, or just any suggestions towards thew way I'm going about this.
I have been able to get this to work using CSS element locators. Since I use CSS selectors far more often than Xpath, I find it easier to always use them with Selenium as well.
$selenium->get_text("css=li a:nth-child(1)")
$selenium->get_text("css=li a:nth-child(2)")
$selenium->get_text("css=li a:nth-child(...)")
$selenium->get_text("css=li a:nth-child(n)")
Use:
(//li/a)[$someNumber]
this will get you the text of $someNumber-th //li/a in the XML document.
In order to know what values to use to substitute the $someNumber with, you need to know the total count of these elements:
count(//li/a)
This is in JAVA. You can use the same concept in perl
int totCountInPage=selenium.getXpathCount(//li/a);
for(int count=1;count<=totCountInPage;count++)
System.out.println(selenium.getText("xpath=//li[count]/a"));
This should print text inside the anchor links under all li tag.

I'm trying to select the adjacent sibling of "this" in jquery

$(this+"p").slideDown("slow");
$(this)+$("p").slideDown("slow");
$("this+p").slideDown("slow");
does not work.
Yeah, your syntax is bad. You should use the jQuery Sibling function:
$(this).siblings().find("p").slideDown("slow");
The jQuery API site is awesome for looking stuff like this up, I rely on it nearly daily. I'd keep an eye on it.
Next.
$(this).next("p").slideDown("slow")
Make sure that the "p" element is directly adjacent, though. Otherwise you'll want to use nextAll.
jQuery have not seemed to apply this? Possibly the syntax we are trying to use is incorrect.
next() can only select elements with an ID or Class - Not just a naked dom element as expected.
Instead use. > means select first level decends only.
$('body > div').hide();
But this gives the exact same result
$('body').children('div').hide();
But,
Next
$('body + div').hide();
and
Previous
$('body ~ div').hide();
Do not seem to work as expected? But jQuery use it as example for CSS selection...
Possibly there is a complex syntax to achieve this but I could not figure it out...