Angular7 Detect change of input value in reactive forms - javascript

I am working for the first time with reactive forms in Angular(v7)
I want to make my submit button enabled if any of the fields has changed. So I am working with the dirty value of the form.
For a simple scenarios its working. I change a input type text and the button became enable.
But now I got a problem with an element (<span id="locationUpdated">) that the value inside of it is being changed by the result of some other javascript functions.
So I decided to listening the change of an hidden input that get the value the same way as the span element
<form [formGroup]="model.form" >
....
<input id="nameInput" type="text"
[(ngModel)]="model.user.name"
formControlName="name" />
...
<span [textContent]="model.user.location.label" id="locationUpdated"></span>
<input type="hidden" [value]="model.user.location.label" formControlName="location" />
....
<button [ngClass]="{'disabled': !model.form.dirty}></button>
</form>
--- Component ---
private buildFormUpdated() {
this.model.form = this.formBuilder.group({
name: [this.model.user.name, [Validators.required]],
location: [this.model.user.location.label]
});
}
I replace the hidden to text so I can see the value change and it is working fine.
However the property dirty continues false. If I change manually I get the dirty:true
What am I missing?
Thanks

What am I missing?
The dirty flag is not set to true when the data is changed programatically.
It is set to true only if the user blurs the control component, or changes the value (through the UI)
Please ref official docs - https://angular.io/guide/form-validation#why-check-dirty-and-touched

you can explicit marks the control as dirty by doing this after your logic
this.model.form.markAsDirty();

Related

how to getvalue of textarea in react?

I am using react-final-form and TextareaAutosizein my example .I am trying to get the value of text-area but not able to do that.
I am able to get value of input field but not textarea
here is my code
https://codesandbox.io/s/react-final-form-simple-example-rd3rc
<div>
<label>Text area Name</label>
<Field
component={TextareaAutosize}
type="textarea"
name="operatingPinCode"
placeholder="Notes"
label="About"
/>
</div>
API link
https://final-form.org/docs/react-final-form/examples/simple
https://www.npmjs.com/package/react-textarea-autosize
Your final-form code is working fine. The problem I think lies with TextAreaAutosize, since it doesn't know how to pass data directly to your form. So you might need to add a handler on that field for the onChange event.
Based on the final form documentation, this code sample below seems to work just fine:sandbox-code Just checkout the second attempt section.
You can get value by this pop:
`onChange={(event) => {
console.log(event.target.value)
}}`

cursor jumps back to input field

I currently have the cursor auto-focus to a particular field which works as expected (when the modal is displayed). The problem is when i click on another field in that same form and begin typing, the cursor jumps back to the initial field with the autofocus attribute. Any idea what's causing this? thanks in advance
This is for an angular 1.7 project. I have tried moving the autofocus function to different locations within the controller, none of which made a difference.
//Controller
angular.module('qmsControllers').controller('ResponseCodesModalCtrl', function($scope) {
$scope.giveFocus = function() {
$(**'#responsecode'**).focus();
return true;
};
});
//view
<div class="form-group modal-form-group">
<label for="code" class="col-sm-2 control-label">Response Code:</label>
<input type="text" class="some class="0 === editMode"
ng-change="onResponseCodeChanged($event)"
**id="responsecode"**
**ng-show="giveFocus()"**
name="code" ng-model="response" />
</div>
The expected result is the autofocus occurring when the modal is displayed but allowing for typing in fields other than the autofocus field.
ng-show does not mean what you might think it means, ng-show controls whether or not the element should be shown, not "execute this function when I'm shown"
So each time angular evaluates if the input element needs to be shown your element triggers an onFocus.
If you want to trigger the focus only when loading the dialog you could simply call
$scope.giveFocus() at the end of the controller function. And remove the ng-show attribute
you can also use the $onInit method this method will be called by angularjs once the view has been initialized, it maybe that the element isn't in the dom yet.
So something like
this.$onInit = function() {
$(**'#responsecode'**).focus();
};

Change input value using javascript in a form built with Aura

