hamzahamidi / ajsf

Angular JSON Schema Form
https://hamzahamidi.github.io/ajsf
MIT License
362 stars 183 forks source link

Any custom submit buttons enabled even if required fields are empty #66

Closed Kobbersvard closed 4 years ago

Kobbersvard commented 5 years ago

Describe the bug which template:

A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. https://hamidihamza.com/Angular6-json-schema-form/?set=asf&example=asf-simple&framework=material-design&language=en In this example there is custom submit button (at least text on it), it is clickable even if form is empty. If you remove submit button node completely from json, button will be rendered by default Submit button and it disabled as it should be.

Expected behavior Disabled mode for submit button with custom text while required fields are empty

woutervs commented 5 years ago

Can confirm, I was also looking for a solution for this.

github-actions[bot] commented 4 years ago

Stale issue

nw-rgails commented 4 years ago

Yeah, I wanted to set custom text for my submit button and realized it doesn't validate properly then.

RS-Roshi commented 4 years ago

Any update regarding this issue or did anyone find where we can modify the code to handle SUBMIT BUTTON's enable/disable property?

Yobikap commented 2 years ago

This is pretty easy.

In your ts file add the following:

formOptions: object = { addSubmit: false }

In your html file add:

` <json-schema-form *ngIf="formData" #jsonSchemaFormComponent [loadExternalAssets]="false" [options]="formOptions" (onSubmit)="validateAndSubmit($event)" framework="material-design"

`

Don't forget to add a onSubmit Fn and also add a submit button in your html template, then you are good to go.

jpuvogel13 commented 2 years ago

I'm also having issues with this. If i don't use the default submit button, I can't get the form data through my custom submit button. Also, I want to validate once the submit button has been clicked.... Any ideas?

<json-schema-form [schema]="schemaObj" framework="bootstrap-4" (onSubmit)="sub($event)" [options]="formOptions" (onChanges)="onChanges($event)" (isValid)="isFormValid($event)" >

<button class="primary" type="submit" (click)="sub($event)"> Next

*edit: I'm currently declaring a variable and then setting equal to ngOnchanges $event, which gives me the data that has been changed, but is there a way to get the whole formdata, whether changed or not?

Yobikap commented 2 years ago

Hi @jpuvogel13

I am using two different functions for the click part on the submit button, and a separate one on json-schema-form, also the json-schema-form is referenced from within my component. (don't forget exclamation mark, this tells typescript that this variable will be initialized at run-time)

@ViewChild('jsonSchemaFormComponent') jsonSchemaFormComponent!: JsonSchemaFormComponent;

Here an example:

      <json-schema-form #jsonSchemaFormComponent
                        [loadExternalAssets]="false"
                        [schema]="schemaObj"
                        [options]="formOptions"
                        (onSubmit)="validateAndSubmit($event)"
                        framework="material-design"
      >
      </json-schema-form>

      <button color="primary" (click)="submit()">Next</button>

Once the user clicks on the Next button, then the following functionBody gets triggered:

  submit(): void {
    this.jsonSchemaFormComponent.submitForm();
  }

In the above function other function validateAndSubmit get's executed automatically.

Because I am using a multi stepper form, I subscribe to the isValid observable in jsonSchemaFormComponent and set a boolean variable in my code, so I can check this at submission if everything is valid:

export class Form implements OnInit, AfterViewChecked {
@ViewChild('jsonSchemaFormComponent') jsonSchemaFormComponent!: KlmJsonSchemaFormComponent;

  formOptions: object = {
        addSubmit: false
  }

  isValid: boolean = false

  constructor(...
  ) {
  }

  ngAfterViewChecked(): void {
    if (this.jsonSchemaFormComponent) {
      this.jsonSchemaFormComponent.isValid.subscribe((valid: boolean) => this.isValid = valid );
    }
  }

  submit(): void {
    this.jsonSchemaFormComponent.submitForm();
  }

  validateAndSubmit($event: Event): void {
    if(isValid) {
    // it is valid, do the magic
    } else {
    // Do something in the application, or show an additional message
    }
  }
}

If you need the formData, you can just console.log(this.jsonSchemaFormComponent) to check which data you need. But it is however not possible to get the full schema with the filled in data & default values.

jpuvogel13 commented 2 years ago

Hi @Yobikap , Thanks for the quick response. This looks very similar to what I'm trying to do. However when declaring JsonSchemaFormComponent, it's saying cannot find it. I was looking for the form object that could be applied but didn't see one in the documentation. Can you please show me your import statement? Am I missing an additional library? I have ajsf/core and ajsf/bootsrap.

Yobikap commented 2 years ago

@jpuvogel13

This is my import statement:

import { JsonSchemaFormComponent } from "@ajsf/core";

in angular.json, you have to add @ajsf to the allowedCommonJsDependencies:

  "architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "allowedCommonJsDependencies": ["@ajsf"],

.....

jpuvogel13 commented 2 years ago

@Yobikap Got it, thank you very much for your help!

jpuvogel13 commented 2 years ago

@Yobikap I have one further issue: When the form is being rendered, it is "Valid" until it is touched. How are you implementing a guard to restrict the user from not touching the form and just hitting submit?

Yobikap commented 2 years ago

@jpuvogel13 In my previous code I have a boolean named isValid.

On initialization this variable has a default boolean false.

And in ngAfterViewChecked I subscribe to the isValid observable of jsonSchemaFormComponent

jpuvogel13 commented 2 years ago

@Yobikap Right, I've followed the same implementation, but when my form is rendered isValid is emitting true, even before the form has been touched. Also my jsonSchemFormComponent.submitForm() is having an infinite loop. I must have some implementation wrong, I'll look into it further. Thanks a bunch for your time and help.

Yobikap commented 2 years ago

@jpuvogel13

Can you please share your jsonSchema? I think the validation is not set properly in the schema or layout.

jpuvogel13 commented 2 years ago

I'm not using any layout, just using the default one.

{ "schema": { "$schema": "http://json-schema.org/draft-07/schema#", "title": " form1", "description": "this is the first in a series of forms to be used for developing interface and UI standards against requirements based on json-schema.org Draft 7", "department": "sales", "type": "object", "properties": { "questionsOrSections": { "type": "object", "properties": { "question_1": { "title": "is this form being used for development purposes?", "description": "this question is of answer type boolean, the a user of FBE will recognize it as a Yes/No answer type", "type": "boolean" }, "question_2": { "title": "please select a date before submitting", "description": "selecting a date is required", "type": "string", "format": "date" }, "question_3": { "title": "please provide text-based detail for this question", "description": "a minimum of 4 characters must be provided in order to continue", "defaultValue": "an example of successfully completed text is provided here: %87T", "type": "string", "minLength": 4 }, "question_4": { "title": "one or more selections are requested but not required", "type": "array", "items": { "type": "string", "enum": [ "option 1", "option 2", "option 3", "option 4" ] } } }, "required": [ "question_2", "question_3" ] } }, "$id": "http://schemaService/formBuilder/schemas/441" } }

Yobikap commented 2 years ago

@jpuvogel13

There is something wrong with the selectboxes. When I select all option 1 until option4, and hit on Next then the form is invalid. This is correct behaviour.

But when I unselect option 1 to option 4, suddenly the form is valid and you can submit. And this is wrong

You can see this behaviour in Console. example: https://codesandbox.io/s/vibrant-elbakyan-zdsz6b