dschnelldavis / angular2-json-schema-form

Angular 2 JSON Schema Form builder
MIT License
285 stars 177 forks source link

Cannot import WidgetLibraryService #49

Open qazq opened 7 years ago

qazq commented 7 years ago

Version: v0.4.0-alpha.7

import { WidgetLibraryService } from 'angular2-json-schema-form';

The error message is has no exported member 'WidgetLibraryService'.

If I use...

import { WidgetLibraryService } from 'angular2-json-schema-form/src/widget-library/widget-library.service';

It can build success, but will get the same error if I use WidgetLibraryService in constructor

constructor(private widgetLibrary: WidgetLibraryService) {}

My project is create by ng create with angular-cli 1.1.0

{
  "name": "angular4",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.0.0",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.1.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.1.0",
    "@angular/compiler-cli": "^4.0.0",
    "@angular/language-service": "^4.0.0",
    "@types/jasmine": "2.5.45",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "protractor": "~5.1.2",
    "ts-node": "~3.0.4",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}
Sebastian-Fitzner commented 7 years ago

Same problem here ... Workaround is to use import { ɵb } from 'angular2-json-schema-form'; .

yovin99 commented 7 years ago

@Sebastian-Fitzner were you able to register a custom component / widget and use it with angular2-json-schema-form. I tried but it didn't work. much appreciate if you can give me some details on how we can use these custom widgets to populate

Sebastian-Fitzner commented 7 years ago

@yovin99 yes i was able to build a whole custom framework with this lib. Unfortunately it did not scale well so I decided to create my own lib.

But here is a short description how you can achieve that:

Create your custom widgets

const customWidgets = {
    'input': BBInputComponent,
    'email': BBEmailComponent,
    'select': BBSelectComponent,
    'checkbox': BBCheckboxComponent,
    // 'checkboxes': BBCheckboxesComponent,
    'radio': BBRadioComponent,
    'input-norway': BBInputNorwayComponent,
    'fieldset': BBFieldsetComponent,
    'wizard': BBWizardComponent,
    'wizard-step': BBWizardStepComponent,
    'submit': BBSubmitComponent
};

Add custom widgets to declarations and entryComponents in your ngModule:

@NgModule({
    imports: [
        RouterModule,
        CommonModule,
        BrowserModule,
        FormsModule,
        ReactiveFormsModule,
        JsonSchemaFormModule
    ],
    declarations: [
        // Components
        DynamicFormComponent,
        // Forms
        BBFormFrameworkComponent,
        BBInputComponent,
        BBEmailComponent,
        BBSelectComponent,
        BBCheckboxComponent,
        BBRadioComponent,
        BBSchemaFormComponent,
        BBRootComponent,
        BBSelectFrameworkComponent,
        BBSelectWidgetComponent,
        BBFieldsetComponent,
        BBWizardComponent,
        BBWizardStepComponent,
        BBInputNorwayComponent,
        BBSubmitComponent
    ],
    entryComponents: [
        BBFieldsetComponent,
        BBFormFrameworkComponent,
        BBInputComponent,
        BBEmailComponent,
        BBSelectWidgetComponent,
        BBSelectComponent,
        BBCheckboxComponent,
        BBRadioComponent,
        BBInputNorwayComponent,
        BBWizardComponent,
        BBWizardStepComponent,
        BBSubmitComponent,
        BBDialogComponent
    ],
    providers: [
        //
    ],
    exports: [
        // 
    ]
})
export class BBModule {
    constructor() {
    }
}

Use your widgets in your components

After that you should have the registration almost done. Now you need to create a reference to your custom widgets in your custom component and provide it to json-schema-form as input, like so:

Class

import { OnInit } from '@angular/core';
import customWidgets from '../form/custom-widgets';

@Component({
    selector: 'bb-dynamic-form',
    templateUrl: 'dynamic-form.component.html',
    styleUrls: ['dynamic-form.component.scss']
})
export class DynamicFormComponent implements OnInit {
    widgets = customWidgets;
}

HTML

<json-schema-form
    [widgets]="widgets"
    (onChanges)="onChanges.emit($event)"
    (onSubmit)="onSubmitFn($event)"
    (validationErrors)="validateErrors($event)">
</json-schema-form>
yovin99 commented 7 years ago

@Sebastian-Fitzner thanks verymuch for the explanation . will give it a try according to what you have suggested :)

Thorski commented 7 years ago

The import of WidgetLibraryService is still not possible with npm version of angular2-json-schema-form@0.5.0-alpha.8

Thorski commented 7 years ago

@Sebastian-Fitzner thank you for this description on how to create/hook in custom widgets. It has been invaluable.

I still cannot import the WidgetLibraryService. You wrote:

Same problem here ... Workaround is to use import { ɵb } from 'angular2-json-schema-form';.

I don't understand this, angular2-json-schema-form"' has no exported member 'eb'.

