Make 'dropdown-content' same width as paper-dropdown-menu? - javascript

I have the following piece of code:
<paper-dropdown-menu id="mydropdown" label="City?">
<paper-listbox class="dropdown-content">
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
But as seen in the image below, the dropdown-content will have very small width. How can I in a clean way set the width to the same size as the actual paper-dropdown-menu?

I believe I have created what you are looking for in this jsfiddle.
or if you prefer here is the code snippet
.custom {
width: 190px;
}
.custom2 {
width: 400px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<base href="//polygit.org/components/">
<link rel="import" href="polymer/polymer.html">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="paper-item/paper-item.html">
<link rel="import" href="paper-listbox/paper-listbox.html">
</head>
<body unresolved>
<dom-module id='base-page'>
<template>
<paper-dropdown-menu id="mydropdown" class="custom" label="City?">
<paper-listbox class="dropdown-content custom" horizontalAlign='left'>
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
<br>
<paper-dropdown-menu id="mydropdown" class="custom2" label="City?">
<paper-listbox class="dropdown-content custom2" horizontalAlign='left'>
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</template>
</dom-module>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'base-page',
properties: {}
});
});
</script>
<base-page></base-page>
</body>
</html>
All I did was created a custom class that was applied both to the dropdown-menu and the listbox that gave them each the same width. I believe 190px is the default, but once you have the class you can size it how you want it.

In this u can adjust the width according to you iron-dropdown give the left 0 and width:100%
.custom {
width: 100%;
}
.custom2 {
width: 100%;
}
iron-dropdown{
left:0 !important;
width:100% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<base href="//polygit.org/components/">
<link rel="import" href="polymer/polymer.html">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="paper-item/paper-item.html">
<link rel="import" href="paper-listbox/paper-listbox.html">
</head>
<body unresolved>
<dom-module id='base-page'>
<template>
<paper-dropdown-menu id="mydropdown" class="custom" label="City?">
<paper-listbox class="dropdown-content custom" horizontalAlign='left'>
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
<br>
<paper-dropdown-menu id="mydropdown" class="custom2" label="City?">
<paper-listbox class="dropdown-content custom2" horizontalAlign='left'>
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</template>
</dom-module>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'base-page',
properties: {}
});
});
</script>
<base-page></base-page>
</body>
</html>

Actually i believe the two answers by #aditya shrivastava and #jarod moser are not working if you want it the "pure" polymer style.
Here my reasoning:
you use CSS that's not getting shimmed by Polymer
Styles are bleeding through the DOM Tree, which is not intended by Polymer
So my solution here:
set the width of input as proposed in the other two answers
set the with of dropdown with the help of the CSS Mixin:
.custom2 {
--paper-dropdown-menu-button: {
left: 0;
width: 100%;
};
}
The Mixin gets applied to the dropdown box - an iron-dropdown actually - when the CSS is getting rewritten. See the documentation at: https://www.polymer-project.org/1.0/docs/devguide/styling#custom-css-mixins
Then your code should follow this basic setup:
<dom-module id="some-kind-of-element">
<style>
#mydropdown {
--paper-dropdown-menu-button: {
left: 0;
width: 100%;
};
}
</style>
<template>
<paper-dropdown-menu id="mydropdown" label="City?">
<paper-listbox class="dropdown-content">
<paper-item>Inbox</paper-item>
<paper-item>Starred</paper-item>
<paper-item>Sent mail</paper-item>
<paper-item>Drafts</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</template>
</dom-module>
I'm not 100% percent sure about the selector now, but you can see in the web inspector how the styles are added to the elements inside the paper-dropdown-menu element. See the element documentation at polymer: https://elements.polymer-project.org/elements/paper-dropdown-menu to find guidance which CSS Mixins are avaliable to you and play around with them, until you nail it. Maybe you also have to overrule the default settings with the use of !important CSS attribute modifier.
Custom CSS is still quite annoying in Polymer...

to make 'dropdown-content' dependent to width of the paper-dropdown-menu do this:
create your own menu: < resizable-dropdown-menu > copy all component from < paper-dropdown-menu-light > (i like it more), or < paper-dropdown-menu >
import IronResizableBehavior
enter
<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
add Polymer.IronResizableBehavior
behaviors: [
//...
Polymer.IronValidatableBehavior,
Polymer.IronResizableBehavior // add this
],
Add this to attached function:
/*
*
* to make menu the same width as container;
*
*/
var ironDropdown = Polymer.dom(this.$.menuButton.root).querySelector('iron-dropdown');
this.addEventListener('iron-resize', (e) => {
ironDropdown.style.width = Polymer.dom(this.root).node.host.offsetWidth+'px';
});

Related

Selcting the first <content> element with polymer 1

