Global css rules in ionic 2 does not work - sass

I'm trying to declare some basic css rules to use them globally in my app. Like pull-rx, pull-lx and so on...
After writing these rules into app.scss, the main.css file inside the build folder gets updated correctly, but when it comes to use one of these rules inside a "LoginPage" for example, each of the rules I've declared before are ignored. Am I missing something?
If I write the pull-rx class inside the login.scss file instead, it will work. Is there a way to get a class globally?
app.scss:
.pull-rx {
float: right !important
}
.pull-lx{
float: left !important
}
app.module.ts:
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { LoginPage } from '../pages/login/login';
#NgModule({
declarations: [
MyApp,
HomePage,
LoginPage,
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
LoginPage,
],
providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
})
export class AppModule { }
login.html:
<ion-header>
<ion-navbar>
<ion-title>
Astrid <small><i>Beta</i></small> <span class="pull-rx">Login</span>
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>

I've figured this out. Since Ionic uses scsss as preprocessor, I have to set the semicolons ";" at the end of the rule. Since I am used to code in sass that were causing the problem.

Related

Can't bind to 'formGroup' since it isn't a known property of 'form' whilst using SharedModule

I've had this error lots of times and I've always been able to fix it but I think I'm overlooking something this time and I can't get it too work.
As stated in the title, the error I get is Can't bind to 'formGroup' since it isn't a known property of 'form'. for the following line of code: <form [formGroup]="contactSettings">.
I already checked all stackoverflow posts but they all come down to add the ReactiveFormsModule to the module that makes use of ReactiveForms. In my case, which was also in various stackoverflow posts, I should export the ReactiveFormsModule in my SharedModule and import that SharedModule in my ContactModule that actually uses the ReactiveFormsModule. I don't see what I'm doing wrong.
contact-settings.component.html
<form [formGroup]="contactSettings">
</form>
contact-settings.component.ts
export class ContactSettingsComponent extends FormComponent {
contactSettings: FormGroup = this.fb.group({ //Moving this to constructor or onInit does not fix it
firstName: ["First name"],
lastName: ["Last name"],
emailAdress: ["email", Validators.email],
gender: ["male"],
parentCustomerId: ["Parent customer name"],
language: ["Language"],
telephone: ["Telephone number"],
mobilephone: ["Mobile phone number"],
});
constructor(private fb: FormBuilder, private contactService: ContactService) {
super();
}
}
contact.module.ts
... //imports
#NgModule({
declarations: [
ContactSettingsComponent
],
imports: [
ContactRoutingModule,
SharedMaterialModule, // <--- contains export ReactiveFormsModule and FormsModule
SharedComponentsModule
]
})
export class ContactModule { }
shared-material.module.ts
... //Angular Material imports
//CommonModule
import { CommonModule } from "#angular/common";
//Forms
import { ReactiveFormsModule, FormsModule } from "#angular/forms";
//Browser
import { BrowserAnimationsModule } from "#angular/platform-browser/animations";
import { BrowserModule } from "#angular/platform-browser";
#NgModule({
//Normally imports are here, but the template I bought does not have this and adding it doesn't fix it either. It worked normally before.
exports: [
//CommonModule
CommonModule,
//Browser animations
BrowserModule,
BrowserAnimationsModule,
//Forms
ReactiveFormsModule, // <--- clearly present here
FormsModule,
//Angular Material Modules
...
]
})
export class SharedMaterialModule {}
My imports were done perfectly. The problem was that my ContactModule was never used in any other module. I had to add load the ContactModule by adding the following code block to my app-routing.module.
{
path: 'contact',
loadChildren: () => import('./views/contact/contact.module').then(m => m.ContactModule)
}

JHipster: I can't add thiered party dependency like 'angular-2-dropdown-multiselect'

