MVC DropDownList Arrow style with css - css

In my razor file, I am building a form.
The form controls need to reflect the modelType of the razor page I have declared, in this case, "Case" is the name of the model.
I have a Html helper DropDownList on the page for a property of case called PSCStatusID with this line:
#Html.DropDownListFor(s => s.PSCStatusID, (SelectList)ViewBag.PSCStatusList, "<--Select One-->", new { #class = "form-control" })
This works perfectly for me with of course the validation kicking in from my POCO attributes.
Notice I am sprinkling in Bootstrap css styles. Actually the creative dept. handed off the HTML to me and I am trying to get it exact.
But their version of my one liner HTML helper above is the following:
<div class="input-group">
#Html.TextBoxFor(c => c.PSCStatusID, null, new { #class = "form-control" })
<div class="input-group-btn">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-nrsa-psc dropdown-menu-right" role="menu">
#foreach (PSCStatus item in ViewBag.PSCStatusList)
{
<li>
<a href="#" onclick="document.getElementById('PSCStatusID').value = this.text;">
#item.StatusCode - #item.StatusTextDesc
</a>
</li>
}
</ul>
</div>
</div>
So I know this is a common way these days for HTML people to display a custom dropdown and make that give that button mimicking the DropDown Arrow some bootstrap classes like class="btn btn-primary".
But this is really messing me up.
It doesn't work well with MVC.
If I now name the textbox which mimicks the dropdown selectedText PSCStatusID, it contains the actual text and not the id.
The list items aren't like select options with both text and a value.
I would have to jump through a lot of hoops to make this work.
All I really need to do is change that drop down arrow from the default to my own button looking drop down.
I've come across a lot of css like:
select::ms-expand {display: none;}
That would make the arrow disappear in IE.
And something like this:
select:after {
content: "▼"; /* Current arrow I would like to change */
position: absolute;
top: 0;
right: 0;
bottom: 0;
font-size: 60%;
line-height: 30px;
padding: 0 7px;
background: #000;
color: black;
}
That shows an arrow but not in the select box.
I just can't quite get it.
Does anyone have any suggestions on how to do this?
Here is what I have currently
Notice my validation working out-of-the-box:)
But this is what I need to get:
If any MVC/CSS gurus out there have an idea how to make this happen in my one liner HTML Helper verison of the drop down rather then the custom way please let me know.
Actually this is the code they handed off to me. The version I have above is where I swapped out some MVC controls for HTML:
<div class="form-group">
<label for="nrsa-psc" class="col-sm-4 control-label">*NRSA PSC Status</label>
<div class="col-sm-8">
<div class="input-group">
<input type="text" class="form-control" id="nrsa-psc">
<div class="input-group-btn">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-nrsa-psc dropdown-menu-right" role="menu">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
</div><!-- /btn-group -->
</div>
</div>
</div>
So got a little closer:
I added the selectpicker class to the dropdown:
#Html.DropDownListFor(s => s.PSCStatusID, (SelectList)ViewBag.PSCStatusList, "<--Select One-->", new { #class = "form-control selectpicker" })
Then brought bootstrap select picker css and js from github.
Then added:
.form-control.bootstrap-select.input-validation-error > button { border: 1px solid #f00; background-color: #fee; }
after:
.input-validation-error { border: 1px solid #f00; background-color: #fee; }
to get MVC validation working with the bootstrap select version of the drop down.
And added:
span.caret{color: blue;}
By the way: why is it so hard to get lines to show up as code on this site.
I hit four space all day long and it still shows up as regular text. They should make this easier - very annoying when trying to be a good citizen and post an answer.

Related

Close navigation menu if page link is clicked

In my Angular 8 application, a fixed navigation bar exists on top of the screen. When a user hovers over a dropdown nav link, a menu will show up.
Now, if the user clicks on one of the menu links, the corresponding page will be opened using Angular Routing:
<div class="nav-left">
<div class="dropdown">
<a class="menu" routerLink="/home">
{{'HOME.TITLE' | translate}}
<span class="icon"><i class="fa fa-fw fa-angle-down"></i></span>
</a>
<div class="dropdown-content">
<a routerLink="/home/welcome">
<span class="icon"><i class="fa fa-fw fa-home"></i></span>
{{'HOME.TITLE' | translate}}
</a>
<a routerLink="/home/news-blog">
<span class="icon"><i class="fa fa-fw fa-newspaper-o"></i></span>
{{'HOME.NEWS_BLOG' | translate}}
</a>
<a routerLink="/home/features">
<span class="icon"><i class="fa fa-fw fa-cubes"></i></span>
{{'HOME.FEATURES' | translate}}
</a>
</div>
</div>
</div>
My SCSS definition has a .dropdown:hover selector that shows a menu only if it is hovered:
.dropdown {
.dropdown-content {
display: none;
}
&:hover {
.dropdown-content {
display: block;
}
}
}
What I would like to achieve is that the navigation menu closes automatically when the user clicks a menu link. Right now, the menu remains open because Angular Router does not reload the page but only replaces the page contents by the selected subpage.
In my opinion, there should be a pure CSS / SCSS solution to this problem, although it would be okay for me if it only works with some TypeScript code. My ideas have been so far:
use a special "click" or "selected" CSS selector to define display: none if a link has been clicked
activate some Angular function (if exists?) that resets the "CSS state" (as if the page would have been reloaded)
write a method to close all navigation menus when a routerLink has been clicked (seems too complicated)
Do you have any recommendations which of the mentioned approaches would fit best and how to realize it?
You could have a listener in your template along the lines of:
<div class="dropdown" [ngClass]="{'visible': menuVisible}" (mouseover)="toggleMenu()" (mouseout)="toggleMenu()">
And in your TS:
menuVisible = false;
toggleMenu() {
this.menuVisible = !this.menuVisible;
}
This would be a very simple implementation. You could also do it using Observables, for example (having a Subject emit for each mouse event).
EDIT: I totally forgot to add the click listener part haha! I think you got the idea though!

How to display whole selected element when html page is in the most bottom position?

I am working project with ace-1.3-master template and try to instal button dropdown who I put in most the bottom on the page of HTML.
My problem is the button not display fully of it's content and user need to scrolling manually html page to see whole of the button content . how I can make it automaticly without scrolling.
The button position
Try use position:fixed; in your css button.
Example:
div#myDIV {
position:fixed;
width:100px;
height:100px;
background:red;
left:10px;
top:100px;
}
Finally I find the solution.
Based from this question https://stackoverflow.com/questions/11715646/scroll-automatically-to-the-bottom-of-the-page
I do what #user5978325 was said.
This is the solution
I create a function containing this command
$('html,body').animate({scrollTop: document.body.scrollHeight},"fast");
and then bind it to first level from my button element
my code look like this
<div class="btn-group">
<button class="btn btn-white btn-primary" >others</button>
<button onclick="scrollToLowest()" data-toggle="dropdown" class="btn btn-white btn-primary">
<span class="ace-icon fa fa-caret-down icon-only"></span>
</button>
<ul class="dropdown-menu dropdown-success">
<li>
Print Document PO
</li>
<li>
Send PO To Email
</li>
<li class="divider"></li>
</ul>
</div>
<script>
function scrollToLowest(){
$('html,body').animate({scrollTop: document.body.scrollHeight},"fast");
}
</script>
Thanks.

CSS navigation using "input:checked" doesn't fire inner link href when using secondary labels to uncheck original input

I have created a nice CSS menu for the app I'm working on, which is activated by using a checkbox and sibling selector.
Problem: clicking on a link doesn't close the menu (it's a single page app, so no page reloads)
Attempted solution: tried to create labels inside or around the menu links, with a "for" attribute pointing to the original menu button. This closes the menu on each link click (unchecks the checkbox), but then the link open doesn't fire.
<label for="btn">menu btn</label>
<input id="btn" type="checkbox"/>
<ul>
<li>
<a href="http://google.com/" target="_blank">
<label for="btn">link 1</label>
</a>
</li>
<li>
<a href="http://google.com/" target="_blank">
<label for="btn">link 2</label>
</a>
</li>
</ul>
<style>
/* important styles */
ul {
opacity: 0;
}
#btn:checked + ul {
opacity: 1;
}
</style>
Fiddle here:
http://jsfiddle.net/gebi/4nzLa9yh/
Any ideas?
I hope this will help, if you open link in same tab.
Menu Btn
<ul id="ul">
<li>
link 1
</li>
<li>
link 2
</li>
</ul>
<style>
ul {
display: none;
}
#ul:target {
display: block;
}
</style>

