Tabindex not working after focus on childcomponent - html

I've made a typeahead that uses hostlistner to listen after focus and then activate focus on the input:
<input #inputField type="text" class="form-control" [(ngModel)]="model" [ngbTypeahead]="search" [resultTemplate]="rt" [inputFormatter]="formatter" (selectItem)="emitResult($event)"/>
<ng-template #rt let-r="result" let-t="term">
{{r[displayKey]}}
</ng-template>
I listen after focus and set focus in the following way:
#ViewChild('inputField') inputField: ElementRef;
#HostListener('focus') focusIn() {
if (!this.focused) {
setTimeout(() => {
this.focused = true;
this.inputField.nativeElement.focus();
});
}
}
And the problem Im having is that it messes up the tabindex in the parent view.
<div class="col-12">
<label for="sw">SW</label>
<shrd-typeahead id="sw" autoFocus [data]="swList" [filterKey]="'name'" [displayKey]="'name'" (result)=selectedSw($event)
tabindex="1"></shrd-typeahead>
</div>
<div class="col-12">
<label for="amount">Amount</label>
<input type="text" class="form-control" id="amount" [(ngModel)]="amount" tabindex="2">
</div>
So I can set the focus without problem. But when I press "tab" after I've picked SW in the list I go to navigation in chrome instead of going to the next inputfield. :S
Is there a neat solution for this problem?
br

Related

input field or help text doesn't turn red when field is invalid

I used to implement an Angular 2/4 application with Bootstrap 3 and used the Reactive Forms approach. I had a field-validation where the border of the input-field turned red and an error message appeared under the field in red font color.
it looks like this:
<div class="form-group row"
[ngClass]="{'has-error': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" />
<span class="help-block" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
Now i have to use Bootstrap 4 and neither the error message or the input-field turns red. How do i realise this? I tried to change the class of the parent span-block to "form-text" but it didn't work.
For beta version of Bootstrap v4, you can check out Form validation docs. There you can read about the new way, supported by all modern browsers for HTML5 way of form-validation with valid/invalid css classes. There Bootstrap uses the .was-validated and .invalid-feedback classes for what you want to achieve (see code snippet).
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<form class="container" id="needs-validation" novalidate>
<label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
<label for="validationCustom03">City</label>
<input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
"use strict";
window.addEventListener("load", function() {
var form = document.getElementById("needs-validation");
form.addEventListener("submit", function(event) {
if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);
}, false);
}());
</script>
If you want something more similar to Bootstrap 3, you can use what they call server-side validation, as it is written:
As a fallback, .is-invalid and .is-valid classes may be used instead of the pseudo-classes for server side validation. They do not require a .was-validated parent class.
Previous answer for alpha version of Bootstrap V4 (if you must use this).
On Bootstrap V4 Form Validation Docs there is the following example:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="form-group has-danger">
<label class="form-control-label" for="inputDanger1">Input with danger</label>
<input type="text" class="form-control form-control-danger" id="inputDanger1">
<div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
<small class="form-text text-muted">Example help text that remains unchanged.</small>
</div>
So i think you just need to change the has-error class to has-danger
This is the solution:
<div class="form-group row">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
[ngClass]="{'is-invalid': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" >
<span class="invalid-feedback" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
i needed to put the [ngClass]into the input-tag. Then i had to define the class as is-invalid and set the parent span-class to invalid-feedback
i know that your question is for long time ago, but it is the best way to validate the form-control input field by reactive form technique and bootstrap 4 to display the validation. first you need to write some code for your form :
in html section:
<form [formGroup]="myForm">
<div class="form-group">
<label for="name">first Name: </label>
<input type="text" class="form-control" formControlName="firstName" id="name">
<div *ngIf="firstName.touched && firstName.invalid" class="alert alert-danger">
<div *ngIf="firstName.errors.required">filling name is required!</div>
</div>
</div>
in ts file, you should implement the logic to conduct the validation.
in ts file:
myForm = new FormGroup({
'firstName':new FormControl('',Validators.required)
})
//getter method
get firstName(){
this.myForm.get('firstName');
}
now you can see that the validation is working. now to give style to input field to show the red border around the invalid input, just go to css file of component and add this class to the css file:
.form-control.ng-touched.ng-invalid{border:2px solid red;}
and simply you can see the result.

required attribute not working with primeng <p-dropdown>

I am working on a angular2 App and I am using primeng for UI elements. I have dropdowns where I am using the options in these dropdowns are dynamically generated from an API call. Now, when I click the submit button, I want it to validate the forms before submitting. So I am using 'required="required"' in order to make the validation happen.
I see that, if the data is not loaded into the dropdowns, the validation works fine, but when the data is loaded and dropdown options are populated, the primeng validation breaks and it does not throw any message.
Here's my html code..
<div method="post" class="content-form">
<div class="col-lg-6">
<form #myForm="ngForm" class="form-horizontal" novalidate>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">System of Origin</label>
<div class="col-sm-10">
<p-dropdown class="contentDetails" [options]="systemOfOrigins" [(ngModel)]="defaultSoO" [ngModelOptions]="{standalone: true}" required="required" filter="filter" placeholder="NONE"></p-dropdown>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Content Type</label>
<div class="col-sm-10">
<p-dropdown class="contentDetails" [options]="contentTypes" [(ngModel)]="selectedContentType" [ngModelOptions]="{standalone: true}" filter="filter" required="required" placeholder="Choose"></p-dropdown>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Rendition</label>
<div class="col-sm-10">
<p-dropdown id ="rendition" placeholder="Select Rendition" class="contentDetails" [options]="renditions" [(ngModel)]="renditionSelected" [ngModelOptions]="{standalone: true}" filter="filter" required="required"></p-dropdown>
</div>
</div>
</form>
Am I not using the required attribute properly or is there any other way to do it with API calls ?
Help is appreciated
This issue happens if there is a dummy first element in the options array that is used to display please select text, and the label in that dummy element is having some value in it. So just set the label value as '' or null or undefined. It will work.
Try
<p-dropdown [required]="true">
required is a boolean property. If you are setting it dynamically, [required]="isRequired", otherwise required="true" should do it for you.
Try replacing required="required" with required="true" and seeing if that makes them required. If not, I suggest adding a plunkr