I have added angular2-dropdown-multiselect in Jhipster angular part. Its not working perfectly as per the angular2-dropdwon-multi select or ngx-treeview I have added the dependency using
npm install angular2-multiselect-dropdown --save
Then I have added the same into app.module.ts
import { AngularMultiSelectModule } from 'angular2-multiselect-dropdown/angular2-multiselect-dropdown';
#NgModule({
// ...
imports: [
AngularMultiSelectModule,
]
// ...
})
Then Try this following example
import { Component, OnInit } from '#angular/core';
export class AppComponent implements OnInit {
dropdownList = [];
selectedItems = [];
dropdownSettings = {};
ngOnInit(){
this.dropdownList = [
{"id":1,"itemName":"India"},
{"id":2,"itemName":"Singapore"},
{"id":3,"itemName":"Australia"},
{"id":4,"itemName":"Canada"},
{"id":5,"itemName":"South Korea"},
{"id":6,"itemName":"Germany"},
{"id":7,"itemName":"France"},
{"id":8,"itemName":"Russia"},
{"id":9,"itemName":"Italy"},
{"id":10,"itemName":"Sweden"}
];
this.selectedItems = [
{"id":2,"itemName":"Singapore"},
{"id":3,"itemName":"Australia"},
{"id":4,"itemName":"Canada"},
{"id":5,"itemName":"South Korea"}
];
this.dropdownSettings = {
singleSelection: false,
text:"Select Countries",
selectAllText:'Select All',
unSelectAllText:'UnSelect All',
enableSearchFilter: true,
classes:"myclass custom-class"
};
}
onItemSelect(item:any){
console.log(item);
console.log(this.selectedItems);
}
OnItemDeSelect(item:any){
console.log(item);
console.log(this.selectedItems);
}
onSelectAll(items: any){
console.log(items);
}
onDeSelectAll(items: any){
console.log(items);
}
}
with HTML
<angular2-multiselect [data]="dropdownList" [(ngModel)]="selectedItems"
[settings]="dropdownSettings"
(onSelect)="onItemSelect($event)"
(onDeSelect)="OnItemDeSelect($event)"
(onSelectAll)="onSelectAll($event)"
(onDeSelectAll)="onDeSelectAll($event)">
</angular2-multiselect>
But after runing yarn serve
it just showing
Please help me
I had a similar problem with another third party library (ngx-treeview) and I also was only getting the html component empty and with no errors in the javascript console.
It was solved after importing the third party library properly following the JHipster project structure. If you want to use an external module in more than one module component, which is common, you need to configure it in shared-libs.module.ts and also add it to imports and to the exports on its #NgModule configuration.
src\main\webapp\app\shared\shared-libs.module.ts
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { CommonModule } from '#angular/common';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { NgJhipsterModule } from 'ng-jhipster';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { CookieModule } from 'ngx-cookie';
import { FontAwesomeModule } from '#fortawesome/angular-fontawesome';
import { TreeviewModule } from 'ngx-treeview';
#NgModule({
imports: [
NgbModule.forRoot(),
NgJhipsterModule.forRoot({
alertAsToast: false,
i18nEnabled: true,
defaultI18nLang: 'en'
}),
InfiniteScrollModule,
CookieModule.forRoot(),
FontAwesomeModule,
TreeviewModule.forRoot() // new third party lib import
],
exports: [FormsModule, CommonModule, NgbModule, NgJhipsterModule,
InfiniteScrollModule, FontAwesomeModule,
TreeviewModule] // new third party lib export
})
export class MyProjectSharedLibsModule {}
Share-libs module is generated by Jhipster and it is by default imported in shared.module which is imported by app.module and also the other modules that are created at start by Jhipster. For more about project structure: https://www.jhipster.tech/using-angular/
However, if you create a new angular module component you need to add the shared module in the imports to be able to use the third parties libraries there.
#NgModule({
...
imports: [MyProjectSharedModule,
RouterModule.forChild([HOME_ROUTE])],
..
})
export class MyProjectAnotherModule {}

Angular CLI - How to reference image paths in reusable components