angular-bootstrap dropdown on mouseenter and keep dropdown-menu from hiding before being clicked.

First, I'm aware of this posts:
Activating bootstrap dropdown menu on hover
Bootstrap Dropdown with Hover
How to make twitter bootstrap menu dropdown on hover rather than click
And others, but still not found the correct solution yet, here's what I did so far.
first I used the is-open attribute from the angular-bootstrap dropdown directive like this:
<span class="dropdown" dropdown is-open="status.isopen">
<a
href
class="dropdown-toggle"
ng-mouseenter="status.isopen = true"
ng-mouseleave="status.isopen = false"
>
hover me for a dropdown with angular-bootstrap
</a>
<ul
class="dropdown-menu"
>
<li ng-repeat="choice in items">
<a href>{{choice}}</a>
</li>
</ul>
</span>
that seemed to work but 2 bugs appeared:
the first is when dropdown-toggle element is clicked the dropdown menu is gone clicking again wont bring it back you have to mouseleave then mouse enter the dropdown-tooggle to get the dropdown-menu back.
the second is a css/html problem.
Usually the regular css solution for a dropdown is like this:
<a class="css-dropdown">
hover here with css.
<div class="css-dropdown-menu">
<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
</div>
</a>
Notice the dropdown-menu now is inside the dropdown-toggle element which mean when moving with the mouse from the dropdown-toggle to the dropdown-menu it's moving from parent to child, so basically we still hovering over the dropdown-toggle since we are in it's child, which mean the dropdown-menu will still be visible, on other hand, the bootstrap dropdown works with the click event so having the dropdown-menu as a child of the dropdown-toggle is not needed, but now when someone wants to change the behavior to mouseenter/hover once the mouse leaves the dropdown-toggle the dropdown-menu disappear so we no longer have access to the dropdown-menu elements this is visible in this plunker
To fix the first bug, I just removed the dropdown directive then replaced the is-open with ng-class directive like this.
Change this:
<span class="dropdown" dropdown is-open="status.isopen">
to this:
<span class="dropdown" ng-class="{'open': status.isopen}">
The rest stays the same plunker that fixed the first bug.
The second bug is tricky, since the dropdown-menu is no longer a child of the dropdown-toggle the hover effect wont last while moving from the toggle to the menu, so I did this.
Changed this:
<ul class="dropdown-menu">
to this:
<ul
class="dropdown-menu"
ng-mouseenter="status.isopen = true"
ng-mouseleave="status.isopen = false"
>
That did it but another bug appeared when clicking the dropdown-menu item it stays open, so I kept hacking by doing this.
changed this:
<li ng-repeat="choice in items">
to this:
<li ng-repeat="choice in items" ng-click="status.isopen = false">
That give me the required behavior plunker.
That said, this is not a good solution since a lot of directives are involved here for a simple visual effect, the last plunker I provided contains a css solution with no Bootstrap or AngularJS involved, though it is the required behavior it is not the required html structure or visual result, what I need is to have a space between the dropdown-toggle and the dropdown-menu not a padding of the toggle element just an empty space, which make the css solution not valid in this situation.
So, my question is there a better way of doing this without adding a new plugin/library more clean and easily reusable solution for the hover drop down menu?
First, have the toggling on the top-most parent element (in this case, the <span>)
<span class="btn-group" dropdown is-open="status.isopen" ng-mouseenter="status.isopen = true" ng-mouseleave="status.isopen = false">
<a class="btn btn-primary dropdown-toggle" dropdown-toggle>
Button dropdown <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Separated link</li>
</ul>
</span>
This will allow the behavior you wanted - while still allowing clicking to show/hide the menu ;-)
However there's an annoyance: if you move the mouse cursor slower and pass the small gap between the toggle and menu, it will hide the menu.
So secondly, add a small CSS to remove the gap
.dropdown-menu {
margin-top: 0;
}
See the action in this plunker.
I know you want a solution without adding a new plugin/library, but you (or others seeking for this behavior) might want to try using No Close from Dropdown Enhancements lib to keep the dropdown open even after clicking in one of its options:
Do not close the menu on click on radio add class .noclose.
<div class="btn-group">
<button data-toggle="dropdown" class="btn btn-default dropdown-toggle">
Checked option <span class="caret"></span>
</button>
<ul class="dropdown-menu noclose">
<li>
<input type="radio" id="gr1_1" name="gr1" value="1">
<label for="gr1_1">Option 1</label>
</li>
<li>
<input type="radio" id="gr1_2" name="gr1" value="2">
<label for="gr1_2">Option 2</label>
</li>
<li>
<input type="radio" id="gr1_3" name="gr1" value="3">
<label for="gr1_3">Option 3</label>
</li>
</ul>
</div>
Also add a CSS solution for the hovering problem:
.btn-group:hover .dropdown-menu.noclose {
display: block;
}
.dropdown-menu.noclose {
margin-top: 0px;
}
And, of course, don't forget to import the libs:
<script src="./js/dropdowns-enhancement.min.js"></script>
<link href="./css/dropdowns-enhancement.css" rel="stylesheet"\>
In your case I suggest you to study the Dropdown Enhancements's source code to see how it works and maybe find a more suitable solution.
Try adding this line to your css:
.btn-group:hover>.dropdown-menu { display: block; margin-top: 0; }
You'll have to remove your is-open, ng-mouseenter and ng-mouseleave directives.
Below is the solution I came up with, while working on the same issue.
I used a simple custom directive that:
binds the mouseenter and mouseleave events to the dropdown in order correctly to show/hide the menu.
dynamically adds a custom CSS class to the dropdown menu in order to prevent the menu from disappearing when moving the cursor from the button to the menu. Note that this solution has the advantage of not removing the visual gap between the button and menu.
prevents the menu from disappearing when the button is clicked.
The CSS rule uses a before pseudo-element to fill the gap between the button and the menu. I added the border property which can be uncommented to easily get a visual feedback.
.dropdown-hover-menu::before {
content: '';
position: absolute;
left: 0;
width: 100%;
top: -3px;
height: 3px;
/*border: 1px solid black;*/
}
The HTML structure of the snippet is based on the available examples in the dropdown section of the angular-ui bootstrap documentation
angular.module('app', ['ui.bootstrap'])
.directive('dropdownHover', function() {
return {
require: 'uibDropdown',
link: function(scope, element, attrs, dropdownCtrl) {
var menu = angular.element(element[0].querySelector('.dropdown-menu')),
button = angular.element(element[0].querySelector('.dropdown-toggle'));
menu.addClass('dropdown-hover-menu');
element.bind('mouseenter', onMouseenter);
element.bind('mouseleave', onMouseleave);
button.bind('click', onClick);
function openDropdown(open) {
scope.$apply(function() {
dropdownCtrl.toggle(open);
});
}
function onMouseenter(event) {
if (!element.hasClass('disabled') && !attrs.disabled) {
openDropdown(true);
}
};
function onMouseleave(event) {
openDropdown(false);
};
function onClick(event) {
event.stopPropagation();
}
scope.$on('$destroy', function() {
element.unbind('mouseenter', onMouseenter);
element.unbind('mouseleave', onMouseleave);
button.unbind('click', onClick);
});
}
};
});
.dropdown-hover-menu::before {
content: '';
position: absolute;
left: 0;
width: 100%;
top: -3px;
height: 3px;
/*border: 1px solid black;*/
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="app">
<div class="btn-group" uib-dropdown dropdown-hover>
<button type="button" class="btn btn-primary dropdown-toggle">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
<li role="menuitem">Action
</li>
<li role="menuitem">Another action
</li>
<li role="menuitem">Something else here
</li>
<li class="divider"></li>
<li role="menuitem">Separated link
</li>
</ul>
</div>
</div>

How to click on an hidden drop down menu element using webdriver, which is not a select

I want to click on delete which is in the sub menu.
I tried the below code, but nothing happens.
wd_handle.execute_script("document.getElementById('optionPanel').hidden=false;")
mouse.move_to_element(OptionPanel).perform()
WebDriverWait(wd_handle,10)
wd_handle.find_element_by_partial_link_text('Delete').click()
HTML Source:
<div id="optionPanel" style="height: auto; width: auto; left: 126px; top: 368px; display: none; overflow-y: hidden;">'
<div class="wrapper">
<ul aria-hidden="false" role="menu">
<li role="menuitem">
<li role="menuitem">
<li class="divider" role="menuitem">
<a class="optionPanelLink" tabindex="0"
href="#playlistManager/action=delete/selected=701f55af-c5f0-4f31-b34f-964f52be5fef/idx=0">
Delete</a>
</li>
</ul>
</div>
</div>
I have to click on the element with id = 7ba9b231-5fc4-448b-b41a-f236437c182cCount to make the above elements visible.
<li class="playlist viewing">
<a id="7ba9b231-5fc4-448b-b41a-f236437c182cLink" class="ellipsis" title="TestList2" href="#playList/name=TestList2/list=7ba9b231-5fc4-448b-b41a-f236437c182c">TestList2</a>
<span class="entryCount">0</span>
<a id="7ba9b231-5fc4-448b-b41a-f236437c182cCount" class="customPlaylistSpriteLocation optionSprite" href="#option/playlist=TestList2/selected=7ba9b231-5fc4-448b-b41a-f236437c182c/idx=0"></a>
</li>
You can click on the hidden menu item using xpath
import org.openqa.selenium.interactions.Actions;
Actions builder = new Actions(driver);
builder.moveToElement(driver.findElement(By.xpath("Enter Menu here"))).build().perform();
builder.moveToElement(driver.findElement(By.xpath("Enter Target here"))).build().perform();
driver.findElement(By.xpath("Enter Target here")).click()
Hope this is code do
Are you sure that your find_element_by_partial_link_text('Delete') works and return an element ?
If it really doesn't work i suggest to use the cssSelector like : "li.divider a"
Tell me what's up.
Replace:
wd_handle.execute_script("document.getElementById('optionPanel').hidden=false;")
With:
wd_handle.execute_script("document.getElementById('optionPanel').style.display='block';")
If it doesn't work, then try using both of them (one after another)...
First of all check your submenu item in which place delete button is highlighted......by using hover.And take that as a reference w.r.t id you can click delete button...here is a code
WebElement wb=driver.findElement(By.xpath("//li[#datapostid='52f377a10a1de86e33f9bc90']/div"));
Actions act=new Actions(driver);
act.moveToElement(wb);
act.perform();
driver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
wb.findElement(By.cssSelector("span.commdelete")).click();

Resources