【问题标题】:Required field validation for kendo-dropdownlist in angular 7 applicationAngular 7 应用程序中 kendo-dropdownlist 的必填字段验证
【发布时间】:2019-07-04 11:02:31
【问题描述】:

我正在尝试在我的模板驱动表单上以角度 7 实现 kendo-dropdownlist 的必填字段验证。如果您可以看到我正在循环并生成一个动态表,该表在每一行中都有 kendo 下拉列表。如果未选中,我需要突出显示下拉菜单。我试图用表单标签将我的 div 括起来,以为当用户按下提交时我可以处理它,但我认为这更多的是在 kendo 中设置。有人可以告诉我如何做到这一点。到目前为止,我看到的所有示例都是基于 jquery 的。

这里是堆栈闪电战 https://stackblitz.com/edit/angular-4v2k8f

HTML

form name="form" (ngSubmit)="f.form.valid && createDocument()" #f="ngForm" novalidate>
<div class="center" class="file-upload-wrapper">
    <ngx-file-drop dropZoneLabel="Drop files here" dropZoneClassName="file-drop" multiple="true"
        (onFileDrop)="dropped($event)" (onFileOver)="fileOver($event)" (onFileLeave)="fileLeave($event)">
        <ng-template ngx-file-drop-content-tmp let-openFileSelector="openFileSelector">
            <button type="button" (click)="openFileSelector()">Drop Files to Upload</button>
        </ng-template>
    </ngx-file-drop>

    <div class="upload-table">
        <table id="table1" class="center">

            <tbody class="upload-name-style">
                <tr *ngFor="let item of files; let i=index">
                    <td> <input kendoTextBox [(ngModel)]="item.relativePath" style="width: 350px" /></td>
                    <td>
                        <kendo-dropdownlist style="width:350px" [(ngModel)]="item.selectedDocumentItem" 
                            [data]="DocumentTypes" [defaultItem]="defaultItem" [filterable]="false" textField="Name"
                            valueField="Id">
                        </kendo-dropdownlist>
                    </td>
                    <td>
                        <kendo-datepicker style="width: 200px" [format]="'dd MMM, yyyy'"
                            [(ngModel)]="item.selectedDate"></kendo-datepicker>
                    </td>
                    <td> <button class="btn btn-default" (click)="deleteRow(i)"><i class="fa fa-trash"></i>Delete
                        </button></td>
                </tr>
            </tbody>
        </table>


    </div>
    <div class="wrapper">
        <button *ngIf="files.length > 0" type="submit" class="btn btn-primary btn-upload">upload</button>
    </div>
</div>


</form>

组件

 public createDocument() {
        this.files.forEach(element => {

            this.uploadDocument = <IDocument>{

                id: 5508,
                documentTypeId: element.selectedDocumentItem.Id ,
                name: element.relativePath,
                documentDate: element.selectedDate

              };


        });
        }

【问题讨论】:

标签: angular kendo-ui


【解决方案1】:

您唯一需要的是使用引用变量并查看是否有效。我在stackblitz 中放了一个简单的例子。由于您只想知道是否有效,因此可以使用简单的 required。我的 stackblitz 就像

更新:在表单中,禁用按钮提交

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
    <form #myForm="ngForm">
    <div *ngFor="let item of files; let i=index">
      <p>T-shirt size:</p>
      <kendo-dropdownlist name="select{{i}}" #name="ngModel" [(ngModel)]="value[i]" [data]="listItems" required>
      </kendo-dropdownlist>
      <span *ngIf="name.invalid">*</span>
    </div>
    <button [disabled]="myForm.invalid">submit</button>
    </form>
    </div>
  `
})
export class AppComponent {
    public listItems: Array<string> = ["X-Small", "Small", "Medium", "Large", "X-Large", "2X-Large"];
    value=[]
    files=[{value:''},{value:''},{value:''}]
}

简单解释一下(但你有docs) 当我们有一个 [(ngModel)] 时,我们可以使用模板引用来引用输入。如果我们将模板引用等同于 ngModel #name="ngModel",我们可以在 .html 中使用模板变量和 ngModel 的所有属性(无效,触摸...),name.invalidname.touched...

啊!别担心你放的是“相同”的引用变量,如果模型的变量不相等,Angular 会理解它们是不同的变量。

注意:我个人建议你使用 ReactiveForms 和 FormArray,但这只是一个意见

Update 2 真的问题是你不能循环遍历你想要修改的同一个列表。你有*ngFor="let item of files",你正在改变files。诀窍是遍历' '.repeat(files.length).split('') - 或在代码中创建一个数组- this.iterator=new Array(this.files.length),然后你可以做&lt;tr *ngFor="let t of iterator;let i=index"&gt;

[(ngModel)] 位于文件[i].selectedDocumentItem.Id

查看stackblitz 和代码

<div class="example-wrapper">
    <form #myForm="ngForm">
        <!-- other way is <tr *ngFor="let t of iterator;let i=index"> -->
        <tr *ngFor="let t of ' '.repeat(files.length).split(''); let i=index">
            <td>
                <kendo-dropdownlist name="select{{i}}" #name="ngModel" [(ngModel)]="files[i].selectedDocumentItem.Id" [defaultItem]="files[i].selectedDocumentItem.id"
                 [data]="DocumentTypes" [valuePrimitive]="true" textField="Name" valueField="Id" required>
                </kendo-dropdownlist>
                <span *ngIf="name.invalid">*</span>
      </td>
    </tr>
    <button [disabled]="myForm.invalid">submit</button>
  </form>
</div>

如果我们想用作 [ngModel]=files[i].selectedDocumentItem(一个对象),我们需要创建一个 customError 指令。好像

@Directive({
  selector: '[requiredId]',
  providers: [{provide: NG_VALIDATORS, useExisting: RequiredIdDirective, multi: true}]
})
export class RequiredIdDirective implements Validator {

  validate(control: AbstractControl): {[key: string]: any} | null {
    return control.value.Id?null:{required:true}
  }
}

我们的下拉菜单现在是这样的

<kendo-dropdownlist name="select{{i}}" #name="ngModel"
      [(ngModel)]="files[i].selectedDocumentItem" 
      [defaultItem]="files[i].selectedDocumentItem" 
      [data]="DocumentTypes" 
      textField="Name" valueField="Id" requiredId>
      </kendo-dropdownlist>

查看新的stackblitz

【讨论】:

  • 我没有得到你的例子。我基本上需要阻止用户单击按钮,直到选择了该值或在控件旁边显示一条消息以说明未选择该值或突出显示该控件
  • 如果我们想要一个禁用的按钮提交,添加标签&lt;form #myForm="ngForm"&gt;,在输入中添加名称(在这种情况下必须不同)并放置一个按钮&lt;button [disabled]="myForm.invalid"&gt;submit&lt;/button&gt;,刚刚在答案和在堆栈闪电战中。注意:我建议你阅读官方文档:angular.io/guide/forms
  • 对我来说它正在工作,只有当您选择所有下拉列表时,您才能使用“提交”按钮。如果下拉列表没有选择任何值,则* 位于其旁边:(
  • 我的意思是我无法打开链接本身。你能再检查一下吗
  • stackblitz.com/edit/angular-ufkcvk-v2cyrl?file=app/… 我用于复制和粘贴:https://stackblitz.com/edit/angular-ufkcvk-v2cyrl?file=app/app.component.ts
猜你喜欢
  • 2014-03-17
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多