From the example above we simple created our custom inputs (by giving also the possibility to use `option` trait property) and defined some input switch behaviour on the type change. Now the result would be something like this
Before going forward and making our trait work let's talk about the layout structure of a trait. You might have noticed that the trait is composed by the label and input columns, for this reason GrapesJS allows you to customize both of them.
For the label customization you might use `createLabel`
```js
editor.TraitManager.addType('href-next', {
// Expects as return a simple HTML string or an HTML element
createLabel({ label }) {
return `<div>
<div>Before</div>
${label}
<div>After</div>
</div>`;
},
// ...
});
```
You've probably seen already that in trait definition you can setup `label: false` to completely remove the label column, but in case you need to force this behaviour in all istances of this trait type you can use `noLabel` property
```js
editor.TraitManager.addType('href-next', {
noLabel: true,
// ...
});
```
You might also notice that by default GrapesJS applies kind of a wrapper around your inputs, generally is ok for simple inputs but probably is not what you need where you're creating a complex custom trait. To remove the default wrapper you can use the `templateInput` option
```js
// Each new type extends the default Trait
editor.TraitManager.addType('content', {
events:{
'keyup': 'onChange', // trigger parent onChange method on keyup
editor.TraitManager.addType('href-next', {
// Completely remove the wrapper
templateInput: '',
// Use a new one, by specifying with `data-input` attribute where to place the input container
templateInput: `<divclass="custom-input-wrapper">
Before input
<divdata-input></div>
After input
</div>`,
// It might also be a function, expects an HTML string as the result
templateInput({ trait }) {
return '<div...';
},
});
```
<img:src="$withBase('/docs-link-trait-raw.jpg')">
In this case the result will be quite raw and unstyled but the point of custom trait types is to allow you to reuse your own styled inputs, probably already designed and defined (or impliemented in some UI framework).
For now let's keep the default input wrapper and continue with the integration of our custom trait.
### Bind to component
At the current state, our element created in `createInput` is not binded to the component so nothing happens when you update inputs, so let's do it now
/**
* Returns the input element
* @return {HTMLElement}
*/
getInputEl: function() {
if (!this.inputEl) {
var input = document.createElement('textarea');
input.value = this.target.get('content');
this.inputEl = input;
```js
editor.TraitManager.addType('href-next', {
// ...
// Update the component based element changes
// `elInput` is the result HTMLElement you get from `createInput`
Now, most of the stuff should already work (you can update the trait and check the HTML in code preview). You might wonder how the editor captures the input change and if it's possible to change it.
By default, the base trait wrapper applies a listener on `change` event and calls `onUpdate` on any captured event (to be captured the event should be able to [bubble](https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing)). If you want, for example, to update the component on `input` event you can change the `eventCapture` property
```js
editor.TraitManager.addType('href-next', {
eventCapture: ['input'],
// ...
});
```
The last thing, you might have noticed the wrong inital render of our trait, which is not populate our inputs in case of already defined `href` attribute. This step should be done in `onRender` method