Checking to see if element is visible - javascript

I have a list of apps that are listed on a non angular page. The list of apps that are available depends on what subscription level was paid for. If the subscription level does not have an app purchased the app is still listed however there is an overlay over the app. (please see picture).
The html looks like this:
<div class="apps-item apps-no-border disabled">
<div class="apps-name">
<span>Interactive Event Diagrams</span>
</div>
<div class="divider">
<div class="apps-description">Interactive Event Diagrams is an indispensable online tool, allowing website visitors to view your meeting rooms and create their own customized event layouts according to their specific needs, all while using your venue’s available inventory. Users
can email and save diagrams or images for future reference.</div>
<div class="apps-image-preview">
<img alt="Interactive Event Diagrams" src="/Content/Images/AppsPreview/interactive_event_diagrams.png">
</div>
<div class="apps-action">Not Purchased</div>
<div class="overlay"></div>
</div>
</div>
Now if an app is purchased the overlay element is shaded gray in the html and is not view-able on screen. (Ex. no grey shading over Hotel Venue Explorer) I want to be able to check and see if the overlay is seen or not seen.
I've tried this:
elm = element.all(by.css('div.apps-item')).get(5);
expect(elm.$('div.overlay').isDisplayed()).toBeTruthy();
However the expect is returning false.
Other apps html, notice the grey over the overlay class

