npm package: @orendaco/of
Description: (Angular Dynamic form) Orenda
Latest version: 3.1.8

# Of

Dynamic Form Orenda

## Code scaffolding

## HTML

```
 <of #vcForm [schemaModel]="schemaModel">
               <of-field id="templateRef" [controlItemTpl]="control">
                    <ng-template #control>
                      <form [formGroup]="schemaModel.form">
                        <nz-input-group nzCompact>
                          <nz-select formControlName="templateOpt" style="width: 50%">
                            <nz-option [nzLabel]="'Option 1'"
                                       [nzValue]="'1'"></nz-option>
                            <nz-option [nzLabel]="'Option 2'"
                                       [nzValue]="'2'"></nz-option>
                          </nz-select>
              
                          <of-item-wrap [schemaModel]="schemaModel" dataField="templateInput"
                                        style="width: 50%">
                            <input formControlName="templateInput"
                                   nz-input
                                   placeholder="templateInput"
                            />
                          </of-item-wrap>
              
                        </nz-input-group>
                      </form>
                    </ng-template>
                  </of-field>
          </of>
  ```

## TS

```
formDisable$ = new BehaviorSubject(false);
ngaySinhMin$ = new BehaviorSubject<Date>(new Date(1991, 2, 27));
danTocOption$ = new BehaviorSubject<IOfSelectOptionDto[]>([{
displayText: 'Kinh',
value: '1'
}, {
displayText: 'Mông',
value: '2'
}]);
schemaModel = new OfSchemaModel({
    fields: [
      new OfTextModel({
        label: 'Mã',
        dataField: 'ma',
        required: true,
        validations: [
          {
            name: 'email'
          }
        ],
        disabled: true

      }),
      new OfTextModel({
        label: 'Họ tên',
        dataField: 'tenDayDu',
        required: true,
        disabledAsync: this.formDisable$
      }),

      new OfSelectModel({
        label: 'Giới tính',
        dataField: 'gioiTinhId',
        value: 1,
        options: [
          { displayText: 'Nam', value: '1' },
          { displayText: 'Nữ', value: '2' }
        ]
      }),
      new OfSelectAsyncModel({
        label: 'Dân tộc async',
        dataField: 'danToc',
        value: 1,
        optionsAsync: this.danTocOption$
      }),
      new OfSelectApiModel({
        label: 'Tỉnh',
        dataField: 'tinhId',
        functionService: this.selectSp.getoptions({
          type: SelectOptionType.Tinh
        } as any),
        keyCache: 'tinh'
      }),
      new OfSelectCascadeModel({
        label: 'Huyện',
        dataField: 'huyenId',
        cascadeField: 'tinhId',
        functionService: (cascade) => {
          return this.selectSp.getoptions({
            type: SelectOptionType.Huyen,
            cascader: cascade
          } as any);
        },
        renderOptionFunc: (opt) => {
          if (opt) {
            return opt.value + ' - ' + opt.displayText;
          }
          return '';
        },
        renderSelectedFunc: (opt) => {
          if (opt) {
            return `<b>${opt.value}</b>` + ' - ' + opt.displayText;
          }
          return '';
        }
      }),
      new OfSelectCascadeModel({
        label: 'Xã',
        dataField: 'xaId',
        cascadeField: 'huyenId',
        functionService: (cascade) => {
          return this.selectSp.getoptions({
            type: SelectOptionType.Xa,
            cascader: cascade
          } as any);
        },
        keyCache: 'xa'
      }),

      new OfSelectSearchServerModel({
        label: 'Quận huyện search',
        dataField: 'huyenSearchServerId',
        functionService: (dto) => {
          return this.searchSp.getoptions({
            ...dto,
            type: SelectSearchServerType.Huyen
          });
        }
      }),
      new OfSelectSearchServerModel({
        label: 'Quận huyện search showPagination',
        dataField: 'huyenSearchServerId',
        functionService: (dto) => {
          return this.searchSp.getoptions({
            ...dto,
            type: SelectSearchServerType.Huyen
          });
        },
        showPagination: true
      }),
        new OfSelectAdvancedSearchModel({
            label: 'Quận huyện search advanced',
            dataField: 'huyenSelectAdvancedSearchId',
            functionService: (dto) => {
              return this.searchSp.getoptions({
                ...dto,
                type: SelectSearchServerType.Huyen
              } as any);
            },
            showPagination: true,
            componentAdvanced: HomeComponent
          }),
      new OfSelectAdvancedSearchModel({
        label: 'Quận huyện search advanced modal',
        dataField: 'huyenSelectAdvancedSearchModalId',
        functionService: (dto) => {
          return this.searchSp.getoptions({
            ...dto,
            type: SelectSearchServerType.Huyen
          } as any);
        },
        showPagination: true,
        componentAdvanced: SearchModalComponent,
        nzModalConfig: {
          nzFooter: null,
          nzStyle: { top: '20px' }
        },
        showComponentType: 'modal'
      }),
      new OfCheckBoxModel({
        label: '',
        dataField: 'checkBox',
        checkBoxLabel: 'Check box',
        disabledAsync: this.formDisable$
      }),
      new OfDateModel({
        label: 'Ngày sinh',
        dataField: 'ngaySinh',
        required: true,
        notGreaterThanCurrent: true,
        minDateAsync: this.ngaySinhMin$,
        disabledAsync: this.formDisable$
      }),
      new OfCurrencyModel({
        label: 'Đơn giá',
        dataField: 'donGia',
        disabledAsync: this.formDisable$
      }),
      new OfContentHtmlModel({
        label: ' ',
        dataField: 'benhNhanId',
        content: '<h3>content string html</h3>',
        disabledAsync: this.formDisable$
      }),
      new OfTextAreaModel({
        label: 'Ghi chú',
        dataField: 'ghiChu',
        rows: 2,
        disabledAsync: this.formDisable$
      }),
      new OfNumberModel({
        label: 'Số thứ tự',
        dataField: 'soThuTu',
        min: 10,
        max: 100,
        step: 2,
        disabledAsync: this.formDisable$
      }),
      new OfNumberModel({
        label: 'Điện thoại',
        dataField: 'dienThoai',
        onlyKeyNumber: true,
        disabledAsync: this.formDisable$
      }),
      new OfPwdModel({
        label: 'Mật khẩu',
        dataField: 'matKhau',
        disabledAsync: this.formDisable$,
        validations: [
          {
            name: 'password'
          }
        ]
      }),
      new OfRadioModel({
        label: 'Loại',
        dataField: 'loai',
        items: [{
          label: 'Loại 1',
          value: 1
        }, {
          label: 'Loại 2',
          value: 2
        }, {
          label: 'Loại 3',
          value: 3
        }]
      }),
      new OfSwitchModel({
        label: 'Switch',
        dataField: 'switch',
        yesText: 'Có'
      }),
      new OfTemplateRefModel({
        label: 'templateRef',
        dataField: 'templateRef',
        controls: [
          new OfExtendControlModel({
            dataField: 'templateOpt',
            value: '1'
          }),
          new OfExtendControlModel({
            dataField: 'templateInput',
            required: true
          })
        ]
      })
    ]
  });
```

