Angular Hidden Ignores - javascript

I am trying to use the Hidden property in Angular2 and when I include a style that alters the display of the DIV, the hidden property is ignored.
When the code below is run, both divs are displayed.
When I remove the class .displayInline the first DIV is hidden and the second is displayed (as expected).
Can I use Hidden and the display CSS together?
import {ComponentAnnotation as Component, ViewAnnotation as View, bootstrap, NgIf} from 'angular2/angular2';
#Component({
selector: 'hello'
})
#View({
template: `<style>.displayInline{ display:inline }</style><span *ng-if="name">Hello, {{name}}!</span>
<div>
<div [hidden]="hideDiv1()" class="displayInline">should be hidden.</div>
<div [hidden]="hideDiv2()" class="displayInline">should be displayed.</div>
</div>`,
directives: [NgIf]
})
export class Hello {
name: string = 'World';
constructor() {
setTimeout(() => {
this.name = 'NEW World'
}, 2000);
}
hideDiv1(){
return true;
}
hideDiv2(){
return false;
}
}
bootstrap(Hello);
Repository:https://github.com/albi000/ng2-play

I faced similar problem with btn class of bootstrap
<button [hidden]="!visible" class="btn btn-primary">Click</button>
I solved this by adding
[hidden] {
display: none;
}
at the end of css stylesheet I use globally.
This is solved the problem for now.

Note: <span>'s default to "display: inline", you may want to use them instead.
Currently classes override [hidden]. I agree, this isn't as effective as ng-hide/ng-show and I hope it is fixed in future versions of angular2. It is currently an open on issue on the Angular2 repo.
You can overcome the problem by simply wrapping your [hidden] element with the class.
<span class="someClass">
<span [hidden]="hideDiv1()">should be hidden.</span>
</span>

You can use style.display instead of hidden if you need more fine-grained control over visibility.
<div [style.display]="active?'inherit':'none'"></div>

Related

Change Multiple CSS property from multiple CSS class dynamically in Angular

In angular, we can easily change the property of a CSS class dynamically, like if I have a class
.my-class {
background: url('..')
}
and if I used my-class as
<div class="my-class">
------
</div>
now, we can change the image effectively by using
[style.background]="url(..)"
like
<div class="my-class" [style.background]="getImageUrl()">
----
</div>
Now, can anyone tell me, is there any solutions if there's have multiple css-class and there I have to change background url all of them, how can I do it?
Like my CSS classes are
.my-class-one {
background: url('..')
}
.my-class-two {
background: url('..')
}
.my-class-three {
background: url('..')
}
and HTML code is
<div class="my-class-one my-class-two my-class-three">
----
</div>
There I need to change all background image URL by calling angular methods
getImageUrlOne()
getImageUrlTwo()
getImageUrlThree()
ngClass can be used in html
[ngClass]="{'my-class-one': getImageUrlOne(), 'my-class-two': false, 'my-class-three': false}"
JS
getImageUrlOne(){
//.... logic to decide my-class-one should be used or not
return true;
}
You can set different-different flag variable in each function and when function call then set one flag true. set ngclass as below:
<div [ngClass]="{'my-class-one': getImageUrlOne(), 'my-class-two': getImageUrlTwo(), 'my-class-three': getImageUrlThree()}">

How to handle full width with StencilJS

Let's assume we have a very simple component as below
#Component({
tag: 'custom-button',
})
export class CustomButton {
render() {
return <button class={{ 'button--blue': true }}>Press Me</button>
}
}
The component above will render as below on the DOM tree
<custom-button class="hydrated">
<button class="button--blue">Press Me</button>
</custom-button>
Now everything is working fine. The problem comes only if we define width: 100% in button--blue class. It will not work because width: 100% of custom-button is essentially pointless.
I know we can solve the problem by using Host element and applying css on it
#Component({
tag: 'custom-button',
})
export class CustomButton {
render() {
return (
<Host class={{ 'full-width': true }}><button class={{ 'button--blue': true }}>Press Me</button></Host>
)
}
}
I am looking for alternative solution, reason being we need to purposely create another generic utility css class just because we are using stencil which I feel its not optimal.
Ultimately it will be great if my CSS is not polluted and I only have button--blue class.
Wondering if there is any alternatives available? Maybe somehow we can omit custom-button element when we render to the DOM tree?

ngIf and click not working for dynamic html in angular2

ngIf and click not working for dynamic html.
when load html using innerHtml then ngIf and click event not loading.
export class FillInBlanksComponent implements OnDestroy, OnInit {
question = '';
editable = true;
ngOnInit() {
question = '<span *ngIf="editable" name="answers['+incr+']" contenteditable="true" (click)="onclick()"> </span>';
}
onClick(){
alert("clicked!!!!");
}
}
The function you're calling is (click)="onclick()" but you've defined onClick().
Another thing is, you might want to DOM Sanitize the string else you'll get a warning. Please check this answer out on how to do that.
check you have done spelling mistake use (click)="onClick()"
you are using small c in your function call

How to define css styles for a vue.js component when registering that component?