If your div.overlay is always present in the DOM, then its hard to check if its displayed because it will always be there in the DOM and your css and javascript might be handling the display property(like add overlay if its needed or don't add when its not needed). Also checking isDisplayed function for an empty html element doesn't work as far as i know.
In order to verify it you can check for css attributes that are responsible for the greying out functionality. Here's how -
elm = element.all(by.css('div.apps-item')).get(5);
//Use your css attribute that greys the apps-item div like height, width, color, etc...
expect(elm.$('div.overlay').getCssValue('background-color')).toEqual('grey');
expect(elm.$('div.overlay').getCssValue('width')).not.toBeNull(); //If you know the width then you can check for equality or greaterThan(someVal).
expect(elm.$('div.overlay').getCssValue('height')).not.toBeNull();
Hope it helps.

Related

How to implement MDC (Material Design Component) tooltips?

I have been setting up a simple web guide without using any framework, by just using separate Material Design Components. Many of these I had no issues with (I have successfully implemented buttons with ripple effects, cards, tabs...) but I can not get tooltips to work.
Following the documentation, I have tried many things to make them appear, but they do not show.
They are included in my CSS:
#use "#material/tooltip/styles";
Instanciated in my JS:
import {MDCTooltip} from '#material/tooltip';
const tooltip = new MDCTooltip(document.querySelector('.mdc-tooltip'));
And implemented in my HTML as per the example given, first the tooltip is declared in the body:
<div id="tooltip-1" class="mdc-tooltip" role="tooltip" aria-hidden="true">
<div class="mdc-tooltip__surface mdc-tooltip__surface-animation">
TestyMcTest
</div>
</div>
...and then the tooltip is attached to another element in the same body:
<div aria-describedby="tooltip-1" class="mdc-card in-card-margins">
<div>The status of these data updates can be observed in the blabla</div>
</div>
The tooltip div is made invisible (which is expected behaviour), however, nothing shows up when mousing over the linked object (in this instance a card, but I tried with multiple types of containers and I could not get anything to work).
Thank you for any help.

Reading last element of div instead of first element in accessibility through arrow keys

Reading - Some text on page load then No instead of Yes
<div>
<div role="alert" aria-live="assertive"> Some text on page load</div>
<div>
<button> Yes</button>
<button> No</button>
</div>
</div>
You can simply switch the order of the elements as shown below
<div>
<div role="alert" aria-live="assertive"> Some text on page load</div>
<div>
<button> No</button>
<button> Yes</button>
</div>
</div>
You can't.
Your post is tagged with nvda and accessibility tags, then accessibility is a concern for you.
WCAG guideline 2.4.3 states that
If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.
You have to create a logical tab order which means that if your language reading order is ltr (left-to-right). Elements on the left should be focused before elements on the right.
For rtl (right-to-left) languages,you have to place the elements in the same order as they appear in the DOM from top to bottom and right to left, and to define the dir="rtl" attribute.
There's no other solution but swapping the two buttons, as suggested by DILEEP THOMAS.
Document/browse/virtual cursors of screen reader always read content in the order of the accessibility tree, which is more or less the same as the DOM tree.
There is no way to change the reading order. If you want a content to be read in a particular order, then it must appear in that order in the tree. Period.
If it doesn't appear visually in the right order, then it's your responsability to fix your CSS to make it look like what you want.
However, think twice before doing that: why screen reader users should read "no" and then "yes", while normal users should first see "yes" before "no" ?
Very often, it's a signal of bad design, and bad design for all users (whether you have sight or not).
Note also that if you use CSS to visually swap the buttons,
Depending on the exact code used, some screen readers will take your CSS into account, while other won't. Most won't, but you can never be 100% sure of that.
Partially sighted and keyboard-only users will still ahve a problem, because the tab order is going to be in an unexpected/illogical order, i.e. people in western culture expect tab order to run top to bottom and left to right, while your CSS code will necessarily imply the opposite.
For that last point, using other values than 0 and -1 for tabindex is a very bad idea. The details on why have already been covered at many places on the web.
if Buttons would be navigated via tab instead of arrow, you can use tabindex to order them accordingly.
<div>
<div role="alert" aria-live="assertive"> Some text on page load</div>
<div>
<button tabindex="2"> Yes</button>
<button tabindex="1"> No</button>
</div>
</div>

How can I "stream" a section of my webpage to another window?

I want to stream a certain container on my webpage to another window.
The setup is similar to a Point of Sale system. ie an operator-facing display and a second customer-facing display.
The operator-facing display will have a window with all the toolbars, menus etc. While the customer-facing display will only show a certain container from the first operator-facing window.
As below: The Operator Display will contain the full webpage content. While the customer display will only contain the #output container.
Operator Display
<div id="toolbar">
<ul>
<li><button>Action 1</button></li>
<li><button>Action 2</button></li>
</ul>
</div>
<div id="output">
//OUTPUT GOES HERE
</div>
Customer Display
<div id="output">
//OUTPUT GOES HERE
</div>
Is there anyway to do this?
Since you put "stream" in quotes, I assumed that you are looking for different solutions for this problem.
In browsers you can easily open a new window and control it from main page, I've created a small snippet which implements a case, where on one window you can add items and display them on another one.
These lines are most important:
const posWindow = window.open("about:blank", "customerDisplayWindow", "height: 50,width: 50");
posWindow.document.body.innerHTML = '<h2>Items</h2><ul id="item-display"></ul>';
You could come up with much cleaner solution than modifying document but you get the idea.
https://jsfiddle.net/jhd5L8wa/1/
I suggest reading MDN page about Window.open() (especially third argument, windowFeatures) to learn more about how opened window will look and behave.

Zeroclipboard, triggered by any element with class="copy"

I've looked through this site along with many others and I can't see the answer anywhere.
I currently have a site with multiple buttons and a preview pane. The text shown in the preview pane differs depending on the button that the user is currently hovering over.
<body>
<div="preview_pane"> <!--ALL TEXT IS SHOWN HERE --> </div>
<div id="button_group">
<div class="copy_me" id="stock1"></div> <!--THIS SHOWS STOCK TEXT-->
<div class="copy_me" id="stock2"></div> <!--COMPLETELY DIFFERENT TEXT-->
<div class="copy_me" id="stock3"></div> <!--YET SOME OTHER DIFFERENT TEXT-->
<div class="copy_me" id="stock4"></div> <!--OTHER COMPLETELY DIFFERENT TEXT-->
</div>
</body>
What I want to do is have zeroclipboard create the flash overlay on any button with the class copy_me. All of these buttons need to copy the text shown in the preview pane.
This way when the user hovers over the button the text in the preview pane will change and then when they click, the text in the preview pane will be copied to the users clipboard.
I can't manually add the script to every button as there will be over 50 stock text buttons.
I have no experience in flash or javascript (only dabbled in jQuery) so this is something completely new for me.
Any help will be greatly appreciated.
answered a similar question at https://stackoverflow.com/a/26200988/3471658
Try using http://www.steamdev.com/zclip/ it allows you direct access to jquery and you can use your own logic in the return statement.
include jquery.zclip.js
download and save ZeroClipboard.swf
Here is a snippet:
$(".class-to-copy").zclip({
path: "assets/js/ZeroClipboard.swf",
copy: function(){
return $(this).attr("data-attribute-with-text-to-copy");
}
});
Make sure you change the path of the swf.
I looked at the api docs for zeroclipboard right quick, and I you want to use the glue method, and pass an array of dom nodes. In this case, you want all the nodes with the class name "copy_me", so:
var clip = new ZeroClipboard();
clip.glue(document.getElementsByClassName('copy_me'));
You mentioned jQuery. This should make things easier for you:
var client = new ZeroClipboard($('.copy_me'));
See:
https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/instructions.md
Also see:
http://jsfiddle.net/rimian/45Nnv/

Loading user control dynamically in two directions

I am developing a commenting like platform where user can post comments and other users can reply on that comments. But these comments can be replied in two directions (Reply & Expand). The idea is that user can reply and user can also expand that discussion. Please see image.
I have developed a control which will be added dynamically whenever user will Reply or Expand a comment.
If user will reply on control a new control will be added under that message (comments) and if user Expand that message (comments) then a control with expanded reply (message) will be added on right side of that messages (comments). More than one user can Expand a message and users can also reply on expanded message.
I am not sure that what should be the place holder or container in which these control should be added.
Should I use Server Table control and create TableRows and TableCells
dynamically?
What container should I use so page don't get too heavy?
Should I create divs and adjust its position on runtime and add control in each
div?
Other question on which I am not clear are:
More than one user can expand a message, in this case how to handle
UI. Hide/Show controls or any other solution.
Should I show horizontal scrollbar on Expansions or is there other
solutions?
Any help/suggestion?
Thanks.
you can do this in different ways, i am not going to give you code cause i want you to try and learn. So you can do all this with JQuery, you don't need Asp.net controllers, cause sometimes they are complicated to work with.
So 1º step:
You can create a simple table with 2 Columns and N rows depending on the number of messages you have (try filter some, Example: you have 100, show only 10 and have a "next page") or use some plugin table that hold bigdata for you.
2º Step:
when you reply a message create an <tr> in you table to place the "reply of first message" (note: you need to create a structure to handle you navigation on the table easily with ID's)
3º Step:
in your second column have like a <div> prepared to receive and show the expand message when user click "expand" and clean it always when a new message is expanded.
That should work for you, there are others ways but try to think in something simple
Other Questions:
1º - I didn't understand the question, but if your site will run on a server, user1 and user2, ... userN use the same page but render in different places, you just need to reload data to let everyone known that someone comment or reply or whatever in a message.
2º - UI its your choice, see what is best for you ;)
enjoy ;)
I think other answer is to complicated. For me it's seems like you need
<div class="rowContainer">
<div style="float:right">
<uc:YourControl>
</div>
<div>
for row of your expandable controls.
When user will quick on expand button page will add another one of YourControls to div.rowContainer with parent another div with float right:
<div class="rowContainer">
<div style="float:right">
<uc:YourControl>
</div>
<div style="float:right">
<uc:YourControl>
</div>
<div>
When user will add another row of messages add another row container with div.rowContainer:
<div class="allMessagesContainer">
<div class="rowContainer">
<div style="float:right">
<uc:YourControl>
</div>
<div>
<div style="clear:both">
<div class="rowContainer">
<div style="float:right">
<uc:YourControl>
</div>
<div>
</div>
clear:both is important since is breaking float to next line.
I think wolud be goo to create 3 controls:
1. <uc:YourControl> with single message
2. Control from div.rowContainer to easy append messages to the left, just add another one to server div with float:right inside same control.
3. Control for all messages to easy adding messages in next row. Just add another row control to container.
Also floating of controls will not force user to scroll to the left infinitely. It's not nice and they hate that.
And just one more: asp.net is not really for this kind of sites. Things get quickly complicated. What if button in one of nested controls should do something on Page?
Should you add method to Page and cast it on control? ((MyPage)Page).DoSomeWork()
What if type of Page change? Create interface? Maybe delegate instead. Where put him? In the Page? Control? Create event and bubble it's through all parents? Some context class?
And not mention with necessity of reinitialization of dynamic controls tree every-single-time post back is send.
1 MSG
2 MSG
Response
...etc...
... you can do like this :)
When it comes to CSS, simple is better.
My suggestion, if you must have it this way in terms of layout:
<div class="row">
<div class="message"><FirstMessage /></div>
<div class="message"><ExpandedFirstMessage /></div>
</div>
<div class="row">
<div class="message"><Reply /></div>
...etc...
</div>
You create a div for each "row" or expanded responses, using a div with class "row.". Then, each message has its own div with class "message", using the following CSS:
.message {
width: 200px; // or whatever size you want here
height: 100px; // or whatever size you want here
display: inline-block; // This is the important part!
...etc // your extra padding, margin, whatnot.
}
Inline-block allows you to avoid floats and whatnot, which should make things a lot simpler. (As a bonus, people with RTL reading order will have this work automatically for them.)
Now, here's your problem.
From the image you've described, it looks as though anyone can reply to any message, or expand any message; this means, logically, that the grid layout you've described might not work well. (For instance, what if someone replies to Expanded First Message, and someone else expands Reply to First Message? You would have to Message usercontrols that would be vying for the same space. How would that work?) I would suggest implementing a different design that would accommodate your usage flow, unless you have something more specific planned.
I hope this answer helps you. Good luck.

Categories