Need help figuring out how to include images in a reusable component that is referenced in another app.
For example, I have an Angular App, let's call it UI-Common, that contains common components and another Angular App, let's call it Command-Center, that will use those common components.
In UI-Common, there is a component called my-control.component that is defined as follows:
[my-control.component.html]
<div>
<img src="assets/images/myImage.png"/>
<div class"username" *ngIf="user">
<p><strong>{{user.companyName}}</strong></p>
<p>{{user.firstName + ' ' + user.lastName}}</p>
</div>
[my-control.component.ts]
import { Component, Input } from '#angular/core';
import { User } from '../../models/user';
#Component({
selector: 'my-control',
templateUrl: './my-control.component.html',
styleUrls: ['./my-control.component.scss'],
})
export class MyControlComponent {
#Input() user: User;
constructor() {
}
}
In Command-Center, it adds UI-Common as a dependency in the package.json. A Command-Center component is created and uses my-control.component as follows:
[app.module.ts]
...
import { HomeComponent } from './home/home.component';
import { MyControlComponent } from 'ui-common';
#NgModule({
declarations: [
...,
HomeComponent,
MyControlComponent,
...
],
...
})
export class AppModule { }
[home.component.html]
<my-control [user]=user></my-control>
<div class="homeContent">
blah blah blah...
</div>
[home.component.ts]
import { Component } from '#angular/core';
import { User } from 'ui-common';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent {
user: User;
constructor() {
this.user = new User();
this.user.companyName = 'iHeartMedia';
this.user.firstName = 'John';
this.user.lastName = 'Smith';
}
}
The problem is the image on my-control when running from Command-Center does not load at all. This appears to be because the image path being used "assets/images/myImage.png" does not exist in Command-Center. I don't want to save a copy of the image in the Command-Center's assets folder. How do I properly handle images in the common component?
Found this Angular CLI feature request: https://github.com/angular/angular-cli/issues/3555
The Angular app can be configured to copy files from a relative file path to a folder within the app's distribution directory. This allows us to get access to images from within the node_modules folder without having to manually copy the images into the local assets folder.
After updating to the latest version of Angular CLI (1.2.1) I modified my angular-cli.json file as follows:
{
...
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico",
"version.txt",
{
"glob": "**/*",
"input": "../node_modules/ui-common/src/assets/images",
"output": "./assets/images"
}
],
...
}
Now all images that are in the UI-Common app are accessible to the Command-Center app.
More details about the configuration here: https://github.com/angular/angular-cli/wiki/stories-asset-configuration
import {APP_BASE_HREF} from '#angular/common';
#NgModule({
declarations: [ ... ],
imports: [ ... ],
providers: [{provide: APP_BASE_HREF, useValue : '/' }]
]);
I think you need to do something like this for the module you want to to use the image in.

How to display images only when loaded [duplicate]