I am using Polymer 1 for web-development and I am encountering a small lack of understanding. Imagine the following:
<div class="value">
<content></content>
</div>
I can easily style the content with the .value selector. Now I only want to style the First content element. :first-child etc. doesn't seem to work.
How can I select different elements of my <content></content> in Polymer?
Thanks!
Note that <content> has been deprecated for <slot>.
To target the first child of the <slot>/<content>, use ::slotted(:first-child):
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
properties: {
foo: {
type: String,
value: 'Hello world!'
}
}
});
});
<head>
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.8.0/lib/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo>
<div>first</div>
<div>second</div>
<div>third</div>
</x-foo>
<dom-module id="x-foo">
<template>
<style>
::slotted(:first-child) {
color: red;
}
</style>
<slot></slot>
</template>
</dom-module>
</body>

Polymer - simple way to access child element properties from parent element

I have a simple polymer element that looks like this:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="selector-course">
<template>
<style>
paper-dropdown-menu {
padding:5px;
}
</style>
<paper-dropdown-menu label="Course">
<paper-listbox class="dropdown-content" selected="{{selected}}" attr-for-selected="value" id="courseSelect">
<paper-item value="main">Main</paper-item>
<paper-item value="soup">Soup</paper-item>
<paper-item value="dessert">Dessert</paper-item>
<paper-item value="appetizer">Appetizer</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</template>
<script>
Polymer({
is: 'selector-course'
});
</script>
</dom-module>
This element is stored in a separate HTML file and then used in a couple of my other elements like this:
<link rel="import" href="components/selector-course.html">
...
<selector-course selected="{{recipe.course}}"></selector-course>
Now, within my parent elements I need to access the selected value of <selector-course>
Right now, I have a solution that looks like this:
this.shadowRoot.querySelector('selector-course').shadowRoot.querySelector('#courseSelect').selectedItem.getAttribute("value");
This works, however, this query seems absurdly complex for such a trivial task as accessing the property of an element.
Is there a more simple way to achieve the same thing?
Oh no, this is a very bad idea. Accessing internal elements is very brittle, because it requires parent elements to have deep (pun intended) knowledge about the implementation details of <selector-course>. Not to mention that your method will not work with Shady DOM.
In your case you could simply adding a notifying property to your element
Polymer({
is: 'selector-course',
properties: {
selected: {
notify: true
}
}
});
To select it's value outside data binding you can use the method #a1626 mentions
var selected = this.$('selector-course').selected;
Polymer({
is: 'selector-course',
properties: {
selected: {
notify: true
}
}
});
<!DOCTYPE html>
<html>
<head>
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import"/>
<link href="paper-dropdown-menu/paper-dropdown-menu.html" rel="import"/>
<link href="paper-listbox/paper-listbox.html" rel="import"/>
<link href="paper-item/paper-item.html" rel="import"/>
</head>
<body>
<template is="dom-bind">
<selector-course selected="{{selection}}"></selector-course>
<div>{{selection}}</div>
</template>
<dom-module id="selector-course">
<template>
<style>
paper-dropdown-menu {
padding:5px;
}
</style>
<paper-dropdown-menu label="Course">
<paper-listbox class="dropdown-content" selected="{{selected}}" attr-for-selected="value" id="courseSelect">
<paper-item value="main">Main</paper-item>
<paper-item value="soup">Soup</paper-item>
<paper-item value="dessert">Dessert</paper-item>
<paper-item value="appetizer">Appetizer</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</template>
</dom-module>
</body>
</html>
Your parent element seems to be a Polymer element in itself as you have used binding. In that case you can access property using
this.$.<id of child>.<property name>
Or in case your element is inside dom-if or dom-repeat
this.$$(<querySelector>).<property name>
You can check it out here
In your case it'll be
<selector-course selected="{{selected}}" id="mySelector"></selector-course>
In javascript
this.$.selected

tooltip in Polymer is cut ourtside of the component it is in

I have made a web component "menu" and it has tooltips on hover. But the tooltips are not visible outside the component. As you can see below I've made tooltip with string "abcdefghijklmnopqrstuvxyz". The tooltip is visible "inside" the component and not "on top" of it.
I want it to be visible on top of everything, not only my component.
If the code is any help, here's component:
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/bower_components/paper-menu/paper-menu.html">
<link rel="import" href="/bower_components/paper-toolbar/paper-toolbar.html">
<link rel="import" href="/bower_components/paper-tooltip/paper-tooltip.html">
<link rel="import" href="/bower_components/paper-menu-button/paper-menu-button.html">
<dom-module id="user-menu">
<template>
<paper-toolbar>
<div class="user-photo" style="background-image:url('image.png');"></div>
<div id="user-name-div">placeholder1</div>
<div class="caption-inv">placeholder2</div>
</paper-toolbar>
<paper-menu>
<paper-icon-item>
<iron-icon id="right-menu-logout" icon="icons:exit-to-app" item-icon></iron-icon>
<paper-tooltip for="right-menu-logout" position="top">abcdefghijklmnopqrstuvxyz</paper-tooltip>
<span>Wyloguj</span>
</paper-icon-item>
</paper-menu>
</template>
<script>
Polymer({
is: "user-menu",
});
</script>
</dom-module>
The tooltip anchors to the parent element; to remedy this I would move the paper-tooltip such that the user-menu element is its parent.
or simply add the attribute:
fit-to-visible-bounds="true"
Making it:
<paper-tooltip for="right-menu-logout" position="top" fit-to-visible-bounds="true">abcdefghijklmnopqrstuvxyz</paper-tooltip>

