Strange behaviour with mat-accordion within a mat-menu - angular-material2

I've built a page with a mat-accordion inside of a mat-menu and there's two issues I've been running into.
First, when I first open the menu, all the accordions within it are open, even though the aria-expanded is set to false for all of them. After clicking on the accordion, it then properly opens, and clicking it again moves to closed and proper functionality returns.
The second issue is that if I place all accordions in closed status and then get out of the menu by clicking elsewhere on the page, and then click on the menu again, while the menu opens up with the accordions closed correctly, but when you go to open one of the accordion's it doesn't open the accordion, giving a strange scrollbar next to it. Again, after clicking the accordion a second time, functionality returns to normal.
Here's my menu and accordion:
<button mat-button [matMenuTriggerFor]="menu" class="right-divide">
<mat-icon>menu</mat-icon>
</button>
<mat-menu #menu="matMenu">
<mat-accordion displayMode = "flat">
<mat-expansion-panel>
<mat-expansion-panel-header (click)="stopClickPropagate($event)">
<mat-panel-title>
PLANNING
</mat-panel-title>
</mat-expansion-panel-header>
<button mat-menu-item>VIEW GOALS</button>
<button mat-menu-item>EDIT GOALS</button>
<button mat-menu-item>ADD A NEW GOAL</button>
<button mat-menu-item>MAKE SCENARIO DECISIONS</button>
<button mat-menu-item>BUILD OPTIONS</button>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header (click)="stopClickPropagate($event)">
<mat-panel-title>
BUDGET
</mat-panel-title>
</mat-expansion-panel-header>
<button mat-menu-item>BASE</button>
<button mat-menu-item>MODIFICATIONS</button>
<button mat-menu-item>ATTRIBUTES</button>
<button mat-menu-item>WORKFLOW</button>
</mat-expansion-panel>
</mat-accordion>
</mat-menu>

best solution that I found.
<mat-menu #menuRef="matMenuTrigger">
<ng-template matMenuContent>
<mat-accordion *ngIf="menuRef.menuOpen">
....
</mat-accordion>
</ng-template>
</mat-menu>
in case with styles, ng-animate of collapse is broken, bcs height = 0

