# Inputs get the `data-[CONTROLLER]-target="hasSkillsTagsInput"` attribute and can be targeted using hasSkillsTagsInputTarget
field :has_skills, as: :tags
```

### All controllers receive the `view` value

All stimulus controllers receive the `view` attribute in the DOM.

```html{4-5}
<div class="space-y-12" data-model-id="280" data-controller="resource-edit course-resource" data-resource-edit-view-value="edit" data-course-resource-view-value="edit">
  
</div>
```

Now you can use that inside your Stimulus JS controller like so:

```js{5,9}
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
  static values = {
    view: String,
  }

  async connect() {
    console.log('view ->', this.viewValue)
  }
}
```

The possible values are `index`, `show`, `edit`, or `new`

## Assign Stimulus controllers to actions

Similarly as to resource, you can assign stimulus controller to an action. To do that you can use the `stimulus_controllers` option on the action file.

```ruby
class Avo::Actions::ShowCurrentTime < Avo::BaseAction
  self.stimulus_controllers = "city-in-country"
end
```

You can add more and separate them by a space character.

```ruby
class Avo::Actions::ShowCurrentTime < Avo::BaseAction
  self.stimulus_controllers = "course-resource select-field association-fields"
end
```

The same way as for the resources, Avo will add stimulus target data attributes to [all field wrappers](#field-wrappers-as-targets) and [all input fields](#field-inputs-as-targets).

Unlike with the resource, Avo will not add a specific default controller for each type of the view (`index`, `show`, `edit`).
Same way, the controllers will not receive the `view` attribute in the DOM, [as in case of resources](#all-controllers-receive-the-view-value).

## Attach HTML attributes

This section has moved.

## Composing the attributes together

You can use the attributes together to make your fields more dynamic.

```ruby{3-9}
  field :has_skills, as: :boolean, html: {
    edit: {
      input: {
        data: {
          # On click run the toggleSkills method on the toggle-fields controller
          action: "input->toggle-fields#toggleSkills",
        }
      }
    }
  }
  field :skills, as: :tags, html: {
    edit: {
      wrapper: {
        # hide this field by default
        classes: "hidden"
      }
    }
  }
```

```js
// toggle_fields_controller.js
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["skillsTagsWrapper"]; // use the target Avo prepared for you

  toggleSkills() {
    this.skillsTagsWrapperTarget.classList.toggle("hidden");
  }
}
```

## Pre-made stimulus methods

Avo ships with a few JS methods you may use on your resources.

### `resource-edit#toggle`

On your `Edit` views, you can use the `resource-edit#toggle` method to toggle the field visibility from another field.

```ruby{5-7}
field :has_country, as: :boolean, html: {
  edit: {
    input: {
      data: {
        action: "input->resource-edit#toggle", # use the pre-made stimulus method on input
        resource_edit_toggle_target_param: "countrySelectWrapper", # target to be toggled
        # resource_edit_toggle_targets_param: ["countrySelectWrapper"] # add more than one target
      }
    }
  }
}
field :country, as: :select, options: Course.countries.map { |country| [country, country] }.to_h
```

<Image src="/assets/img/stimulus/toggle-method.gif" width="800" height="421" alt="Toggle method" />

### `resource-edit#disable`

Disable works similarly to toggle, with the difference that it disables the field instead of hiding it.

```ruby{5-7,16}
field :has_skills, as: :boolean, html: {
  edit: {
    input: {
      data: {
        action: "input->resource-edit#disable", # use the pre-made stimulus method on input
        resource_edit_disable_target_param: "countrySelectInput", # target to be disabled
        # resource_edit_disable_targets_param: ["countrySelectWrapper"] # add more than one target to disable
      }
    }
  }
}
field :country, as: :select, options: Course.countries.map { |country| [country, country] }.to_h
```

<Image src="/assets/img/stimulus/disable-method.gif" width="800" height="421" alt="Disable method" />

You may also target the `wrapper` element for that field if the target field has more than one input like the searchable polymorphic `belongs_to` field.

```ruby{6}
field :has_skills, as: :boolean, html: {
  edit: {
    input: {
      data: {
        action: "input->resource-edit#disable", # use the pre-made stimulus method on input
        resource_edit_disable_target_param: "countrySelectWrapper", # target the wrapper so all inputs are disabled
        # resource_edit_disable_targets_param: ["countrySelectWrapper"] # add more than one target to disable
      }
    }
  }
}
field :country, as: :select, options: Course.countries.map { |country| [country, country] }.to_h
```

### `resource-edit#debugOnInput`

For debugging purposes only, the `resource_edit` Stimulus JS controller provides the `debugOnInput` method that outputs the event and value for an action to the console. Use this just to make sure you targeted your fields correctly. It doesn't have any real use.

<Image src="/assets/img/stimulus/debug-on-input.gif" width="800" height="261" alt="Debug on input stimulus method" />

## Custom Stimulus controllers

<DemoVideo demo-video="https://youtu.be/ZMOz22FaAUg?t=1127" />

:::info Check the source code
If you visit our demo website on the [course edit page](https://main.avodemo.com/avo/resources/courses/1/edit) you can see this in action.

- Demo of the feature in action <br>
https://main.avodemo.com/avo/resources/courses/1/edit
- JS controller that does that change <br>
https://github.com/avo-hq/main.avodemo.com/blob/main/app/javascript/controllers/course_controller.js
- Rails controller that returns the results <br>
https://github.com/avo-hq/main.avodemo.com/blob/main/app/controllers/avo/courses_controller.rb#L3
- Stimulus action that triggers the update <br>
https://github.com/avo-hq/main.avodemo.com/blob/main/app/avo/resources/course.rb#L68
:::

The bigger purpose of this feature is to create your own Stimulus JS controllers to bring the functionality you need to the CRUD interface.

Below is an example of how you could implement a city & country select feature where the city select will have its options changed when the user selects a country:

1. Add an action to the country select to trigger a change.
1. The stimulus method `onCountryChange` will be triggered when the user changes the country.
1. That will trigger a fetch from the server where Rails will return an array of cities for the provided country.
1. The city field will have a `loading` state while we fetch the results.
1. The cities will be added to the `city` select field
1. If the initial value is present in the returned results, it will be selected.
1. All of this will happen only on the `New` and `Edit` views because of the condition we added to the `connect` method.

::: code-group

```ruby [app/avo/resources/course.rb]