Angular Material Select styling not behaving correctly - css

I am following this example of using a material select field: https://material.angular.io/components/select/overview
I have this list in my ts file:
accessTypes: string[] = [
'New Employee', 'Rehire', 'New Provider', 'New Resident/Fellow', 'Transfer/Job Title Change',
'New Contractor/Vendor', 'New Student/Intern', 'Change to existing user'
];
I'm able to make a simple drop down list and get the value quite easily:
<select class="md-col-6 numberEight" [(ngModel)]="model.accessType">
<option *ngFor="let item of accessTypes" [value]="item">{{item}}</option>
</select>
But when I try to use the mat-select the css from the example is not applied and the list options appear all the way at the bottom of the screen:
<div class="question">
<div class="row">
<h5>8. Type of Access Request</h5><p class="required">*</p>
</div>
<div class="col-md-6">
<mat-form-field appearance="fill">
<mat-label>Access Types</mat-label>
<mat-select [(ngModel)]="model.accessType">
<mat-option *ngFor="let item of accessTypes" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
This is what it looks like:
And then all the way at the bottom of the page the list options appear:
There is no styling at all in my css file that affects anything in the select field. Class question has no styling and required just makes the * red.
Even when I do this in a completely new component with an html file including only:
<mat-form-field appearance="fill">
<mat-label>Access Types</mat-label>
<mat-select [(ngModel)]="this.accessTypes" placeholder="Choose...">
<mat-option *ngFor="let item of accessTypes" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
It behaves the same.
So why is this happening? Why does the list not appear as it does in the example ?Does the example exclude some styling that is necessary?
I found this similar question: Mat Select appears in the bottom of the page and tried adding #import "~#angular/material/prebuilt-themes/indigo-pink.css"; to the pages css file but this did not fix the problem.
I have
import {MatSelectModule} from '#angular/material/select';
import {BrowserAnimationsModule} from '#angular/platform-browser/animations';
I also am including in package.json:
"#ng-bootstrap/ng-bootstrap": "^9.1.0",
"bootstrap": "^4.5.0",
and in angular.json I include in styles:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"src/styles.css"
],
and in scripts:
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.js"
]
In my app module. Do I need anything else/are these wrong? Is the bootstrap I already have somehow affecting the style of the select list?
I can't share the entire html page because it makes the question too long, but if you need anything else please let me know.

You code seems to be working properly in my test project, and your imports look correct. You may have something overriding the material select styling, or something is missing in your angular material structure. The use of class="col-md-6" tells me that you are using some sort styling bootstrap framework?
Update:
I spun up a new project specifying .css only, and it looks like I was able to reproduce the issue. It appears that you are indeed missing the material theme structure. I added the #import "~#angular/material/prebuilt-themes/indigo-pink.css"; to the styles.css file and it fixed the problem.
styles.css file:
/* You can add global styles to this file, and also import other style files */
#import "~#angular/material/prebuilt-themes/indigo-pink.css";
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }

Related

How to include bootstrap-vue icons into nuxtjs? Problem with navbar down arrows

