Comments (14)
Hi @travist
Thanks for this great library. It's exactly what we're looking for!
However, I am looking for a working custom component example, as well. I have been trying to render some html by a custom a component for 2 days with no luck.
Is it possible that you can extend the CustomComponent.ts file to make a small working example for us?
We appreciate it very much .
Thanks in advance!
Sinan
from angular-material.
Hello @JoeyHengst, @senvaitis,
this problem still occurs with the latest version. Did you find any solution or workaround to this problem?
I appreciate it a lot, if you can share your experience, solution or workaround, if you have any.
Thank you guys!
Best Regards
from angular-material.
You do not render with the Form.io component, but with this library, you actually render using the Angular Material component within the template
construct of the @component. Like so....
@Component({
template: '<-- HERE IS WHERE YOU RENDER YOUR COMPONENT -->'
})
export class MyCustomComponent extends MaterialComponent {
...
}
from angular-material.
I am also trying to render a custom component, however without success.
These are the changes I made:
CustomComponent.ts
:
import { Components, MaterialHtmlComponent } from 'angular-material-formio';
import HtmlComponent from 'formiojs/components/html/HTML.js';
import { Component } from '@angular/core'; // <--- ADDED
class HeaderComponent extends HtmlComponent {
// Custom logic goes here.
}
@Component({ // <--- ADDED
template: '<div>HALLO</div>'
})
export class MaterialHeaderComponent extends MaterialHtmlComponent {
// Custom Material logic goes here.
}
(HeaderComponent as any).MaterialComponent = MaterialHeaderComponent;
Components.addComponent('header', HeaderComponent);
app.component.html
:
<mat-card>
<!-- <mat-formio src="https://examples.form.io/kitchensink"></mat-formio> --> <!-- COMMENTED -->
<mat-formio [form]="form"></mat-formio> <!-- UNCOMMENTED -->
</mat-card>
File app.component.ts
is unchanged (tried changing/removing label, content, tag
of header
but no success):
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
form: any = {
components: [
{
type: 'textfield',
label: 'First Name',
key: 'firstName'
},
{
type: 'header',
label: 'Header',
content: 'This is a header',
tag: 'h1'
},
{
type: 'htmlelement',
tag: 'strong',
content: '{{ data.firstName }}',
refreshOnChange: true,
key: 'html'
}
]
};
onSubmit(submission:any) {
console.log(submission);
}
}
What should I do to get <div>HALLO</div>
rendered?
from angular-material.
You do not render with the Form.io component, but with this library, you actually render using the Angular Material component within the
template
construct of the @component. Like so....@Component({ template: '<-- HERE IS WHERE YOU RENDER YOUR COMPONENT -->' }) export class MyCustomComponent extends MaterialComponent { ... }
I tried this approach but the html doesn't seem to get rendered. @travist
from angular-material.
Try with the latest version. I made a change to the HTMLComponent.
from angular-material.
@travist I tried this with the latest version but it didn't seem to work.
import HtmlComponent from 'formiojs/components/html/HTML.js';
import { FormsHtmlComponent } from '../html/html.component';
import { Component } from '@angular/core';
const Components = require('formiojs/components/Components').default;
class HeaderComponent extends HtmlComponent {
// Custom logic goes here.
}
@Component({
template: '<p>HALLO</p>'
})
export class FormsCustomComponent extends FormsHtmlComponent {
// Custom Material logic goes here.
}
(HeaderComponent as any).FormsComponent = FormsCustomComponent;
Components.addComponent('custom', HeaderComponent);
It's added to the index.ts to get rendered like :
import { FormsCustomComponent } from './custom/custom.component';
// Set the components.
const components: any = {
....
custom: FormsCustomComponent
}
Results in the following error :
from angular-material.
@travist Can you maybe take a look at this? Since with the Wizard now in place. Thank you for that btw. It's for us now useless if we can't render our own custom components which are made in FormManager.
For instance we have a custom address component which content managers can drag and drop in the FormManager to create forms.
The address component is composed of :
Panel
TextField
Column
TextField TextField
TextField
TextField
We now want to render this custom component but since we are getting the above error for a custom component. We are stuck.
from angular-material.
I believe it should be...
(HeaderComponent as any).MaterialComponent = FormsCustomComponent;
from angular-material.
I believe it should be...
(HeaderComponent as any).MaterialComponent = FormsCustomComponent;
Ah yeah we renamed MaterialComponent to FormsComponent.
But I think that’s not the issue we even tried it out with a fresh checkout with the demo project and then a wizard form which contained a customcomponent without renaming anything but just use our own form in the <mat-formio>
. And we didn’t got our html being rendered. The customcomponent was detected but it didn’t show us our html we had in the template.
from angular-material.
There is really nothing different between a custom component and a regular component. The ONLY thing different is that you need to ensure you register the component using
Formio.Components.addComponent('custom', CustomComponent);
It could be that when you are getting the Components
from formiojs that you are including the wrong module that the application is not using. I have seen this before... You may try doing this...
import { Formio } from 'angular-formio';
And then
Formio.Components.addComponent(....);
If this does not work, then try importing from formiojs
. If that does not work, then try importing from angular-material-formio like this.
import { Formio } from 'angular-material-formio';
It may take some trial and error since it is hard to know which Formio.js library is getting imported by your application if there are multiple instances of the library getting pulled in.
from angular-material.
Using https://github.com/formio/angular-material-formio/blob/master/projects/angular-material-formio/src/lib/components/index.ts as a guide here's what I have that seems to work:
replace
(HeaderComponent as any).MaterialComponent = HeaderComponent;
with
const CompClass = (HeaderComponent as any);
CompClass.MaterialComponent = MaterialHeaderComponent;
CompClass.prototype.render = (function () {
if (this.materialComponent) {
return this.materialComponent;
}
const viewContainer = this.parent ? this.parent.viewContainer(this) : this.viewContainer(this);
if (!viewContainer) {
return;
}
const factory = this.options.viewResolver.resolveComponentFactory(CompClass.MaterialComponent);
const componentRef = viewContainer.createComponent(factory);
(componentRef.instance as any).setInstance(this);
});
const setValue = CompClass.prototype.setValue;
CompClass.prototype.setValue = (function (...args) {
if (this.materialComponent) {
this.materialComponent.setValue(args[0]);
}
return setValue.call(this, ...args);
});
Then follow @travist use of the Angular @Component
template to add your code. I think you can treat it as a regular Angular component from here out.
The library doesn't seem to update the renderer to the MaterialComponent automatically. There is probably a need for a angular-material-formio addComponent wrapper that does this, and I may work towards something like this as I get more comfortable with the library (assuming this isn't moot thanks to the Angular 9 upgrades).
from angular-material.
Hi @enigmatic,
thank you for the long explanation and sample code. I have done it as you described but with no luck. Nothing will be rendered. I have debugged a litte bit and I have realised that a renderComponent of HeaderComponent will be called with empty body.
Here is my final code:
import { Components, MaterialHtmlComponent } from 'angular-material-formio';
import HtmlComponent from 'formiojs/components/html/HTML.js';
import {Component} from '@angular/core';
export class HeaderComponent extends HtmlComponent {
// Custom logic goes here.
}
@Component({
template: '<div>dropzone comes here</div>'
})
export class MaterialHeaderComponent extends MaterialHtmlComponent {
// Custom Material logic goes here.
}
const CompClass = (HeaderComponent as any);
CompClass.MaterialComponent = MaterialHeaderComponent;
CompClass.prototype.render = (function () {
if (this.materialComponent) {
return this.materialComponent;
}
const viewContainer = this.parent ? this.parent.viewContainer(this) : this.viewContainer(this);
if (!viewContainer) {
return;
}
const factory = this.options.viewResolver.resolveComponentFactory(CompClass.MaterialComponent);
const componentRef = viewContainer.createComponent(factory);
(componentRef.instance as any).setInstance(this);
});
const setValue = CompClass.prototype.setValue;
CompClass.prototype.setValue = (function (...args) {
if (this.materialComponent) {
this.materialComponent.setValue(args[0]);
}
return setValue.call(this, ...args);
});
Components.addComponent('dropzone', HeaderComponent);
Do I miss here anything?
I registered MaterialHeaderComponent in entryComponents of app.module. Otherwise angular complains as follows:
ERROR Error: No component factory found for MaterialHeaderComponent. Did you add it to @NgModule.entryComponents?
from angular-material.
Odd. It works for me. I did get an error MaterialHeaderComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'nativeElement' of undefined
when extending MaterialHtmlComponent, so you can extend the new Component from MaterialComponent:
export class MaterialHeaderComponent extends MaterialComponent {
// Custom Material logic goes here.
}
The empty renderComponents function comes from MaterialComponent and shouldn't have any impact on the custom component.
Here's the full project: https://github.com/enigmatic/angular-material-formio-demo
from angular-material.
Related Issues (20)
- [BUG] SyntaxError: invalid regexp group in Firefox HOT 3
- [BUG]Date/Time Component do not show value. HOT 2
- [BUG] Extra empty item at select component HOT 3
- is it possible to use file upload in angular-formio ? [BUG] HOT 1
- [BUG] conditional in wizard page produces "this.parent.viewContainer is not a function" HOT 4
- Bootstrap dependency HOT 3
- [BUG] nextPage event in wizard not working HOT 1
- [BUG] MatFormioModule is not a reference: [object Object] HOT 6
- Update to Angular 11 HOT 2
- Placeholder for search input field in the "Select Component"
- [BUG] Custom angular component shows as Unknown Component: componentId HOT 2
- angular-formio form builder don`t work with formio/angular-material HOT 2
- Address Field Not Showing Up HOT 3
- [BUG] HOT 3
- FormioModule, MatFormioModule Lazy Loading Conflict HOT 2
- [BUG] Saved valued does not retain
- Support Angular 12 HOT 4
- [BUG] Cannot set submission in Angular 11 HOT 1
- Error on build
- FormioComponent isnot export by Module
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular-material.