I have an input in a form built with aura (Salesforce JS framework):
<input class=" input uiInput uiInputText uiInput--default uiInput--input" type="text" aria-describedby="5284:0" placeholder="" id="7:4790;a" data-aura-rendered-by="17:4790;a" data-aura-class="uiInput uiInputText uiInput--default uiInput--input" data-interactive-lib-uid="54" aria-required="true">
I need to change the value of this input using javascript.
However, when doing:
document.getElementById("7:4790;a").value = "random value";
Visually, it changes the value in the input, but it is not taken into account when saving as if I didn't change anything.
How can I achieve this ?
Do I need to trigger a specific event so that aura takes notice of the new data ?
You need to create an attribute of string type.
<aura:attribute name="myInputValue" type="String" />
Pass the attribute to the value property of the input tag.
<input .... value="{! v.myInputValue}" />
Now, whenever you want to change the value in the input, you can simply do this from your javascript function:
component.set('v.myInputValue, "My new String" />
Important Note: Salesforce frameworks don't allow DOM level manipulation due to a security architecture called Locker service. It is not advisable to follow DOM level Manipulation. Instead, follow the state-based approach like above.

Changing input value field that has interpolation

I'm trying to reset a value when you click a button by simply setting the .val() with JQuery. The weirdest thing is happening- my code is ONLY working for the state dropdown but not the other inputs, which have their values set inline with SWIG interpolation like so:
<input type="text" class="moving-input form-control" id="first-name-search" value="{{search.firstName}}">
When this button is clicked:
<button type="reset" class="results-form-link" id="perform-new-search">Perform a New Search</button>
It should run this code:
$('#perform-new-search').click(function() {
$('#first-name-search').val('hello');
$('#last-name-search').val('');
$('#results-states option:selected').val('Select State');
})
What's weird is if I try to run $('#first-name-search').val('hello'); in the console directly in the browser it works but it doesn't work when the button is clicked.
$('#perform-new-search').click(function() {
$('#first-name-search').val('hello');
$('#last-name-search').val('');
$('#results-states option:selected').val('Select State');
})
Seems like it's working,
check https://jsfiddle.net/aLLrku6r/

Angularjs, checking if radio buttons in form have been selected

I'm starting with AngularJS, and I'm building a multi-step form where user has to fill different pages. When finished a page, he's allowed to press a next button and fill the following page.
For the first page, I've built in the HMTL a form (named pageOneForm), with different text input fields, marked as required, and in the relative controller I'm doing this watch:
$scope.$watch('pageOneForm.$valid', function(validity) {
ModelData.actualPageCompleted = validity;
})
And it works like a charme. My model (ModelData) is updated.
I was trying to apply the same logic to the following part of the app, the second page. Instead of input text, the user has to select two options from 2 different radio buttons groups.
So I built in the html a list of buttons via ng-repeat :
<div ng-Controller="PageTwo" ng-show='data.actualPage == 2'>
<form name="pageTwoForm">
<h3>General Information > Knowledge About </h3>
<div>
<b>User</b>
<div ng-repeat="option in userOptions">
<input type="radio" name="userGroups" ng-model="data.knowledgeAboutUser" ng-value="option.id" id="{{option.id}}" required>{{option.text}}
</div>
<div ng-repeat="option in targetGroupUserOptions">
<input type="radio" name = "targetUserGroup" ng-model="data.knowledgeAboutTargetGroup" ng-value="option.id" id="{{option.id}}" required>{{option.text}}
</div>
</div>
</form>
and I've implemented the same code as above in its controller:
$scope.$watch('pageTwoForm.$valid', function(validity) {
ModelData.actualPageCompleted = validity;
})
but apparently it doesn't work, and in my model actualPageCompleted is always true...
What am I doing wrong?
Thanks
I did my best to create a controller with some dummy data to get a fiddle working with your example code. Here is the fiddle You need to force the $digest cycle to update your form's validity state on ng-click for the radio buttons (see this SO post for more details), which is why the method
$scope.forceDigest = function(){
setTimeout(function(){ $rootScope.$$phase || $rootScope.$apply(); });
};
is necessary. Alternatively, you can get rid of the method call and uncomment the html code
<h3 ng-show="false">{{data.knowledgeAboutTargetGroup}}</h3>
<h3 ng-show="false">{{data.knowledgeAboutUser}}</h3>
in the fiddle to force the form object to update as well.
And I would make sure that ModelData.actualPageCompleted is not retaining its true value from when pageOneForm.$valid became true and it was set.
I hope that this helps!

Categories

Resources