Edit: hmm there might be a styling override -
I can take the dropdown from below thats working. And stick it into the nav area and the down arrow disappears. Same can be said for the "lang" drop down, if i move it to the body, the arrow shows up..
EDIT: FML - it was another nav bar styles overriding, USE SCOPE LOL
Navbar svg downarrows won't show up. Most other icons are working just fine..The code below is pretty much copy and pasted for bootstrap vue exampe..
<b-navbar toggleable="lg" type="dark" >
<b-navbar-brand href="#"><img src="" class="d-inline-block align-top" width="220" height="45"></b-navbar-brand>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-nav-item href="#"></b-nav-item>
<b-nav-item href="#">Home</b-nav-item>
<b-nav-item href="#">Contact Us</b-nav-item>
<b-nav-item href="#">FAQ</b-nav-item>
</b-navbar-nav>
<!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto">
<b-nav-item-dropdown text="Lang" right>
<b-dropdown-item href="#">EN</b-dropdown-item>
<b-dropdown-item href="#">ES</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item-dropdown right>
<!-- Using 'button-content' slot -->
<template v-slot:button-content>
<em>Welcome, Friend</em>
</template>
<b-dropdown-item href="#">Profile</b-dropdown-item>
<b-dropdown-item href="#">Sign Out</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-collapse>
</b-navbar>
Some icons work others don't.No errors are being throw.
The documentation says they are not installed by default...so I installed them with
https://icons.getbootstrap.com/#install
https://bootstrap-vue.js.org/docs/icons/
npm i bootstrap-icons
I created a plugin thats included nuxt.config.js. The elements all seem to be working correctly but the icons..
plugins: [
'#/plugins/bootstrap-vue.js'
,'#/plugins/mixins/user.js'
],
/plugins/bootstrap.vue.js below
import Vue from 'vue'
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue'
Vue.use(BootstrapVue)
Vue.use(BootstrapVueIcons)
I also tried to include them specifically
import {BootstrapVue,BIconArrowUp, BIconArrowDown } from 'bootstrap-vue'
Vue.use(BootstrapVue)
import { BootstrapVueIcons } from 'bootstrap-vue'
Vue.use(BootstrapVueIcons)[![enter image description here][1]][1]
Vue.component('BIconArrowUp', BIconArrowUp)
Vue.component('BIconArrowDown', BIconArrowDown)
1) I DON'T see any related to icons in the node_modules/bootstrap folder.
2) I DO see bootstrap.vue-icon.* in the node_modules/bootstrap-vue folder. It contains like -icons.common.js, -icons.css.
I ALso tried to add icons directly to the element like..
<b-nav-item-dropdown icon="circle-fill" text="Lang" right>
Here's a snip from bootstrap-vue site with the down arrow icons showing correctly. The very bottom photo is a snip of my project with the arrows missing..
Here i added some of the other <b> components to my project to see if icons, arrows were working.And they do..
But for b-navbar-dropdown.... They don't work!
Suggestions?
According to the official docs, BootstrapVue does not install the icons plugin by default.
To enable this in Nuxt, edit your nuxt.config.js, find the 'bootstrap-vue/nuxt' module in the modules array and change it from this:
modules: [
'bootstrap-vue/nuxt',
// ...other modules
]
to this, with inline configs:
modules: [
'bootstrap-vue/nuxt', {
icons: true
}
]
or this if you want separate module configs:
modules: [
'bootstrap-vue/nuxt'
],
bootstrapVue: {
icons: true
}
Soviut is mostly correct but the inline config option will not work but will throw a Nuxt Fatal Error. It only expects strings in the modules array. This solution does work however which is just creating an object for bootstrapVue specifying icons: true:
modules: [
'bootstrap-vue/nuxt'
],
bootstrapVue: {
icons: true
}
If you wish to reduce your production bundle size I would recommend you to import specific icons.
module.exports = {
modules: ['bootstrap-vue/nuxt'],
bootstrapVue: {
components: ['BIcon', 'BIconAlertFill', 'BIconCalendar', 'BIconGears']
}
}
We can import BootstrapVueIcons like this:
first,edit bootstrap-vue.js file
my nuxtjs project
second,add this content in this file
import Vue from 'vue';
import { BootstrapVue ,BootstrapVueIcons} from 'bootstrap-vue';
Vue.use(BootstrapVue, {});
Vue.use(BootstrapVueIcons, {})
then you will get it.
See the official docs for instructions on how to use bootstrap icons with nuxt.js
https://bootstrap-vue.org/docs#icons

Materilaize css breaking primeng rendering of input field. How do I fix this css?

