Reputation: 2607
I separated a special input-row, since it is often used, so it's better to create a new component to handle all of its stuff separately. The problem is that when I press on a reset button, the text input's value that is located inside the new component isn't changed back to its original value, it's just removed. I guess it's because the input's value is dynamically wired to the component's input parameter, and the actual input field doesn't have value="constant text"
attribute.
The page's HTML:
<form>
<h3 class="form-group-caption"
>Mappaútvonalak
<input type="reset" class="ml-3 btn btn-light" value="Visszaállítás" />
</h3>
<app-stateful-text-input
label="FRM"
inputValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
The component's HTML contains some wrapper elements, and:
<input
type="{{inputType}}"
class="form-control form-control-lg"
id="input-{{label}}"
value="{{inputValue}}"
(keypress)='onInputChanged($event)'
/>
For one input, I could write a resetInputs()
method, and call it when the reset button is pressed. However, there're a lot of instances of this new component, in multiple pages, anywhere inside forms. If I'd need to maintain references to all of them, just to be able call a method in that sub-component, I'd lose the key point of separating them.
Is there any simple solution to this situation?
Upvotes: 0
Views: 363
Reputation: 2607
I could make this automatic by adding a reset
event listener to the container <form>
, at that time I overwrite the value
attribute with the stored one.
However, it's still ugly, this requires additional JS. I'd love a "native solution" where the reset button could do what it wants to.
export class StatefulInputComponent implements OnInit {
@Input() inputValue: string;
@ViewChild('inputField', {static: true}) inputField: ElementRef;
defaultValue: string;
ngOnInit() {
this.defaultValue = this.inputValue;
let element = this.inputField.nativeElement as HTMLElement;
do {
element = element.parentElement;
} while (element != null && element.tagName !== 'FORM');
if (element == null) {
throw new Error('<app-stateful-input> must be placed inside a <form>!');
}
const form = element as HTMLFormElement;
form.addEventListener('reset', (event: Event) => {
const input = this.inputField.nativeElement as HTMLInputElement;
input.value = this.defaultValue;
event.preventDefault();
});
}
}
Upvotes: 0
Reputation: 106
You could set a default value in the Input component and use it with a resetInputs()
method, as you suggest, in the parent component.
<app-stateful-text-input
label="FRM"
defaultValue="A:\Temp"
inputType="text"
apiPath="/api/frm"
></app-stateful-text-input>
@Component({
selector: 'app-stateful-text-input',
template: `...`
})
export class StatefulTextInputComponent implements OnInit {
@Input()
public defaultValue: string;
public inputValue: string;
public ngOnInit(): void {
this.inputValue = this.defaultValue;
}
}
In your parent component you can iterate in all the children custom input and set the old value when resetting.
@Component({
selector: 'app-form-component',
template: `...`
})
class FormComponent {
@ViewChildren(StatefulTextInputComponent) statefulTextInputs: QueryList<StatefulTextInputComponent>;
...
public resetInputs(): void {
this.statefulTextInputs.forEach((item: StatefulTextInputComponent) => item.inputValue = item.defaultValue);
}
...
}
Upvotes: 1