arrow key navigation in mdc-select not working - material-components

I am working on a page with material-components-web v8.0.0 and I am having trouble navigation the options of my mdc-select elements with keyboard. On arrow-up it only selects the first option, on arrow-down only the last option. Selecting any option in between is not possible.
Tried it in Chrome, Firefox and Opera.
The select markup (made off the example markup in the documentation):
<div id="employees_count_select" class="mdc-select mdc-select--filled fullwidth input-space">
<div class="mdc-select__anchor">
<span class="mdc-select__ripple"></span>
<span class="mdc-select__selected-text"></span>
<span class="mdc-select__dropdown-icon">
<svg
class="mdc-select__dropdown-icon-graphic"
viewBox="7 10 10 5">
<polygon
class="mdc-select__dropdown-icon-inactive"
stroke="none"
fill-rule="evenodd"
points="7 10 12 15 17 10">
</polygon>
<polygon
class="mdc-select__dropdown-icon-active"
stroke="none"
fill-rule="evenodd"
points="7 15 12 10 17 15">
</polygon>
</svg>
</span>
<span class="mdc-floating-label">Employees count</span>
<span class="mdc-line-ripple"></span>
</div>
<div class="mdc-select__menu mdc-menu mdc-menu-surface fullwidth">
<ul class="mdc-list" role="listbox">
<li class="mdc-list-item mdc-list-item--selected" data-value="small" aria-selected="true" role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">1-49</span>
</li>
<li class="mdc-list-item" data-value="medium" aria-selected="false" role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">50-249</span>
</li>
<li class="mdc-list-item" data-value="large" aria-selected="false" role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">more than 249</span>
</li>
</ul>
</div>
</div>
My source import:
import * as mdc from "material-components-web";
My initialization code (typescript):
private instantiateMaterialSelects = (): void => {
console.debug("instantiate material selects");
const selects = document.querySelectorAll('.mdc-select');
Array.apply(null, selects).forEach((uList: HTMLElement) => {
const mdcSelect = mdc.select.MDCSelect.attachTo(uList);
if (uList.id) {
this._mdcSelects[uList.id] = mdcSelect;
}
});
};
No related error messages in the browser console.
Things I tried to fix it: added all the attributes etc. like in the documentation; instantiation with new keyword; add more options, even and odd amounts
Is arrow navigation in select options just not supported, or am I doing something wrong?
I couldn't really get something useful from google or the mdc issues. I might have overlooked something though.
Thanks for any help.

I don't have enough reputation to add comment, so I have to use answers.
I tried your HTML and it seems to be fine, see jsfiddle link in comment to this post. My guess - it is some other your code messing with arrows keys behavior. Try creating minimal reproducible sample.

Related

How to scrape the text Alpha Esports from the html using Selenium and Python

I've recently been undertaking a personal project to improve my programming. I'm relatively new to Python.
What i'm trying to do is scrape some data( about 100-200 items) from a website. I've managed to do it for some elements but not for others. Selenium can't seem to recognize that class name.
<span ng-class="$ctrl.className"> Alpha Esports </span>
I believe the $ctrl has to do with angularjs. The span tag is contained in a div tag, as seen here:
<div class="ui-scoreboard-coupon-template__content--vertical-container"> <!----><div class="ui-scoreboard-coupon-template__content--vertical-aligner" ng-if="!$ctrl.viewModel.isAmericanEvent"> <div> <!----><div class="ui-scoreboard-coupon-template__cell__spacer" ng-if="!$ctrl.viewModel.inPlay"></div><!----> <!----> <div class="ui-scoreboard-coupon-template__cell"> <ui-scoreboard-runner class="ui-scoreboard-runner ui-scoreboard-runner__home" name="$ctrl.viewModel.home">
<span ng-class="$ctrl.className"> Alpha Esports </span> </ui-scoreboard-runner> </div> </div> <div class="ui-scoreboard-coupon-template__row__space"></div> <div> <!----><div class="ui-scoreboard-coupon-template__cell__spacer" ng-if="!$ctrl.viewModel.inPlay"></div><!----> <!----> <div class="ui-scoreboard-coupon-template__cell"> <ui-scoreboard-runner class="ui-scoreboard-runner ui-scoreboard-runner__away" name="$ctrl.viewModel.away">
<span ng-class="$ctrl.className"> G-Rex </span> </ui-scoreboard-runner> </div> </div> </div><!----> <!----> </div>
I've thought about using the xpath but it differs for each data piece and I don't know how to make 'dynamic' xpaths.
When I try to use the class name of a parent tag, it does not return any element. I've tried all of the class names that are present in the code excerpt above.
teams = []
teams = driver.find_elements_by_class_name("ui-scoreboard-coupon-template__content--vertical-container")
Finally, I thought the $ctrl might've been initialized to something earlier in the code but this is the first use of it:
<div class="collapsed-header collapsed-header--show" ng-show="$ctrl.showCollapsedHeader" ng-class="{'collapsed-header--show': $ctrl.showCollapsedHeader}">
<div class="frame-layout">
<div class="left-hand-side">
<a class="collapsed-header__logo" ng-href="/bet" href="/bet">
<svg class="collapsed-header__img">
<use xlink:href="sprite_9c5b742d050f5c4b58fe55f82f78c576.svg#logos-header_logo-usage"></use>
</svg>
</a>
</div>
<div class="center"></div>
<div class="right-hand-side"></div>
</div>
</div>
Any tips regarding what to research/read up on would be much appraciated as I'm a bit overwhelmed by the angularjs concepts and selenium implementation.
I have tried with XPath and it works.Please try and let me know.
print(driver.find_element_by_xpath("//ui-scoreboard-runner[#class='ui-scoreboard-runner ui-scoreboard-runner__home']/span").text)
To extract the text Alpha Esports, as the element is an Angular element, you have to induce WebDriverWait for the visibility of element located and you can use either of the following solutions:
CSS_SELECTOR:
myText = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ui-scoreboard-coupon-template__content--vertical-aligner div:nth-child(2) ui-scoreboard-runner.ui-scoreboard-runner.ui-scoreboard-runner__home>span[ng-class]"))).get_attribute("innerHTML")
XPATH:
myText = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='ui-scoreboard-coupon-template__content--vertical-aligner']//following::div[2]//ui-scoreboard-runner[#class='ui-scoreboard-runner ui-scoreboard-runner__home']/span[#ng-class]"))).get_attribute("innerHTML")
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Angular Material swipe gesture works hardly