Angular2: Reference form in the html from outside of the form tag

I am trying to do the following :
<span *ngIf="heroForm?.dirty">
FOO
</span>
<form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name"
#name="ngModel">
</div>
</form>
Basically, displaying a span outside of the form tag, using the form states (here dirty). Unfortunately, FOO is never shown. Is there any way to work around this ?
Create a model property, showFoo: boolean
and change that on some form event, like onChange
then your span will look like
<span *ngIf="showFoo">FOO</span>

AngularJs ng-dirty flag being applied

In our rather complex form I found that the ng-dirty flag being applied when nothing was actually changed. I originally thought the problem was in the placeholder attribute on the input text, but now even with this attribute removed the flag is still being set when nothing was changed. Is it some sort of a bug? If yes, what is the solution? The problematic elements defined as following
<div class="form-group" ng-show="isNew">
<div class="controls">
<label class="control-label col-md-3 col-lg-3" title="#Labels.operatorCode">#Labels.operatorCode:</label>
<div class="col-md-6 col-lg-6">
<input type="text" name="opCode" id="opCode" ng-model="currentOperator.opCode"
class="form-control" ng-maxlength="6" ng-show="isNew"
ng-required ="isNew" />
<div class="field-validation-error" >
<span ng-show="form.editOperatorGeneralForm.opCode.$error.required && form.editOperatorGeneralForm.opCode.$dirty">#String.Format(Messages.isRequired, Labels.operatorCode)</span>
<span ng-show="form.editOperatorGeneralForm.opCode.$error.maxlength && form.editOperatorGeneralForm.opCode.$dirty">#String.Format(Messages.cannotExceed, Labels.operatorCode, "6")</span>
</div>
</div>
</div>
</div>
The form itself is quite complex with several tabs.
I only see this problem in Chrome browser now, it works fine in IE (no question).
Although this does not answer your exact question, I do believe it will solve your problem. Consider doing your validation logic like this.
View
<div class="form-group" ng-class="{'has-error':!SomeForm.someValue.$valid && SomeForm.$submitted}">
<label class="control-label" for="someValue">Some Value</label>
<input id="someValue"
name="someValue"
class="form-control"
type="text"
placeholder="(Required)"
required
ng-model="vm.temp.someValue"
ng-maxlength="255"/>
<div class="help-block"
ng-messages="SomeForm.someValue.$error"
ng-if="SomeForm.$submitted">
<div ng-messages-include="ui/messages.tpl.html"></div>
</div>
</div>
Controller
vm.submit = function(Form, data) {
if (!Form || Form.$invalid) { return; }
if (vm.isUnchanged()) { return; }
someService.save(data).then(function () {
Form.$setPristine();
});
};

JQuery - radio button CSS not refreshing after submit

I have a form with twitter bootstrap buttons as below
<label class="control-label span3">Status of the Dispute? </label>
<div class="controls span7">
<label class="inline radio">
<input type="radio" id="status" name="status" value="Continue"/> Continue</label>
<label class="inline radio">
<input type="radio" id="status" name="status" value="Resolved"/>Resolved</label>
<label class="inline radio">
<input type="radio" id="status" name="status" value="Referred"/> Referred</label>
<label for="status" class="error">Please tell us the dispute status</label>
</div>
</div>
Upon submission, the form submits the data successfully and refreshes well all other elements except the radio buttons.
I've searched for various options, and came along prop function. It helped me to somepoint as it unchecks the selector on the inside. CSS stylsheet on the user page still remain as if it is selected.
$('input[name="status"]').prop('checked', false);
I also tried this idea
$('input:not(:checked)').parent().removeClass("inline radio");
but its still not successfull.
My full submit code is as follows:
$.validator.setDefaults({
submitHandler: function(form) {
$.post('registermyform.php',
$("#registermyform").serialize(),
function(data)
{
$('#results').html(data);
if (data="yes"){
alert("The new Dispute has been successfully submitted!");
$('#registerDispute')[0].reset();
$('input[name="status"]').prop('checked', false);
$('input:checked').parent().removeClass("inline radio");
}
else {
alert("not submitted!");
}
});
}
});
Please assist. I want to remove the CSS of radio buttons such that it doesn't appear as if it is checked while it is not.
You need to iterate through the elements to reset them all:
var $items = $('input[name="status"]');
for (var i = 0; i < $items.length; i++) {
$($items[i]).prop('checked', false);
}