I have the following code:
<div class="container" style="width:100%;">
<div class="ui-widget-header" style="padding:4px 10px;border-bottom: 0 none">
<i class="fa fa-search" style="margin:4px 4px 0 0"></i>
<input #gb type="text" pInputText size="50" placeholder="Global Filter">
</div>
<p-dataTable [value]="cars" [globalFilter]="gb">
<p-column field="vin" header="Vin"></p-column>
<p-column field="year" header="Year"></p-column>
<p-column field="brand" header="Brand"></p-column>
<p-column field="color" header="Color"></p-column>
</p-dataTable>
</div>
My component has:
cars = [{
'vin': 'von',
'year': '1990',
'brand': 'Audi',
'color': 'blue'
},{
'vin': 'another',
'year': '2050',
'brand': 'Honda',
'color': 'silver'
}
]
This should be fine, but the problem is I want to use primeng with materializecss. Is there a way I can make it so that for the input box, it does not use materializecss's styling and preserves what primeng already has? At this point, the search box looks messed up with the magnifying glass being above the input field and not inline.
Its supposed to look like this:
https://www.primefaces.org/primeng/#/datatable/filter
If materalizecss overrides same class that primeng uses, you could just load them in different order, first materalizecss then primeng css. This will ensure that primeng css will override same classes materalize defines.
Find out which class materalize overrides and try to work on that.
Edit
I think this plnkr provides an example of your problem
http://plnkr.co/edit/6ptJJw8z9fOgHAAfSv4u?p=preview
Here is how you can fix it
When I open developer tools and select the input box that I want to examine,
it shows me that materalize.css has a class as follows
As you can see here, this css class has highest priority and overrides primeng class. Also, it gives a hint that is :not(.browser-default) pseudoclass.
So if you give your input browser-default class, this rule won't apply.
Check this plnkr
http://plnkr.co/edit/hTa2yxNZJP2Z8p91tQ9t?p=preview
All I did is to add browser-default class to the input
<input #gb type="text" class="browser-default" pInputText size="50" placeholder="Global Filter">

How to open and hide ng-bootstrap datepicker on custom actions?

Currently I am using:
ng-bootstrap 1.0.0-alpha.24
angular/core 4.0.0
bootstrap 4.0.0-alpha.6
I wanted to ask if someone knows how to autoclose the datepicker
when the focus is lost or another datepicker is opened.
Also i wanted to now if it is possible to close the datepicker in the component code with typescript.
It would be nice if someone could provide a working plunker or a code snippet.
My actual implementation:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
Plunker: ng-bootstrap team demo
I have searched a long time and I am also pretty new to angular and these things.
Thank you for your help!
Update:
Possible solution:
There were a lot of good solutions provided.
I also found out by myself that I could use the class NgbInputDatepicker
to close the datePicker (I always used NgbDatepicker, so it didn't work).
#ViewChild('datePickerInput') datePicker: NgbInputDatepicker;
this.datePicker.close();
you can open and close your datepicker from your html itself
for eg:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
<div (click)="datePickerInput.open()"></div>
<span (click)="datePickerInput.close()"></span>
and also there are many functions which you can use in your html. some are close(), isOpen(), manualDateChange(), open(), toggle(), validate() etc. You can refer it in this plunkr http://plnkr.co/edit/G1b6fFrtVZwEz4lsou8n?p=preview
In typescript you can simply define a variable datepickerVisibility and then in your template use *ngIf to show or hide your datepicker component. Here is a demo code:
Template: <datepicker *ngIf="datepickerVisibility" [ngModel]="date"> </datepicker>
Component: private datepickerVisibility: boolean = false;
// Show the datepicker
showDatepicker() {
this.datepickerVisibility = true;
}
Edit:
Therefore you could use jQuery. Add the jQuery js into your index.html and in your typescript component use jQuery as follows:
declare let jQuery: any;
#Component({
moduleId: module.id,
selector: 'test',
templateUrl: 'template.html',
styleUrls: ['test.css'],
})
export class TestComponent {
constructor() {}
public toggleDatepicker() {
jQuery("#datepicker01").toggle();
}
}
And in your template file just add the id datepicker01 to your datepicker div
<div id="datepicker01" ...>
I was looking for a solution to this issue, but in a scenario where the datepicker is wrapped in a custom component and has to expose a function a parent component can call to toggle the datepicker. The answers provided are great and will work for most use case, but not mine, as I didn't want to add a jQuery dependency and calling toggle from the HTML isn't an option.
Here's how I solved it.
I added a ViewChild reference to the datepicker input in the *.component.ts file
#ViewChild('d', {static: true}) d;
that matches the datepicker identifier in the HTML file
<input (dateSelect)="dateSelected($event)" class="form-control" (focus)='d.toggle()' placeholder="yyyy-mm-dd" name="d"
[ngModelOptions]="{standalone: true}" [(ngModel)]="date" ngbDatepicker #d="ngbDatepicker">
and called the toggle function within a method exposed by the component
toggle() {
this.d.toggle();
}
That way, another component can call the toggle() function exposed by this component to toggle the datepicker like so:
In HTML
<app-custom-datepicker #date></app-custom-date-picker>
In .ts file
#ViewChild('date', {static: true}) date;
.
.
.
this.date.toggle();