I am able to register a custom vue.js component with
// register
Vue.component('my-component', {
template: '<div class="my-class">A custom component!</div>'
})
Also see https://v2.vuejs.org/v2/guide/components.html
How can I include css classes for my component?
I would expect something like
Vue.component('my-component', {
template: '<div class="my-class">A custom component!</div>',
css: '#... my css stylesheet...'
})
but there does not seem to be a css option.
I know that I could
a) define all css classes in a global css stylesheet or
b) use singe-file-vue-components (would require build tool supporing *.vue files, see https://v2.vuejs.org/v2/guide/single-file-components.html)
but I would prefer to
c) specify a css stylesheet for the component when registering the component.
=> How to do so?
there does not seem to be a css option.
That is correct. You cannot do what you describe. The documentation on single file components is pretty clear that one of the advantages is that you can do this with them and cannot do it without them.
In many Vue projects, global components will be defined using
Vue.component, followed by new Vue({ el: '#container' }) to target a
container element in the body of every page.
This can work very well for small to medium-sized projects, where
JavaScript is only used to enhance certain views. In more complex
projects however, or when your frontend is entirely driven by
JavaScript, these disadvantages become apparent:
[...]
No CSS support means that while HTML and JavaScript are
modularized into components, CSS is conspicuously left out
Here is a way to achieve what you're looking for:
export const ContactUs = Vue.component(
'mycomponent-contact-us'
,{
props: {
backgroundColor: {
type: String
,required: false
,default: "red"
}
}
,data: function(){
return {
}
}
,template: `
<div>
<span class='contact_us_text' >Contact Us Component and its bg color will be {{backgroundColor}}</span>
</div>
`
,mounted: function(){
var css_text = `
.contact_us_text{
color: `+this.backgroundColor+`;
}
`;
var css = document.createElement('style');
css.type='text/css';
css.setAttributeNode( document.createAttribute('scopped') );
css.appendChild( document.createTextNode( css_text ) );
this.$el.appendChild( css );
}
}
);
Its true that you cannot add <style> inside a Vue template or add CSS within
component directly, unless you bind it or define your css globally. But you can create a custom component that will dynamically do it for you. sample
Keep in mind that Vue components are effectively macros.
Where render is the substitution function, and the vueDefinition (defn3 below) is effectively a class for the given tagName.
A template is just a convenient syntactic-sugar shorthand that will be compiled (with some vue-usage pattern restrictions) into a render function if you don't provide your own render function.
const defn3 = {
tagName: 'ae-css',
mounted() {
const vueDefinition = this.$options;
this.$el.appendChild(document.createTextNode(vueDefinition.css));
},
css: `
* {
color: blue;
}
`,
render(h) {
return h('style');
}
}
Vue.component(defn3.tagName, defn3);
With that solution in hand, there are a number of good reasons why you probably don't want something as simplistic as what I just provided.
Namely, you want to have your css modularized such that it does not affect any aspects of your page you did not intend it to. For that, you either need carefully designed css rules with your intended inheritance and scope; probably using a class=... But a better approach would be to just use Vue's facilities that offer similar capabilities automatically.
If you want to use modern browser architecture capabilities for this, then you might want your components to be real browser DOM WebComponents that make use of the shadowDOM and keep your internal elements and styles encapsulated within a shadowRoot. See this library, for doing that in Vue.
You can embed a style tag within your template root element:
Vue.component('my-component', {
template: `
<div class="my-class" my-component>
A custom component!
<style>
.my-class[my-component] {
// ... my-component styles
}
</style>
</div>
`
})
Try this:
this.$el.style.cssText = "border: 5px solid blue;"

Weird behaviour querySelector

I have component in angular
in component.ts i have line of code that serach html element
var myArticle = document.querySelector('article');
this return null
in component.html
<article id="bodyArticle" *ngIf="isClicked"></article>
but when I use article in sibling component.ts
var myArticle != null from component.ts
How it's work querySelector serach element in all file project ?
I also have other problem. In same componen.html i have button
<div class="btnGrp">
<button (click)="loadXML($event)">Load</button>
<input type="file" name="img" multiple (change)="onChange($event)">
</div>
<article id="bodyArticle" *ngIf="isClicked"></article>
When i click button one click emitted is value true firstly and i must click second to button to load thata to article content
snippet from component.ts
loadXML(event?: Event) {
var myArticle = document.querySelector('article');
console.log(myArticle);
if(this.imageService.getBodyRes() == ''){
myArticle.textContent = 'Error can't load data';
this.isClicked = true;
this.xmlLoadedEvent.emit(this.isClicked);
} else {
myArticle.textContent = this.imageService.getBodyRes();
console.log(myArticle.textContent);
this.isClicked = true;
this.xmlLoadedEvent.emit(this.isClicked);
}
}
How to do that when i click button in article tag ngIf set true value and also loadData without dobule click.
Try to avoid using the document object and its methods in Angular. It will make your life very difficult if you try to do that.
<article #articleId id="bodyArticle" *ngIf="isClicked"></article>
You can put a template variable name on the article tag, and then query it with angular's 'ViewChild' class like so -
import { Component, ViewChild, ElementRef, ...others?....} from '#angular/core'
export class MyComponent {
articleToggle: boolean = false; // add a toggle in your component for turning the article on
#ViewChild('articleId') article: ElementRef;
ngAfterViewInit() {
this.article.nativeElement.<<access DOM attributes here>>
}
}
This will give you access to the DOM node, like you expected your document query to have done, but even so, there are probably still better ways to do what you are doing, especially since you mentioned you are trying to use the article in sibling components. If that is the case, you may want to make it its own component allowing you to avoid queries altogether, but again, impossible to know with so little info.
Also, its generally recommended to avoid comparing to null entirely in typescript. Use 'undefined' instead.
<button (click)="loadXML($event); articleToggle = true">Load</button>
Set your variable to true on click, and then for the article.
<article #articleId id="bodyArticle" *ngIf="articleToggle"></article>
Now it will appear after the first click of the button, as that will be the only time the value changes from false -> true.

Categories

Resources