# AUR4200

## Error Message

`AUR4200: Validate behavior used on non property binding`

## Description

This error occurs when the `& validate` binding behavior is used on a binding type other than property bindings. The validate binding behavior is specifically designed to work with property bindings (like `value.bind`, `checked.bind`) and cannot be used with other binding types such as event bindings, template controllers, or other binding behaviors.

## Common Scenarios

### Using Validate on Event Bindings

```html
<!-- ❌ Wrong: Validate behavior on event binding -->
<button click.trigger="save() & validate">Save</button>
<form submit.trigger="handleSubmit() & validate">
```

### Using Validate on Template Controllers

```html
<!-- ❌ Wrong: Validate behavior on template controllers -->
<div if.bind="isVisible & validate">Content</div>
<div repeat.for="item of items & validate">
```

### Using Validate on Text Content

```html
<!-- ❌ Wrong: Validate behavior on text interpolation -->
<span textcontent.bind="message & validate">Error</span>
```

### Using Validate on Class/Style Bindings

```html
<!-- ❌ Wrong: Validate behavior on class bindings -->
<div class.bind="cssClass & validate">Content</div>
<div style.bind="styles & validate">Content</div>
```

## Solutions

### 1. **Use Validate Only on Form Control Property Bindings**

```html
<!-- ✅ Correct: Validate on form control value bindings -->
<input type="text" value.bind="user.name & validate">
<input type="email" value.bind="user.email & validate">
<input type="checkbox" checked.bind="user.isActive & validate">
<select value.bind="user.country & validate">
  <option value="">Select Country</option>
  <option value="US">United States</option>
  <option value="CA">Canada</option>
</select>
```

### 2. **Use Validation Controller for Programmatic Validation**

```typescript
import { ValidationController, ValidationControllerFactory } from '@aurelia/validation-html';

export class MyComponent {
  user = { name: '', email: '' };
  
  constructor(private validationControllerFactory: ValidationControllerFactory) {
    this.validationController = validationControllerFactory.createForCurrentScope();
  }
  
  async save() {
    // ✅ Correct: Programmatic validation instead of binding behavior on events
    const result = await this.validationController.validate();
    if (result.valid) {
      // Proceed with save
      this.performSave();
    }
  }
  
  private performSave() {
    // Save logic here
  }
}
```

### 3. **Proper Template Structure with Validation**

```html
<!-- ✅ Correct: Comprehensive validation setup -->
<template>
  <form submit.trigger="save()">
    <div class="form-group">
      <label for="name">Name:</label>
      <input 
        id="name" 
        type="text" 
        value.bind="user.name & validate"
        class.bind="user.name | errorClass">
      <span class="error" if.bind="user.name | hasError">
        ${user.name | errorMessage}
      </span>
    </div>
    
    <div class="form-group">
      <label for="email">Email:</label>
      <input 
        id="email" 
        type="email" 
        value.bind="user.email & validate"
        class.bind="user.email | errorClass">
      <span class="error" if.bind="user.email | hasError">
        ${user.email | errorMessage}
      </span>
    </div>
    
    <button type="submit" disabled.bind="!isFormValid">
      Save
    </button>
  </form>
</template>
```

### 4. **Custom Validation Triggers**

```html
<!-- ✅ Correct: Validate with specific triggers -->
<input 
  type="text" 
  value.bind="user.name & validate:blur"
  placeholder="Enter your name">

<input 
  type="email" 
  value.bind="user.email & validate:change"
  placeholder="Enter your email">

<!-- ✅ Correct: Manual validation trigger -->
<input 
  type="password" 
  value.bind="user.password & validate:manual"
  placeholder="Enter password">
<button click.trigger="validatePassword()">Validate Password</button>
```

```typescript
export class MyComponent {
  
  validatePassword() {
    // Manually trigger validation for password field
    this.validationController.validateTrigger = ValidationTrigger.manual;
    this.validationController.validate({ object: this.user, propertyName: 'password' });
  }
}
```

## Example: Complete Validation Setup

```typescript
// user-form.ts
import { ValidationRules, ValidationController, ValidationControllerFactory } from '@aurelia/validation';
import { autoinject } from '@aurelia/kernel';

@autoinject
export class UserForm {
  user = { 
    name: '', 
    email: '', 
    age: null as number | null,
    isActive: false 
  };
  
  validationController: ValidationController;
  
  constructor(validationControllerFactory: ValidationControllerFactory) {
    this.validationController = validationControllerFactory.createForCurrentScope();
    this.setupValidation();
  }
  
  private setupValidation() {
    ValidationRules
      .ensure((u: typeof this.user) => u.name)
        .required()
        .minLength(2)
        .maxLength(50)
      .ensure((u: typeof this.user) => u.email)
        .required()
        .email()
      .ensure((u: typeof this.user) => u.age)
        .required()
        .min(18)
        .max(120)
      .on(this.user);
  }
  
  async save() {
    const result = await this.validationController.validate();
    if (result.valid) {
      console.log('User is valid, saving...', this.user);
      // Perform save operation
    } else {
      console.log('Validation errors:', result.results);
    }
  }
  
  get isFormValid() {
    return this.validationController.results.length === 0 ||
           this.validationController.results.every(r => r.valid);
  }
}
```

```html
<!-- user-form.html -->
<template>
  <form submit.trigger="save()">
    <!-- ✅ Correct: Validate behavior only on property bindings -->
    <input 
      type="text" 
      value.bind="user.name & validate"
      placeholder="Name">
      
    <input 
      type="email" 
      value.bind="user.email & validate"
      placeholder="Email">
      
    <input 
      type="number" 
      value.bind="user.age & validate"
      placeholder="Age">
      
    <label>
      <input 
        type="checkbox" 
        checked.bind="user.isActive & validate">
      Active User
    </label>
    
    <!-- ✅ Correct: No validate behavior on submit event -->
    <button type="submit" disabled.bind="!isFormValid">
      Save User
    </button>
  </form>
</template>
```

## Debugging Tips

1. **Check Binding Type**: Ensure `& validate` is only used on property bindings (`value.bind`, `checked.bind`, etc.)
2. **Review Template**: Look for validate behavior on event bindings or template controllers
3. **Use Validation Controller**: For complex validation scenarios, use the validation controller programmatically
4. **Validate Binding Syntax**: Make sure the binding syntax follows the correct pattern

## Related Errors

* [AUR4201](https://docs.aurelia.io/developer-guides/error-messages/4200-to-4206/aur4201) - Validate binding behavior extraneous args
* [AUR4202](https://docs.aurelia.io/developer-guides/error-messages/4200-to-4206/aur4202) - Validate binding behavior invalid trigger name
* [AUR4204](https://docs.aurelia.io/developer-guides/error-messages/4200-to-4206/aur4204) - Validate binding behavior invalid binding target