I have to clone the repository and directly access the source code to import the WidgetLibraryService rather than use the npm version.

Thanks.

Sebastian-Fitzner commented 7 years ago

@Thorski Did you copied my snippet over for the import? Because it is not an e. But I need to say, that I didn't tested the newest version ... Can give it a try.

Thorski commented 7 years ago

@Sebastian-Fitzner - I copied import { ɵb } from 'angular2-json-schema-form';

I get the error: node_modules/angular2-json-schema-form/angular2-json-schema-form"' has no exported member 'eb'.

Is there another snippet?

I don't know what "Because it is not an e" means.

Thank you!

Sebastian-Fitzner commented 7 years ago

Okay i can give it another try ... will provide some feedback if I can come up with a solution.

neil-coutinho commented 6 years ago

@Sebastian-Fitzner thanks for the above example. Do you have a repo/examples of the custom widgets (BBInputComponent, BBEmailComponent...) ?

neil-coutinho commented 6 years ago

@Thorski were you able to create a custom widget?

Sebastian-Fitzner commented 6 years ago

@neil-coutinho Custom widgets are easy to implement, but I haven't tried to implement a complete framework with the latest version. To create a custom widget, just copy over one of the widgets in that lib which fits best.

Let's say I want to create a custom text widget which is more performant than the origin. Here is what I do:

Copy over the source

Just take this one: https://github.com/dschnelldavis/angular2-json-schema-form/blob/master/src/lib/src/widget-library/input.component.ts

Modify to your needs

I just need to update the value after I have lost the focus of the field, in that way I speed up the performance, thats why I change input to blur and get rid of boundControl.

Register the widget

Now just import your widget in your module and register it first in entryComponents and Declarations.

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Bootstrap3FrameworkModule, JsonSchemaFormModule } from 'angular2-json-schema-form';
import { InputComponent } from './components/input/input.component';
import { SectionComponent } from './components/section/section.component';
import { TabComponent } from './components/tab/tab.component';
import { TabsComponent } from './components/tabs/tabs.component';
import { TextareaComponent } from './components/textarea/textarea.component';
import { ContentEditComponent } from './containers/content-edit/content-edit.component';

@NgModule({
    imports: [
        CommonModule,
        SharedModule,
        FormsModule,
        ReactiveFormsModule,
        Bootstrap3FrameworkModule,
        JsonSchemaFormModule.forRoot(Bootstrap3FrameworkModule)
    ],
    providers: [],
    entryComponents: [
        SectionComponent,
        TabsComponent,
        TabComponent,
        TextareaComponent,
        InputComponent
    ],
    declarations: [
        ContentEditComponent,
        SectionComponent,
        TabsComponent,
        TabComponent,
        TextareaComponent,
        InputComponent
    ]
})
export class ContentModule {
}

Last step is to provide it in the template. So I am going to import it into the ContentEdit Component. In there I create a reference to my custom widgets and use that as Input.

import { Component, OnDestroy, OnInit } from '@angular/core';
import { JsonSchemaFormService } from 'angular2-json-schema-form';
import { SectionComponent } from '../../components/section/section.component';
import { TabsComponent } from '../../components/tabs/tabs.component';
import { ContentPublishState, getContentPublishState } from '../../store/content.state';
import { TabComponent } from '../../components/tab/tab.component';
import { TextareaComponent } from '../../components/textarea/textarea.component';
import { InputComponent } from '../../components/input/input.component';

@Component({
    selector: 'gs-content-edit',
    templateUrl: './content-edit.component.html',
    styleUrls: ['./content-edit.component.scss']
})
export class ContentEditComponent implements OnInit, OnDestroy {
    schema: object;
    uiSchema: object;
    formIsValid: boolean;
    formData = {};
    initialFormData = null;
    formOptions = {
        addSubmit: false, // Add a submit button if layout does not have one
        validateOnRender: false,
        returnEmptyFields: false, // Don't return values for empty input fields
        defautWidgetOptions: {
            listItems: 1
            // feedback: true // Show inline feedback icons
        }
    };
        customWidgets = {
        section: SectionComponent, // Replace existing 'section' widget
        fieldset: SectionComponent, // Replace existing 'fieldset' widget
        tabs: TabsComponent, // Replace existing 'section' widget
        tab: TabComponent, // Add 'tab' widget
        textarea: TextareaComponent,
        text: InputComponent
    };
    constructor(
        private jsf: JsonSchemaFormService
    ) {}
}

In the template you can now use this.customWidgets:

<json-schema-form
    [schema]="schema"
    [data]="initialFormData"
    [options]="formOptions"
    [widgets]="customWidgets"
    [UISchema]="uiSchema"
    (isValid)="isValid($event)"
    (onChanges)="subscribeToFormChanges($event)">
</json-schema-form>
neil-coutinho commented 6 years ago

@Sebastian-Fitzner Thank you. This helped a lot