I'm using ion-img in my ionic2 application to load my pictures correctly. However, I wonder if there is a way to indicate to the user that the picture is actually loading.
Thank you for your help!
EDIT : Here is the answer if you absolutely need to use the ion-img tag. If not, you should use ionic-image-loader as AdminDev826 suggested.
I finally solved that problem with CSS! When an image is loading in ionic 2, the ion-img tag doesn't have any class. However, when the image is finally loaded, the ion-img tag get the class "img-loaded".
Here is my solution :
<ion-img [src]="img.src"></ion-img>
<ion-spinner></ion-spinner>
And my CSS :
.img-loaded + ion-spinner {
display:none;
}
I hope it can help someone!
I finally solved that problem with CSS! When an image is loading in ionic 2, the ion-img tag doesn't have any class. However, when the image is finally loaded, the ion-img tag get the class "img-loaded".
Here is my solution :
<ion-img [src]="img.src"></ion-img>
<ion-spinner></ion-spinner>
And my CSS :
.img-loaded + ion-spinner {
display:none;
}
I hope it can help someone!
If you want to use the img tag instead of ion-img here is the solution:
<img src="{{image.src}}" (load)="loaded = true" [ngClass]="{'img-loaded':loaded}" [hidden]="!loaded" *ngIf="image_exists" />
<ion-spinner [ngClass]="{'center':true}" *ngIf="!loaded"></ion-spinner>
In your CSS file you should write the following:
.img-loaded + ion-spinner {
display:none;
}
// .center in my case to make the spinner at the center
.center{
margin-left: auto;
margin-right: auto;
display: block;
}
loaded is a boolean variable with false default value you have to define in your component.
Please use ionic-image-loader plugin
Install the NPM Package
npm install --save ionic-image-loader
Install Required Plugins
npm i --save #ionic-native/file
ionic plugin add cordova-plugin-file --save
npm i --save #ionic-native/transfer
ionic plugin add cordova-plugin-file-transfer --save
Import IonicImageLoader module
Add IonicImageLoader.forRoot() in your app's root module
import { IonicImageLoader } from 'ionic-image-loader';
// import the module
#NgModule({
...
imports: [
IonicImageLoader.forRoot()
]
})
export class AppModule {}
Then add IonicImageLoader in your child/shared module(s)
import { IonicImageLoader } from 'ionic-image-loader';
#NgModule({
...
imports: [
IonicImageLoader
]
})
export class SharedModule {}
Your solution is not the best one because the app still downloads all the images, For example in a Facebook like app, You will be downloading all the images from the Feed to your app, This will make everything super slow.
Use this:
https://github.com/NathanWalker/ng2-image-lazy-load
ionic-image-loader not works in ionic4+. You must create a component:
HTML
<ion-spinner name="dots" [hidden]="viewImage" color="primary"></ion-spinner>
<ion-img #image alt=""(ionImgDidLoad)="loadImage()" (ionError)="errorLoad()"></ion-img>
Typescript
#Component({
selector: 'preloader-img',
templateUrl: './preloader-img.component.html',
styles: [`
ion-spinner {
display: block;
margin: auto;
}
`],
})
export class PreloaderImgComponent implements AfterViewInit {
viewImage = false;
#Input() url: string;
#ViewChild('image', { static: false }) imageRef: IonImg;
ngAfterViewInit() {
this.imageRef.src = this.url;
}
loadImage() {
this.viewImage = true;
}
errorLoad() {
this.imageRef.src = '<your_default_img>';
}
}

Mdl-Select won't expand contract

so I'm stumped! I decided to try the Mdl-Select but the select stays permanently expanded and refuses to contract. My first thought was that something was installed incorrectly specifically the popover which I assume manages that part.
here is what I am doing.
app.module.ts
import { MdlModule } from '#angular-mdl/core'
import { MdlPopoverModule } from '#angular-mdl/popover';
import { MdlSelectModule } from '#angular-mdl/select';
systemjs.config.ts
'#angular-mdl/core': 'npm:#angular-mdl/core/bundle/core.js',
'#angular-mdl/popover': 'npm:#angular-mdl/popover/index.umd.js',
'#angular-mdl/select': 'npm:#angular-mdl/select/index.umd.js'
app.module.ts (which is consumed by main.ts)
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MdlModule } from '#angular-mdl/core'
import { MdlPopoverModule } from '#angular-mdl/popover';
import { MdlSelectModule } from '#angular-mdl/select';
#NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
routing,
MdlModule,
MdlPopoverModule,
MdlSelectModule
]
app.component.html
<div>
<mdl-select [(ngModel)]="user.SelectedFeature" placeholder="Feature">
<mdl-option [value]><em>-- Select a Feature --</em></mdl-option>
<mdl-option *ngFor="let feature of features" [value]="feature">{{feature}}</mdl-option>
</mdl-select>
</div>
features is a string[]
I am pretty much stumped here on what else to do... obviously I have other modules imported but nothing that isn't generic.
no errors are thrown.
The issue was I missed adding the extra imports in my style sheet
issue resolved by adding the following to style.css
#import '~#angular-mdl/popover/popover';
#import '~#angular-mdl/select/select';

Resources