Grid System doesn't shows color as in documentation

I just started to use angular-material.
I was trying out grid elements in my example, I am testing flex attribute. In the example, this shows three different color for each flex element, but in the codepen, I am not getting those colors.
Here is my code:
HTML:
<html lang="en" ng-app="StarterApp">
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.4/angular-material.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:300,400,500,700,400italic">
<meta name="viewport" content="initial-scale=1" />
</head>
<body layout="column" ng-controller="AppCtrl">
<md-toolbar layout="row">
<div class="md-toolbar-tools">
<md-button ng-click="toggleSidenav('left')" hide-gt-sm class="md-icon-button">
<md-icon aria-label="Menu" md-svg-icon="https://s3-us-west-2.amazonaws.com/s.cdpn.io/68133/menu.svg"></md-icon>
</md-button>
<h1>Hello World</h1>
</div>
</md-toolbar>
<div layout="row">
<div flex>
[flex]
</div>
<div flex>
[flex]
</div>
<div flex hide-sm>
[flex]
</div>
</div>
<!-- Angular Material Dependencies -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.4/angular-material.min.js"></script>
</body>
</html>
JS:
var app = angular.module('StarterApp', ['ngMaterial']);
app.controller('AppCtrl', ['$scope', '$mdSidenav', function($scope, $mdSidenav){
$scope.toggleSidenav = function(menuId) {
$mdSidenav(menuId).toggle();
};
}]);
Please help.
The css is not included in the example. The colors are there to denote the differences between grid size. You can color them using CSS3 nth child selector. You cand find documentation here: http://www.w3schools.com/cssref/sel_nth-child.asp
As an example for your code you can have
#parentDivId div:nth-child(1) {
background: red;
}
#parentDivId div:nth-child(2) {
background: blue;
}
#parentDivId div:nth-child(3) {
background: yellow;
}
So an and so forth. Rename parentDivId with the ID of parent DIV.
DEMO : http://codepen.io/anon/pen/epyQVN

css, html, angularjs or jade issue?

I am having issue getting my css to display. I think its because I applied the html through a directive.
here is my js file:
angular.module('app', []);
angular.module('app').controller('mainCtrl', function($scope){
$scope.user = {
name:'Chelsey',
address:{
street:'PO Box 123',
city: 'Secret Rebel Base',
planet: 'Yavin 4'
},
friends:[
'Hans',
'chewbacca',
'Leia'
]
}
});
angular.module('app').directive('userInfoCard', function(){
return {
templateUrl:"userInfoCard.html",
restrict:"E",
controller: function($scope){
$scope.knightMe=function(user){
user.rank="knight";
};
}
}
});
my root html:
<!DOCTYPE html>
<html ng-app="app">
<head>
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js"> </script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel ="stylesheet" href="style.jade" type="text/css/">
<script src= "app.js"></script>
</head>
<body ng-controller = "mainCtrl" class="container" style ="padding-top:30px">
<h1>Hello World!</h1>
**<user-info-card></user-info-card>**
</body>
</html>
The html that I want the css applied too (user-info-card.html):
<div class="panel panel-Primary">
**<div class="panel-heading">{{user.name}}</div>**
<div class="panel-body">
<div ng-show = 'user.address'>
<h4>Address: </h4>
{{user.address.street}}<br />
{{user.address.city}}<br />
{{user.address.planet}}
</div><br />
<h4> Friends:</h4>
<ul>
<li ng-repeat='friend in user.friends'>
{{friend}}
</li>
</ul>
<div ng-show ="user.rank">
Rank: {{user.rank}}
</div>
<button ng-show="!user.rank" class="btn btn-sucess" ng-click="knightMe(user)">Knight Me</button>
</div>
</div>
and my css in jade:
style.
.panel-heading {
text-decoration-color: blue;
}
I am just trying to get my css to display {{user.name}} in blue right now but it keeps saying that the class is never used. I am a little new to this so anything would be helpful.
text-decoration-color is for the color of the underline. You might want to use color instead.
Also, please note that text-decoration-color has, as of now, poor browser support. See browser support on caniuse
EDIT: Jade is a templating engine for html documents, not for css stylesheets. So in your root html, include the stylesheet as the following :
<link rel="stylesheet" href="style.css" type="text/css">
and in style.css :
.panel-heading {
color: blue;
}

Categories