I am trying to add swipe functionality to a ng-repeated list of elements. However, the swiping works badly. Sometimes a swipe gestures (all on desktop) is recognized, but most of the times I'm click and swiping like a madman to achieve the expected result.
I am using Material Angular.
Code:
<div ng-repeat="link in Links | filter: { category: 'quick' }">
<div ng-show="!link.show" md-swipe-left="link.show = true">
<div class="lv-item ">
<span href="{{link.url}}" class="no-select" target="_blank" >
<div class="lv-title" class="no-select">{{link.title}}</div>
<small class="lv-small" class="no-select">{{link.description}}</small>
</span>
</div>
</div>
<div ng-show="link.show" md-swipe-right="link.show = false">
<div class="lv-item delete" >
<button ng-click="deleteLink(link.id)">Verwijder</button>
</div>
</div>
</div>
On the Angular Material swipe docpage (https://material.angularjs.org/latest/demo/swipe) it seems easy and it works like a charm. However my implementation of the directive doesn't seem to work as it should. It rather lets me select the text inside the element than swiping.
Also, I'd rather want the span to be a a href, but this only lets me drag the whole element out of space.
I believe that to assure a proper work of all material function you should use their containers and directives instead. So you should put all of that inside a md-content, and also use ng-ifs instead of ng-show on the swiped div. Which would result in something like that :
<md-content>
<div ng-repeat="link in Links | filter: { category: 'quick' }">
<div ng-if="!link.show" md-swipe-left="link.show = true">
<div class="lv-item ">
<span href="{{link.url}}" class="no-select" target="_blank" >
<div class="lv-title" class="no-select">{{link.title}}</div>
<small class="lv-small" class="no-select">{{link.description}}</small>
</span>
</div>
</div>
<div ng-if="link.show" md-swipe-right="link.show = false">
<div class="lv-item delete" >
<button ng-click="deleteLink(link.id)">Verwijder</button>
</div>
</div>
</div>
</md-content>
I used this kind of code snippet on some md-sidenav and it works. By the way, if you're using chrome and use mobile view, the md-swipe-left is always triggered, doesn't matter if you swipe left, right, top or bottom.
Hope this helps

Joomla editor moves </a> tag

Semi-novice web developer getting increasingly frustrated with my Joomla editor changing my code. I've research online and found Q&As that hint at a similar problem but I can't seem to figure this out.
Essentially it's code to create a linked image with a text caption added on hover. Desired code shown below:
<ul class="photo-grid">
<li>
<figure><a href="index.php?option=com_hikashop&view=category&layout=listing&Itemid=179"><img src="images/purple-biothane-waterproof-dog-collars.jpg" alt="purple biothane waterproof dog collars" width="280" height="187" /><figcaption>
<p>Waterproof collars</p>
</figcaption></figure></a>
<p class="photocaption">FEATURED PRODUCT</p>
</li>
BUT each time I open the editor the </a> tag has been moved upwards, directly after the <img> tag. Can anyone offer a resolution, I'd really appreciate it. Thanks.
You are closing the <a> tag after </figure> but you have opened it within <figure> so therefore it needs closing inside <figure>. So use:
<ul class="photo-grid">
<li>
<figure>
<a href="index.php?option=com_hikashop&view=category&layout=listing&Ite‌​mid=179">
<img src="images/purple-biothane-waterproof-dog-collars.jpg" alt="purple biothane waterproof dog collars" width="280" height="187" />
<figcaption>
<p>Waterproof collars</p>
</figcaption>
</a>
</figure>
<p class="photocaption">FEATURED PRODUCT</p>
</li>

polymer on-tap can't work in everywhere on-click can

<div class="list-group bg-light no-border list-group-opt no-radius m-b-none">
<a class="list-group-item" on-tap="enterIndividual">
<div class="primary-info"
<div class="pull-left w-1x">
<img src={{avatar}} class="w-full r-3x"/>
</div>
<div class="pull-left m-l intro">
<span class="text-lg font-bold text-black m-b-sm">{{name}}</span>
<i class="fa fa-user"></i>
<div class="text-muted long-intro">
<span>{{detail}}</span>
</div>
</div>
</div>
</a>
</div>
It works well in computer,but when I tested it in my mobile,it had no react for touching.But if I use on-click instead of on-tap,it performs pretty well.So I am puzzled with this problem.Are there any requirement to use on-tap.Oh,it still has a strange point.If I touch it above a half of the div,it can work.What's the problem?
First, there are some errors in the code:
close the div.primary-info tag
a-tags are not allowed (HTML5) to contain block elements (div) - usually not a problem, but can cause some and will definitely not validate.
I guess your problem is, that the a-tag enclosing everything does not have the proper height and width. Try to give it a background and u'll see how large the a-tag is actually rendered as the tappable area.
U can simply skip the a-tag and move your event on-tag to the div.primary-info

Angular bootstrap returning setIsOpen is not a function

We've got the following HTML:
<div class="btn-group search-dropdown" dropdown is-open="gender.isopen">
<button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle>
{{sex_temp=='F'?'Female':'Male'}} <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-class="{'dropdown-selected':sex_temp=='F'}">
<a ng-click="sex_temp='F'">Female</a>
</li>
<li ng-class="{'dropdown-selected':sex_temp=='M'}">
<a ng-click="sex_temp='M'">Male</a>
</li>
</ul>
</div>
In the console, we're getting the following error:
Error: setIsOpen is not a function #http://127.0.0.1/lib/bootstrap-ui/ui-bootstrap-tpls-0.12.1.js:1734:5
$RootScopeProvider/this.$get</Scope.prototype.$digest#http://127.0.0.1/lib/AngularJS/angular.js:12406:23
$RootScopeProvider/this.$get</Scope.prototype.$apply#http://127.0.0.1/lib/AngularJS/angular.js:12679:13
done#http://127.0.0.1/lib/AngularJS/angular.js:8279:34
completeRequest#http://127.0.0.1/lib/AngularJS/angular.js:8484:7
createHttpBackend/</xhr.onreadystatechange#http://127.0.0.1/lib/AngularJS/angular.js:8423:1 #debugger eval code:1:1
consoleLog/<#http://127.0.0.1/lib/AngularJS/angular.js:10062:18
$ExceptionHandlerProvider/this.$get</<#http://127.0.0.1/lib/AngularJS/angular.js:7363:7
$RootScopeProvider/this.$get</Scope.prototype.$digest#http://127.0.0.1/lib/AngularJS/angular.js:12426:19
$RootScopeProvider/this.$get</Scope.prototype.$apply#http://127.0.0.1/lib/AngularJS/angular.js:12679:13
done#http://127.0.0.1/lib/AngularJS/angular.js:8279:34
completeRequest#http://127.0.0.1/lib/AngularJS/angular.js:8484:7
createHttpBackend/</xhr.onreadystatechange#http://127.0.0.1/lib/AngularJS/angular.js:8423:1
We're using ui-bootstrap-tpls-0.12.1.js
I have tried adding $scope.gender={isopen:false} but that didn't help.
Any idea on what might be the problem here? The dropdown is working perfectly. I just want to get rid of these errors in the console.
I had the same issue, I believe it has something to do with the overlap of bootstrap's drop-down. Try removing the "dropdown-toggle" class from your button.
In my case it helped to simply remove the is-open attribute.
This is 2 years later, but updating your ui-bootstrap would fix this problem if you're using an older version (example 0.13 instead of 2.5)

Resources