I'm trying to select this button using protractor:
<button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)">
<i class="glyphicon glyphicon-chevron-up">
</i>
</button>
the only unique element in this is ng-click="$arrowAction(-1, 0)"
Nothing I have tried works:
element(by.css("//button[#ng-click='$arrowAction(-1, 0)']")).click();
//button[#ng-click='$arrowAction(-1, 0)'] is not a valid CSS selector. It actually looks like this is an XPath expression and you meant to use by.xpath() locator.
You can though use the partial attribute check instead:
$("button[ng-click*=arrowAction]").click();
$ here is a shortcut to element(by.css(...)), *= means "contains".
Or, do an exact match:
$("button[ng-click='$arrowAction(-1, 0)']").click();
I still don't like the location technique used in this case, but, given what we have, it is probably the best we can do. Ideally, if you have control over the application code and templates, add a meaningful id, class or a custom data attribute to uniquely identify the element.
Related
I have a button class that is placed inside an iframe. Problem is that this button's class has such a long name and I do not understand how to reference it in my script.
<button class="PDF-dmzpd5z6ckdkxkn8 PDF-5rbqp8nfgh6e11 PDF-tma5quj Toolbar-Button Tool-Button" title="SignUp" aria-label="myButton001" type="button"></button>
I am using my javascript to reference this class as:
document.querySelector("iframe").contentWindow.document.querySelector(".PDF-dmzpd5z6ckdkxkn8").click();
The above code does not work. Do I have to provide the complete class name for reference?
I am on right track because I have another button that looks like this:
<button class="PDF-tdsfethgr51stg Next-Button Next-Previous-Button" title="Next" aria-label="Next" type="button"></button>
And I can easily call/reference it via:
document.querySelector("iframe").contentWindow.document.querySelector(".PDF-tdsfethgr51stg").click();
If selecting with class doesn't work, you can try to select with title attribute:
document.querySelector('button[title="SignUp"]');
Using Id in button is the best option
Example:
<button class="PDF-dmzpd5z6ckdkxkn8 PDF-5rbqp8nfgh6e11 PDF-tma5quj Toolbar-Button Tool-Button" title="SignUp" aria-label="myButton001" type="button" id="exbtn1"></button>
document.querySelector("iframe").contentWindow.document.querySelector("#exbtn1").click();
Note: It's best option to define the tags in Query Selector (eg. document.querySelector("iframe")[0]). The index starts from 0.
Bootcamp sample html file suggests a button written like this:
<p><a class="btn btn-primary btn-lg" onclick="run_update()" role="button">Button</a></p>
Though, I've written button always like this
<button class="btn btn-primary" onclick="run_update()">Button</button>
They seems identical and functions similarly. I'm wondering are they any different or will they impact performance everso slighly?
For this, always go for .addEventListener() instead of onclick. onclick is not recommended for executing an action in JS.
MDN (Mozilla Developer Network) also states that .addEventListener must be used instead of onclick.
For the button, it doesn't affect the overall meaning and work of it. A button doesn't cause a change when inside a p tag.
I'm stuck in a form, I am wondering how can I display an image inside a select option.
Inputs will load text.
What I'm trying to do...
What is the best way to make this work inside the form?
This is what I've done.
So my code is this because <select><option><img href=""></option></select> wont work.
<div class="input-group mb-3">
<input type="text" class="form-control" aria-label="Text input with dropdown button">
<div class="btn-group">
<button type="button" class="no-border btn btn-secondary dropdown-toggle dropdown-toggle-split" id="dropdownMenuReference" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu " aria-labelledby="dropdownMenuReference" style="position: absolute;transform: translate3d(-352px, 35px, 0px);min-width: 380px;overflow-x: hidden;" x-placement="bottom-start">
#foreach($categories as $category)
<a class="dropdown-item" href="#"><img class="rounded" src="/storage/category-icon/{{$category->business_icon}}">{{$category->business_name}}</a>
#endforeach
</div>
</div>
</div>
What is the best practice for this?
(using bootstrap 4 and laravel btw)
Since it is not possible to do that with native HTML elements, you cannot make it work without Javascript. Therefore you at least need a hidden input field (<input name="foo-bar-baz" type="hidden value="…" />) to transfer the data between the server and the client. The data could be a simple serialized JSON Object like so:
[
{
"label": "Click ME",
"icon": "/img/icon.png",
"value": "item-xxx"
},
…
]
Going from there you need to write some Javascript code that generates something that looks like a <select> but isn't. Each change on that »virtual field« needs to modify the respective hidden one's value, such that at submission, the correct value is transferred to the server.
Here I could find an example based on bootstrap, maybe that is helpful. It renders a <ul><li></li>…</ul> list to display the »virtual field«.
One possible solution maybe found here.
To sum up, you need to find a proper Javascript library that helps you doing it, or write some code by yourself to make it. Which one to choose strongly depends on your needs and requirements.
Another thing to keep in mind here is accessibility — what should happen if the user has Javascript disabled, or uses a browser that has problems to execute the code provided. Then it might be a good starting point to render a regular <select> and use data attributes to inject images like so:
<select name="foo-bar-baz">
<option value="value" data-icon="/path/to/icon">Label</option>
</select>
which yields a working form element, which then can be enriched with icons, in case Javascript works properly.
So to answer the question: IMHO best practice is the solution which always works and doesn't exclude users without Javascript, a screen reader or a text-based browser. So the solution provided above, starting with a regular <select>, which should be progressively enhanced, is what I would call best practice here.
right now i'm using an ng-if to determine which button to show my users based on a condition. It just checks if my $scope.method matches the file variable.
<a class="btn btn-default" ng-if="method != file" ng-click="change(file)">Upload</a>
<a class="btn btn-primary" ng-if="method === file" ng-click="change(file)">Upload</a>
however im wondering if there is a more eloquent way to do this by using ng-class or any other angular directives...
Yes, you are correct. ng-class is what you are wanting.
<a class="btn" ng-class="{'btn-default': method != file, 'btn-primary': method === file}"
ng-if="method != file" ng-click="change(file)">Upload</a>
Here is a fantastic article I always reference when I'm needing to use ng-class.
You shall use ng-class to acheive that and add conditionnal class
https://docs.angularjs.org/api/ng/directive/ngClass
I am checking code on w3c validator and I keep getting these errors for each individual blog and portfolio post that has the "Like" button attached to it. Is there something I can do to correct these errors so they validate properly?
Here is a sample of the code:
<a href="#" class="like " title="Like this" data_action="likepost" data_postid="74" data_nonce="13e20f93ee">
<span class="glyphicon glyphicon-heart"></span>
<span class="likecount">2</span>
</a>
Make sure you have doctype declaration like:
<!DOCTYPE html>
and replace the custom attributes as :
data-action data-postid and so on.
Note the hyphen instead of underscore. HTML5 allows custom attributes and suggests to use those which starts with data- .
A custom data attribute is an attribute in no namespace whose name starts with the string data-, has at least one character after the hyphen, is XML-compatible, and contains no uppercase ASCII letters
Reference