It`s known issue and it has ugly but working solution. This solution works for me
<mat-expansion-panel #myPanel [class.is-expanded]="myPanel.expanded" [class.is-
collapsed]="!myPanel.expanded">
and in the css:
.is-expanded {
.mat-expansion-panel-content {
visibility: inherit !important; //overwrite the element style
height: inherit !important; //overwrite the element style
}
}
.is-collapsed {
.mat-expansion-panel-content {
overflow: hidden;
height: 0;
visibility: hidden;
}
}
This solution from here
https://github.com/angular/material2/issues/10046

Related

Cypress: How to test that content is *not* accessible (clickable etc) because of overlay?

I have implemented a loading indicator in Angular that looks like this:
<div cdkTrapFocus class="activity-indicator-container">
<div class="content-container">
<ng-content></ng-content>
<div [ngStyle]="{visibility: showLoader ? 'visible': 'hidden'}" class="indicator-overlay">
<div class="loading-indicator">
</div>
</div>
</div>
</div>
The indicator-overlay is styled like that:
.indicator-overlay {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.35);
}
When the indicator is displayed, the content is greyed out by a semi-transparent div.
Running cy.contains('text in content').should('not.be.visible') fails when the overlay is displayed.
So is there a way to test in Cypress that the text is actually not accessible (selectable, clickable etc)?
You could use a try/catch block. It sounds like you are testing that the overlay is trapping any click events, more than you are testing that the elements are not clickable (since you aren't changing the elements themselves)
You could do something like this
displayLoadingOverlay();
try{
// this should fail, since the overlay will be blocking it
element.click();
} catch(error){
expect(error).to.contain(message);
}
this test ensures that if you try to click on the element (repeat for as many elements as you would like) an error should be thrown since the element is not clickable by Cypress. If no error is thrown, you can assume the click event worked.

Customize the style/class of a Material2 MdMenu

The documentation is a little sparse on how to modify a menu...either that or I'm just dense. How could I, for example, just change the backcolor of a menu to red?
Simply use the class input on your md-menu:
app.component.html:
<button md-button [mdMenuTriggerFor]="moreMenu">Menu</button>
<md-menu #moreMenu="mdMenu" class="myMenu">
<button md-menu-item>Item 1</button>
<button md-menu-item>Item 2</button>
</md-menu>
styles.css (For some reason it doesn't work in styleUrls):
.myMenu {
background-color: red;
}
Plunker demo
By the way, the thing you were looking for is this:

css overflow with elements moved outside div, elements disappear

I have a form in a div where I brought submit buttons out of the div to another part of the screen. This works nicely. However, I want to lock that div down to a specific size and relative position and use overflow:auto so when it grows too big (the form has elements that are unhidden with checkboxes) the entire screen doesn't scroll, just the div. The problem is, as soon as I add the overflow style, the submit boxes I moved off the div are hidden. I assume this is because with overflow all elements are locked into that div and scroll bars allow you to access them, but in this case the elements are moved left:-500px and it doesn't even give me a scroll bar to scroll left to see them. Basic code follows:
<div class="div1">
<div class="div2">
<form>
<input type="submit" class="sub1" />
</form>
</div>
</div>`
CSS would be:
div.div1 {
position:relative;
width:1000px;
margin: 0 auto;
}
div.div2 {
width:500px;
height:500px;
position:absolute;
top:125px;
left:500px;
}
input[type=submit].sub1 {
position:absolute;
left: -500px;
}
So this works, but as soon as I change the div2 css to:
div.div2 {
width:500px;
height:500px;
position:absolute;
top:125px;
left:500px;
overflow:auto;
}
The submit button disappears.
My question: is there any way to get the scrollbar and keep the div2 container to 500px high without losing the elements outside the div?
If I understand correctly, you can move div2 within the form and leave the submit button outside of div2. That way, the submit button will always be visible and div2 can have overflow.
<div class="div1">
<form>
<div class="div2">
<!-- form fields go here -->
</div>
<input type="submit" class="sub1" />
</form>
</div>
Note: You'll likely need to adjust styles on the button, but I'm not entirely sure about your end goal.

ActionButton instead of ActionLink

I want to create a button which when clicked calls an action. I have used Html.ActionLink to create a link which does exactly that but there is no Html.ActionButton. Is there some other way?
Here is an example using Bootstrap's CSS button and applying it against the link to make it look exactly like the button.
#Html.ActionLink("Select", "Select", new { id = patient.Id }, new { #class = "btn btn-primary", #style = "color:white" })
Is there some other way?
You could use a html <form>:
#using (Html.BeginForm("someAction", "someController"))
{
<button type="submit">OK</button>
}
This seems very simple - am I missing something?
#Html.ActionLink("About", "About","Home", new { #class = "btn btn-success" })
Use this:
#using (Html.BeginForm("yourAction", "yourController"))
{
<input type="submit" value="Some text"/>
}
#using (Html.BeginForm("ActionName", "ControllerName")){
<input type="button" value="Submit" />
}
a[type="button"] {
background-color: #d3dce0;
border: 1px solid #787878;
cursor: pointer;
font-size: 1.2em;
font-weight: 600;
padding: 7px;
margin-right: 8px;
width: auto;
text-decoration: none;
}
#Html.ActionLink("ActionName", "ControllerName",null, new {type = "button" })
Sometimes your button might have nested markup (e.g. for an icon)
This might be helpful to some people:
<button type="button" onclick="location.href='#Url.Action("Action", "Controller")'" class="btn btn-success">My button name <i class="glyphicon glyphicon-search"></i></button>
type=button is required to prevent page from submitting... Another possible solution (if you think type=button looks weird because the element is already a button) would be to call event.preventDefault() in the OnClick javascript handler.
<button onclick="event.preventDefault(); location.href='#Url.Action("Action", "Controller")'" class="btn btn-success">My button name <i class="glyphicon glyphicon-search"></i></button>
This should answer your question.
Can I use an asp:Button like an Html.ActionLink?
Uses CSS to make the link look like a button.
Or use the button inside the form with the form controls moving the page along.
You can write a link to controller and view this way / skip the whole razor notation (worked for me recently on my localhost!):
<button type="submit">OK</button>
use FORMACTION
<input type="submit" value="Delete" id="delete" formaction="#Url.Action("Delete", new { id = Model.Id })" />
I know this is an old topic, but this helped me:
#Html.ActionLink("New member", "Create", null, new {#class = "btn btn-default"})
Make sure you use the correct overload or else you will be directed to the wrong controller.
you need to use a "null" before the new {} as shown below:
#Html.ActionLink("About", "Action Name","Controller Name",null, new { #class = "btn btn-success" })
Notice the null above. This is important!!!
For those of you trying to make an anchor tag look like a button in Bootstrap v3 (maybe v4, too), beware that there are some subtle styling differences regarding margin that bootstrap targets to the Input element and not the A element. This can be a little frustrating when trying to put several buttons next to each other.
There's a rather obvious reason why MVC doesn't have a ButtonLink helper: Think about it. Buttons do not link to anything. They run code. So what code would the helper render? I mean it seems simple that it could just render something like onclick="window.location=/controller/method..." but, is that really what you want? Is it what everyone always wants? Isn't that really just doing a GET? It gets kind of goofy.
So, really, if you want a button that opens a link the easiest way is to do what everyone else suggested and style an A tag to look like a button but then probably go into your stylesheet and do a very specific target of your button anchors to get the same styling as actual buttons. Or use an Input tag and force Razor (or whatever) to render the link inline with your JavaScript.

