I am trying to open the Select file dialog box when clicking on the button, It is possible using this.$refs.fileInput.click() in VUE, but this is not working in composition API.
Here is the code for reference: https://codepen.io/imjatin/pen/zYvGpBq
Script
const { ref, computed, watch, onMounted, context } = vueCompositionApi;
Vue.config.productionTip = false;
Vue.use(vueCompositionApi.default);
new Vue({
setup(context) {
const fileInput = ref(null);
const trigger = () => {
fileInput.click()
};
// lifecycle
onMounted(() => {
});
// expose bindings on render context
return {
trigger,fileInput
};
}
}).$mount('#app');
Template
<div id="app">
<div>
<div #click="trigger" class="trigger">Click me</div>
<input type="file" ref="fileInput"/>
</div>
</div>
Thank you.
Have you tried to access it using context.refs.fileInput.click();?
Don't forget that it's setup(props, context) and not setup(context).
Try my edit here: https://codepen.io/ziszo/pen/oNxbvWW
Good luck! :)
I'm working in Vue 3 CLI and have tried several different recommendations and found the following to be the most reliable.
<template>
<input class="btnFileLoad" type="file" ref="oFileHandler" #change="LoadMethod($event)" />
<button class="btn" #click="fileLoad">Load</button>
</template>
<script>
import {ref} from "vue";
export default{
setup(){
const hiddenFileElement = ref({})
return {hiddenFileElement }
}
methods:{
fileLoad() {
this.hiddenFileElement = this.$refs.oFileHandler;
this.hiddenFileElement.click();
},
}
}
</script>
<style>
.btn{ background-color:blue; color:white; }
.btnFileLoad{ display:none }
</style>
I also discovered in Chrome that if the call from the button element to the hidden file handler takes to long, an error message that reads "File chooser dialog can only be shown with a user activation." is displayed in the source view. By defining the hiddenFileElement in setup the problem went away.
I created a default Vue project with the Vue CLI, and got an embed code sent to my email for Font Awesome 5. I added that code to my project index.html in the public folder.
<head>
<script src="https://use.fontawesome.com/8e1c33adc2.js"></script>
</head>
I'm using this in a component template:
<i class="fas fa-trash"></i>
It just shows up as a box.
Do I have to do something special to get the embed code to work in my Vue component, like adding it to main.js?
I have had issues with font-awesome with vue. The solution for my problem was to use vue-fontawesome components.
For example, I used font-awesome the following way
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
import { faAngleDown } from '#fortawesome/free-solid-svg-icons'
import { faAngleUp } from '#fortawesome/free-solid-svg-icons'
export default {
name: 'Timer',
props: {
msg: String
},
components:{
FontAwesomeIcon
},
data: function(){
return {
selected_interval: null,
intervalID: null,
buttonText: "Start",
isStart: true,
isStop: false,
toggleAngle: faAngleDown,
},
methods: {
dropdown_toggle: function(event) {
event.stopPropagation()
let dropdown = document.querySelector('#pomodoro-dropdown');
dropdown.classList.toggle("is-active")
if(this.toggleAngle == faAngleDown){
this.toggleAngle = faAngleUp
}
else{
this.toggleAngle = faAngleDown
}
}
}
and used the componenent-
<font-awesome-icon :icon="toggleAngle" />
hope this helps.
I got it working by logging into Font Awesome and using the free kit code from https://fontawesome.com/kits.
All I needed was this in the head section of index.html:
<head>
<script src="https://kit.fontawesome.com/[kit code].js" crossorigin="anonymous"></script>
</head>
you have to add the css file of font-awesome.you can open developer tools and see there is no class with the <i></i>
I try to include a bot developed with landbot.io in my nuxt web app (NUXT.js framework).
Below, there is the code that the landbot's guide provides me.
Code to include:
<script src="https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js"></script>
<div id="myLandbot" style="width: 100%; height: 500px"></div>
<script>
var myLandbot = new LandbotFrameWidget({
container: '#myLandbot',
index: 'https://landbot.io/u/..../index.html',
});
</script>
But i don't know what i should do with the second script tag because i always get this error:
"LandbotFrameWidget do not definied"
I include the first script tag in nuxt.config.js like that:
head: {
script: [
{ src: 'https://static.landbot.io/umicore/UmiAccessPoint.js' },
{ src: 'https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js' }
]
}
Your nuxt.config.js config is correct, but the first script src is not needed.
I've created a working example in this codesandbox, take a look at the code used in the index.vue file:
<template>
<section>
<div>
<div id="myLandbot" style="width: 100vw; height: 100vh"></div>
</div>
</section>
</template>
<script>
export default {
mounted() {
var myLandbot = new LandbotFrameWidget({
container: "#myLandbot",
index: "https://landbot.io/u/H-117144-ZGUSSI5IM2OI5NYH/index.html"
});
}
};
</script>
Hope it helps!
I am trying to apply the html from my internal text/ng-template script tag. but it's fails to work. how to apply html from the script tag?
Here is my code and html:
js part :
//our root app component
import {Component} from 'angular2/core'
#Component({
selector: 'my-app',
providers: [],
templateUrl: "template.html", //this is the id.
directives: []
})
export class App {
public title = "My Title";
private userName = "Test Name";
constructor() {
this.name = 'Angular2'
}
}
HTML part :
<body>
<my-app>loading...</my-app>
//template declared
<script type="text/ng-template" id="template.html">
<h2>{{title}}</h2>
<div>
<h2>Hello {{name}}</h2>
<h2>{{userName}}</h2>
</div>
</script>
</body>
I am getting a error :
Failed to load template.html
What is the correct way to use it?
Unfortunately, this is not, nor will be, supported in Angular 2 :\ https://github.com/angular/angular/issues/6126
In Angular 1.x, we could insert HTML in real-time by using the HTML tag ng-bind-html, combined with the JavaScript call $sce.trustAsHTML(). This got us 80% of th way there, but wouldn't work when Angular tags were used, such as if you inserted HTML that used ng-repeat or custom directives.
To get that to work, we could use a custom directive that called $compile.
What is the equivalent for all of this in Angular 2? We can bind using [inner-html] but this only works for very simple HTML tags such as <b>. It doesn't transform custom angular 2 directives into functioning HTML elements. (Much like Angular 1.x without the $compile step.) What is the equivalent of $compile for Angular 2?
In Angular2 you should use DynamicComponentLoader to insert some "compiled content" on the page. So for example if you want to compile next html:
<div>
<p>Common HTML tag</p>
<angular2-component>Some angular2 component</angular2-component>
</div>
then you need to create component with this html as a template (let's call it CompiledComponent) and use DynamicComponentLoader to insert this component on the page.
#Component({
selector: 'compiled-component'
})
#View({
directives: [Angular2Component],
template: `
<div>
<p>Common HTML tag</p>
<angular2-component>Angular 2 component</angular2-component>
</div>
`
})
class CompiledComponent {
}
#Component({
selector: 'app'
})
#View({
template: `
<h2>Before container</h2>
<div #container></div>
<h2>After conainer</h2>
`
})
class App {
constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {
loader.loadIntoLocation(CompiledComponent, elementRef, 'container');
}
}
Check out this plunker
UPD You can create component dynamically right before the loader.loadIntoLocation() call:
// ... annotations
class App {
constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {
// template generation
const generatedTemplate = `<b>${Math.random()}</b>`;
#Component({ selector: 'compiled-component' })
#View({ template: generatedTemplate })
class CompiledComponent {};
loader.loadIntoLocation(CompiledComponent, elementRef, 'container');
}
}
I personally don't like it, it's look like a dirty hack to me. But here is the plunker
PS Beware that at this moment angular2 is under active development. So situation can be changed at any time.
DynamicComponentLoader is deprecated, you can use ComponentResolver instead
You could use this directive, add pipes if you need additional data manipulation. It also allows for lazy loading, you don't need it in your case, but it's worth mentioning.
Directive(I found this code and made some changes, you can do that too to make it fit your taste or use it as is):
import { Component, Directive, ComponentFactory, ComponentMetadata, ComponentResolver, Input, ReflectiveInjector, ViewContainerRef } from '#angular/core';
declare var $:any;
export function createComponentFactory(resolver: ComponentResolver, metadata: ComponentMetadata): Promise<ComponentFactory<any>> {
const cmpClass = class DynamicComponent {};
const decoratedCmp = Component(metadata)(cmpClass);
return resolver.resolveComponent(decoratedCmp);
}
#Directive({
selector: 'dynamic-html-outlet',
})
export class DynamicHTMLOutlet {
#Input() htmlPath: string;
#Input() cssPath: string;
constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) {
}
ngOnChanges() {
if (!this.htmlPath) return;
$('dynamic-html') && $('dynamic-html').remove();
const metadata = new ComponentMetadata({
selector: 'dynamic-html',
templateUrl: this.htmlPath +'.html',
styleUrls: [this.cssPath]
});
createComponentFactory(this.resolver, metadata)
.then(factory => {
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.vcRef.createComponent(factory, 0, injector, []);
});
}
}
Example how to use it:
import { Component, OnInit } from '#angular/core';
import { DynamicHTMLOutlet } from './../../directives/dynamic-html-outlet/dynamicHtmlOutlet.directive';
#Component({
selector: 'lib-home',
templateUrl: './app/content/home/home.component.html',
directives: [DynamicHTMLOutlet]
})
export class HomeComponent implements OnInit{
html: string;
css: string;
constructor() {}
ngOnInit(){
this.html = './app/content/home/home.someTemplate.html';
this.css = './app/content/home/home.component.css';
}
}
home.component.html:
<dynamic-html-outlet [htmlPath]="html" [cssPath]="css"></dynamic-html-outlet>
After reading a lot, and being close of opening a new topic I decided to answer here just to try to help to others. As I've seen there are several changes with the latest version of Angular 2. (Currently Beta9)
I'll try to share my code in order to avoid the same frustration I had...
First, in our index.html
As usual, we should have something like this:
<html>
****
<body>
<my-app>Loading...</my-app>
</body>
</html>
AppComponent (using innerHTML)
With this property you will be able to render the basic HTML, but you won't be able to do something similar to Angular 1.x as $compile through a scope:
import {Component} from 'angular2/core';
#Component({
selector: 'my-app',
template: `
<h1>Hello my Interpolated: {{title}}!</h1>
<h1 [textContent]="'Hello my Property bound: '+title+'!'"></h1>
<div [innerHTML]="htmlExample"></div>
`,
})
export class AppComponent {
public title = 'Angular 2 app';
public htmlExample = ' <div>' +
'<span [textContent]="\'Hello my Property bound: \'+title"></span>' +
'<span>Hello my Interpolated: {{title}}</span>' +
'</div>'
}
This will render the following:
Hello my Interpolated: Angular 2 app!
Hello my Property bound: Angular 2 app!
Hello my Interpolated: {{title}}
AppComponent Using DynamicComponentLoader
There is a little bug with the docs, documented in here. So if we have in mind that, my code should look now like this:
import {DynamicComponentLoader, Injector, Component, ElementRef, OnInit} from "angular2/core";
#Component({
selector: 'child-component',
template: `
<div>
<h2 [textContent]="'Hello my Property bound: '+title"></h2>
<h2>Hello my Interpolated: {{title}}</h2>
</div>
`
})
class ChildComponent {
title = 'ChildComponent title';
}
#Component({
selector: 'my-app',
template: `
<h1>Hello my Interpolated: {{title}}!</h1>
<h1 [textContent]="'Hello my Property bound: '+title+'!'"></h1>
<div #child></div>
<h1>End of parent: {{endTitle}}</h1>
`,
})
export class AppComponent implements OnInit{
public title = 'Angular 2 app';
public endTitle= 'Bye bye!';
constructor(private dynamicComponentLoader:DynamicComponentLoader, private elementRef: ElementRef) {
// dynamicComponentLoader.loadIntoLocation(ChildComponent, elementRef, 'child');
}
ngOnInit():any {
this.dynamicComponentLoader.loadIntoLocation(ChildComponent, this.elementRef, 'child');
}
}
This will render the following:
Hello my Interpolated: Angular 2 app!
Hello my Property bound: Angular 2 app!
Hello my Property bound: ChildComponent title
Hello my Interpolated: ChildComponent title
End of parent: Bye bye!
I think all you have to do is set the element you want to have compiled html with the [innerHTML]="yourcomponentscopevar"
Angular provided DynamicComponentLoader class for loading html dynamically. DynamicComponentLoader have methods for inserting components. loadIntoLocation is one of them for inserting component.
paper.component.ts
import {Component,DynamicComponentLoader,ElementRef,Inject,OnInit} from 'angular2/core';
import { BulletinComponent } from './bulletin.component';
#Component({
selector: 'paper',
templateUrl: 'app/views/paper.html'
}
})
export class PaperComponent {
constructor(private dynamicComponentLoader:DynamicComponentLoader, private elementRef: ElementRef) {
}
ngOnInit(){
this.dynamicComponentLoader.loadIntoLocation(BulletinComponent, this.elementRef,'child');
}
}
bulletin.component.ts
import {Component} from 'angular2/core';
#Component({
selector: 'bulletin',
templateUrl: 'app/views/bulletin.html'
}
})
export class BulletinComponent {}
paper.html
<div>
<div #child></div>
</div>
Few things you need to take care of :
Don't call loadIntoLocation inside the constructor of class . Component view is not yet created when component constructor is called. You will get error -
Error during instantiation of AppComponent!. There is no component
directive at element [object Object]
Put anchorName #child in html otherwise you will get error.
Could not find variable child
Have a look at this module https://www.npmjs.com/package/ngx-dynamic-template
After a long research, only this thing helped me. The rest of the solutions seems to be outdated.