CSS Modules and React components, I feel like I am not using CSS modules correctly and my styles are clashing

So I have a search box component that is to be used in the Navigation bar on all pages of the site. I also want to use this component/html in other pages of the site hence I put it inside a component shown below
LocationSearchBox.js
import React, {PropTypes} from 'react'
import {Button,FormGroup, FormControl} from 'react-bootstrap'
import styles from '../scss/components/LocationSearchBox.scss'
export default function LocationSearchBox(props) {
return (
<FormGroup>
<FormControl type="text" placeholder="Search" />
<Button bsStyle="success" type="submit" className={styles.navbarSubmitButton}>Get Weather</Button>
</FormGroup>
)
}
I am using css modules with web pack to convert my scss into css and than generate random styles to use in classnames for the components.
LocationSearchBox.scss
.navbarSubmitButton {
margin-left: 20px;
}
This used inside the component just adds some space between the input and submit button.
This is the NavBar component again with the help of react-bootstrap.
MainNavBar.js
import React from 'react';
import {Navbar, NavbarHeader, NavbarBrand, NavbarCollapse} from 'react-bootstrap';
import {default as Search} from './LocationSearchBox'
import styles from '../scss/components/MainNavbar.scss'
export default function MainNavbar() {
return(
<Navbar fixedTop className={styles.navbarColour} >
<NavbarBrand pullLeft >
<a href='#' className={styles.Brand}>Weather-app</a>
</NavbarBrand>
<Navbar.Collapse>
<Navbar.Form pullRight>
<Search/>
</Navbar.Form>
</Navbar.Collapse>
</Navbar>
)
}
Now I have created a homepage component and I want to use the LocationSearchBox component inside it.
Home.js
import React from 'react'
import {default as Search} from '../components/LocationSearchBox'
import styles from '../scss/components/Home.scss'
export default function Home() {
return (
<div className={styles.center}>
<h2>Enter a city and state</h2>
<Search />
</div>
)
}
The search component inside Home.js, the button has the same margin-left property was the navigation bar so it is moved to the right a bit. I don't want that to happen. I want it only to be applied to the search box used inside the navigation bar but I am unsure of how to do that with CSS modules and React components without creating a separate search box for the navigation bar but I see that as pointless when it will have the exact same code.
I feel like I am not using CSS modules correctly at all, I am not using its philosophy and the point of CSS modules correctly.
It's hard to say what the best approach would be without understanding why it needs to be visually different in those locations but generally I would update <Search /> to accept a new prop to conditionally apply the extra margin.
It could be theme if those two styles are likely to be used many times:
<FormControl type="text" placeholder="Search" />
<Button bsStyle="success" type="submit" className={props.theme === 'foo' ? styles.navbarSubmitButton : null}>Get Weather</Button>
Or if it's more of an override you could provides a buttonClassName prop to add exceptional styles at specific call sites:
<FormControl type="text" placeholder="Search" />
<Button bsStyle="success" type="submit" className={`${styles.navbarSubmitButton} ${props.buttonClassName}`}>Get Weather</Button>

Sass extending isn't working with simple example

below is both simple sass code,an Angular 2 component accessing the sass code, and the rendered HTML. In my last span element, blueBig is not working as it should. I'm new to sass and I'm not sure why this simple example is not extending properly. Can anyone shed some light on this issue for me? Thank you!
Angular2 Component
#Component({
selector: 'test',
template: `
<h1> testing sass</h1>
<span [ngClass]="{blue : true}">This should be blue</span>
<br>
<span [ngClass]="{big: true}">This should be big</span>
<br>
<span [ngClass]="{blue : true, big: true }">This should be big and blue</span>
<br>
<span [ngClass]="{blueBig : true}"> this should be big and blue as well</span>
`,
styleUrls: ['assets/scss/testing-component.scss']
})
Sass
.blue{
color:blue;
}
.big{
font-size: 200%;
}
.blueBig{
#extend .blue;
#extend .big;
}
HTML
Rendered HTML
I compiled your Sass locally and it appears to be authored correctly.
Without being able to see the rendered HTML, my guess is that Angular is converting camelcase blueBig into kebab-case blue-big. Try putting quotes around the classname, i.e.
<span [ngClass]="{'blueBig' : true}">

Resources