WatiN SelectList or DIV Click from Google Adwords Keywords Page

I have tried everything but no luck. I am using Watin and C# .NET
What I am doing is going to:
https ://adwords.google.com/o/Targeting/Explorer?__u=1000000000&__c=1000000000&ideaRequestType=KEYWORD_IDEAS#search.none
Note: There's no space between https and ://, but I had to add it because of a markdown problem
Entering the captcha manually (typing the text from Watin).
After you search for keywords, you will see that in the bottom of the page you have a Next and a Previous button.
I would like from WatiN to go to page 2, 3,...
It sounds simple, click on the div (with id gwt-debug-aw-paging-next ) and it will go to next page, but it does not happen.
I tried FireEvent, click, KeyDown, everything ... but it's not working.
I also tried to select 100 results from the Selectlist, but again, it does not work.
I tried it in all ways:
browser.DomContainer.SelectList("gwt-debug-aw-paging-list-box").Option("100").Select();
Nothing seems to work when talking about the buttons from the bottom right of the page.
I managed to "simulate" the click on Broad or Exact results, but not with the bottom buttons.
Any suggestions?
Edit 1:
I uploaded an image so you can see exactly the button I am talking about:
Click here to view it larger.
<div id="gwt-debug-aw-paging-next" class="goog-button-base goog-inline-block goog-button aw-btn aw-pagination-button" tabindex="0" title="Next page">
<input type="text" tabindex="-1" style="opacity: 0; height: 1px; width: 1px; z-index: -1; overflow: hidden; position: absolute;">
<div class="goog-button-base-outer-box goog-inline-block">
<div class="goog-button-base-inner-box goog-inline-block">
<div class="goog-button-base-pos">
<div class="goog-button-base-top-shadow"> </div>
<div class="goog-button-base-content">
<span id="gwt-debug-aw-paging-next-content" class="aw-pagination-next"> </span>
</div>
</div>
</div>
</div>
Please paste the markup of the element you would like to click, including a parent element or two.
This will help in suggesting solutions.
Thanks.
So the following does not work?
using(IE ie = new IE("your-page's-url"))
{
// ... any steps needed to bring up the page in question ...
ie.Element("gwt-debug-aw-paging-next").Click();
}
If not, maybe try clicking on the span gwt-debug-aw-paging-next-content.
I managed to solve the problem. Another programmer gave me this tip, so the credits go to him.
The idea is that there are more spans with the same ID in google adwords (strange, I know), so what we need to do is click on every span, not only at the first span.
Here is the final code that needs to be added:
var pagination = browser.Spans.Where(e =>
e.IdOrName == "gwt-debug-aw-paging-next-content").ToList();
foreach (var item in pagination)
item.Click();

Resources