## Table

# Html

```
<o-table #vcTable [setting]="otSetting" [items]="pageConfig.items" [loading]="pageConfig.loading$ | async">
  <o-column type="checkbox"></o-column>
  <o-column name="value" headerText="Id" cellAlign="center" [width]="50" [allowSorting]="true"></o-column>
  <o-column name="displayText" headerText="Tên" [width]="100"></o-column>
  <o-column headerText="Tên">
    <ng-template #template let-data="data">
      <div>
        <span>{{data.value}} - {{data.displayText}}</span>
      </div>
    </ng-template>
  </o-column>
  <o-column name="value" headerText="Tiền vnd" type="vnd" [width]="100"></o-column>
  <o-column name="displayText" headerText="Tên 1" *ngIf="showCol"></o-column>
  <o-column name="displayText" headerText="Tên 2"></o-column>
  <o-column name="displayText" headerText="Tên 3"></o-column>
  <o-column name="displayText" headerText="Tên 4" fix="right"></o-column>
  <ng-template #expand let-data="data">
    {{data|json}}
  </ng-template>
</o-table>
<op #vcPage [config]="pageConfig"></op>
```

# TS

```
 @ViewChild('vcPage') vcPage!: OpComponent;


  pageConfig = new OpConfigModel<any>({
    type: 'ord-custom',
    sourceType: 'func',
    dataSourceFunc: (dto) => {
      dto.type = 27;
      return this.selectSp.getoptions(dto).pipe(map(result => {
        return {
          items: result,
          totalCount: result.length
        };
      }));
    }
  });
  otSetting: OTableSettingModel;
  showCol = false;

  constructor(private selectSp: SelectoptionServiceProxy) {
  }

  ngOnInit(): void {
    this.otSetting = new OTableSettingModel({
      bordered: true,
      scrollY: '60vh',
      expandable: true
    });
  }

  search() {
    this.vcPage.search({});
  }
```

## Tree Table

# HTML

```$xslt
<button nz-button
        (click)="expand = !expand; vcTreeTable.expandAll(expand)"> Expand
</button>
<o-table-tree #vcTreeTable
              [setting]="setting"
              [items]="items"
              (expandChange)="expandChange($event)"
              (nodeCheckedChange)="nodeChecked = $event"
>
<!--    <o-tree-column type="checkbox"></o-tree-column>-->
<!--    <o-tree-column headerText="Tên"-->
<!--                   name="ten"-->
<!--                   [isContainIconExpand]="true"-->
<!--                   [width]="300"-->
<!--                   [hasTreeIndex]="true"></o-tree-column>-->
<!--    <o-tree-column headerText="Tên đầy đủ">-->
<!--        <ng-template #template-->
<!--                     let-data="data">-->
<!--            {{data?.tenDayDu}}-->
<!--        </ng-template>-->
<!--    </o-tree-column>-->
</o-table-tree>
```

# TS

```$xslt
 setting = new OTreeTableSettingModel({
        primaryKey: 'id',
        parentKey: 'parentId',
        //  expandAllAfterLoad: true,
        loadAsync: true,
        scrollY: '60vh',
        singleChecked: false,
        columns: [{
            type: 'checkbox',
            width: 60
        },
            {
                headerText: 'Tên',
                name: 'ten',
                isContainIconExpand: true,
                hasTreeIndex: true,
                width: 300
            },
            {
                headerText: 'Tên đầy đủ',
                renderHtml: (record) => {
                    return record?.tenDayDu;
                }
            }
        ]
    });

    expandChange(node: IOTreeTableNode) {
        const children = this.allItems.filter(s => s.parentId === node.id);
        this.vcTreeTable.setChildrenForNode(node, children);
    }

```