Поле ввода прядильного устройства PrimeNG неправильно отображает требуемый стиль проверки (поле ввода никогда не помечается красной рамкой). Я использую angular8 и primeng 8.0.2. Числовое поле "iznosDuguje" объявлено как FormControl с проверкой - [Validators.required]. Элемент управления формы правильно помечен как допустимый / недействительный / грязный / и т. Д., Но обычный стиль (красная граница) никогда не отображается на p-spinner.
Снимок экрана проверки (включая всю панель):
https://prnt.sc/pn1u6k
// релевантный .ts part - инициирование formControl для "iznosDuguje"
//more code
this.editPrpStavkaPlanaForm = new FormGroup({
//more code
'iznosDuguje': new FormControl(this.prpStavkaPlanaEdit.iznosDuguje? this.prpStavkaPlanaEdit.iznosDuguje : "", [Validators.required]),
//more code
// релевантный .html part - счетчик "iznosDuguje" и сообщения проверки
<form [formGroup]="editPrpStavkaPlanaForm" (ngSubmit)="snimi()">
//more code
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="iznosDuguje" l10nTranslate>prpStavkaPlanaRashodaIPrihoda.iznosDuguje</label>
<label>*</label>
</div>
<p-spinner class="ui-md-4 ui-sm-6" style="margin-left: -0.6%;" [step]="0.01" #iznosDuguje name="iznosDuguje"
formControlName="iznosDuguje" tabindex="1"
[decimalSeparator]="numberUtil.getDecimalSeparator(lang)" [thousandSeparator]="numberUtil.getThousandSeparator(lang)" [formatInput]="true">
</p-spinner>
<div class="ui-md-4 ui-sm-12 ui-message ui-messages-error ui-corner-all" style="margin-left: 0.6%;"
*ngIf="!editPrpStavkaPlanaForm.get('iznosDuguje').valid && editPrpStavkaPlanaForm.get('iznosDuguje').dirty && editPrpStavkaPlanaForm.get('iznosDuguje').errors">
<span
*ngIf="editPrpStavkaPlanaForm.get('iznosDuguje').errors && editPrpStavkaPlanaForm.get('iznosDuguje').errors['required']">
<i class="fa fa-close"></i>
<label for="iznosDuguje" l10nTranslate>validations.required</label>
</span>
</div>
//more code
// full component.ts Поле объявляется в FormGroup как FormControl:
import { NumberUtil } from 'src/app/global/utils/number-util';
import { OnInit, Input, Output, EventEmitter, Component } from '@angular/core';
import { CoreSort, SortOrder } from './../../../../../global/domains/CoreSort';
import { HttpErrorResponse } from '@angular/common/http';
import { PrpPlanRashodaPrihoda } from 'src/app/backend-domains/prp/PrpPlanRashodaPrihoda';
import { SffIzvorFinansiranja } from './../../../../../backend-domains/sff/SffIzvorFinansiranja';
import { SffMestoTroska } from './../../../../../backend-domains/sff/SffMestoTroska';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { PrpStavkaPlana } from './../../../../../backend-domains/prp/PrpStavkaPlana';
import { BaseComponent } from './../../../../../global/utils/base.component';
import { CoreBackendService } from './../../../../../services/core-backend.service';
import { CoreMessageService } from './../../../../../services/core-message.service';
import { Language, DefaultLocale, TranslationService } from 'angular-l10n';
import { SysKorisnikUtil } from 'src/app/global/utils/sys-korisnik-util';
@Component ({
selector: 'app-prp-stavka-rashoda-prihoda-modal-panel',
templateUrl: './prp-stavka-rashoda-prihoda-modal-panel.component.html',
styleUrls: ['./prp-stavka-rashoda-prihoda-modal-panel.component.css']
})
export class PrpStavkaRashodaPrihodaModalPanelComponent extends BaseComponent implements OnInit {
constructor(private ms: CoreMessageService,
private coreBackendService: CoreBackendService,
private translation: TranslationService,
public numberUtil: NumberUtil) { super(); }
@Language() lang: string;
@DefaultLocale() defaultLocale: string;
prpStavkaPlanaEdit: PrpStavkaPlana;
editPrpStavkaPlanaForm: FormGroup;
//lov mesta troska
fgVisibleSffMestoTroskaLovModalPanel: boolean;
selectedSffMestoTroska: SffMestoTroska;
sffMestoTroskas: SffMestoTroska[];
sffIzvorFinansiranjas: SffIzvorFinansiranja[]
//lov izvora finansiranja
fgVisibleSffIzvorFinansiranjaLovModalPanel: boolean;
@Input() selectedSffIzvorFinansiranja: SffIzvorFinansiranja;
@Input() prpStavkaPlanaEditAzuriranje: PrpStavkaPlana;
@Input() fgVisible: boolean;
@Input() fgUnos: boolean;
@Input() prpPlanRashodaPrihoda: PrpPlanRashodaPrihoda;
@Output() hideModalPanel = new EventEmitter<boolean>();
ngOnInit() {
this.initForm();
this.sffMestoTroskas = [];
this.sffIzvorFinansiranjas = [];
}
onShow() {
this.initForm();
this.sffMestoTroskas = [];
this.sffIzvorFinansiranjas = [];
}
onHide() {
this.hideModalPanel.emit(false);
}
initForm() {
if (this.fgUnos) {
this.prpStavkaPlanaEdit = new PrpStavkaPlana();
} else {
this.prpStavkaPlanaEdit = this.prpStavkaPlanaEditAzuriranje;
this.selectedSffIzvorFinansiranja = this.prpStavkaPlanaEditAzuriranje.sffIzvorFinansiranja;
this.selectedSffMestoTroska = this.prpStavkaPlanaEditAzuriranje.sffMestoTroska;
}
this.editPrpStavkaPlanaForm = new FormGroup({
'brojKonta': new FormControl(this.prpStavkaPlanaEdit.brojKonta,[Validators.required]),
'iznosDuguje': new FormControl(this.prpStavkaPlanaEdit.iznosDuguje? this.prpStavkaPlanaEdit.iznosDuguje : "", [Validators.required]),
'iznosPotrazuje': new FormControl(this.prpStavkaPlanaEdit.iznosPotrazuje? this.prpStavkaPlanaEdit.iznosPotrazuje : "", [Validators.required]),
'izvorFinansiranja': new FormControl(this.prpStavkaPlanaEdit.sffIzvorFinansiranja ? this.prpStavkaPlanaEdit.sffIzvorFinansiranja.internaSifra : null),
'mestoTroska': new FormControl(this.prpStavkaPlanaEdit.sffMestoTroska ? this.prpStavkaPlanaEdit.sffMestoTroska.sifra : null),
'namena': new FormControl(this.prpStavkaPlanaEdit.namena, [Validators.required]),
'napomena': new FormControl(this.prpStavkaPlanaEdit.napomena),
});
}
hidePanel() {
this.fgVisible = false;
}
snimi() {
this.markFormAsDirty();
if (this.editPrpStavkaPlanaForm.valid) {
this.prpStavkaPlanaEdit.prpPlanRashodaPrihoda = this.prpPlanRashodaPrihoda;
this.prpStavkaPlanaEdit.brojKonta = this.editPrpStavkaPlanaForm.get('brojKonta').value;
this.prpStavkaPlanaEdit.namena = this.editPrpStavkaPlanaForm.get('namena').value;
this.prpStavkaPlanaEdit.napomena = this.editPrpStavkaPlanaForm.get('napomena').value;
this.prpStavkaPlanaEdit.iznosDuguje = this.editPrpStavkaPlanaForm.get('iznosDuguje').value;
this.prpStavkaPlanaEdit.iznosPotrazuje = this.editPrpStavkaPlanaForm.get('iznosPotrazuje').value;
this.prpStavkaPlanaEdit.sffIzvorFinansiranja = this.selectedSffIzvorFinansiranja;
this.prpStavkaPlanaEdit.sffMestoTroska = this.selectedSffMestoTroska;
this.coreBackendService.postResource('/prp-stavka-plana/insert/', this.prpStavkaPlanaEdit).subscribe(
(dataResult) => {
this.ms.addSuccessMessage(this.translation.translate('prpEvidencijaPlanovaRashodaIPrihoda.snimanjePrpPlanRashodaPrihoda'), this.translation.translate('prpEvidencijaPlanovaRashodaIPrihoda.snimanjePrpPlanRashodaPrihodaUspesno'));
this.hidePanel();
},
(error: HttpErrorResponse) => {
this.ms.addErrorMessage(error.error.error, error.error.error_description);
}
);
}
}
onShowLovMestoTroska() {
this.fgVisibleSffMestoTroskaLovModalPanel = true;
}
resetMestoTroska() {
this.selectedSffMestoTroska = null;
this.editPrpStavkaPlanaForm.controls.mestoTroska.setValue(null);
this.editPrpStavkaPlanaForm.get('mestoTroska').markAsDirty();
}
onHideLovMestoTroska(sffMestoTroska: SffMestoTroska) {
if (sffMestoTroska) {
this.selectedSffMestoTroska = sffMestoTroska;
}
setTimeout(() => { this.fgVisibleSffMestoTroskaLovModalPanel = false; });
}
public searchMestoTroska(event) {
let sifra:string=event.query.trim();
if(sifra.length<2){
// ukucati barem 2 karaktera sifre
this.sffMestoTroskas = [];
return;
}
let coreSorts: CoreSort[] = [];
let coreSort: CoreSort = { sortField: "sifra", sortOrder: SortOrder.ASC };
coreSorts.push(coreSort);
let pretraga: { key: string, value: any }[];
pretraga = [];
pretraga.push({ key: "sifra", value: sifra });
pretraga.push({ key: "idFirma", value: SysKorisnikUtil.getOdabranaFirma().idFirma })
return this.coreBackendService.getResourceForDataTable('/sff-mesto-troska/filter-lov', 0, 20, coreSorts, pretraga).subscribe(
(response: any) => {
this.sffMestoTroskas = response.content;
},
(error: HttpErrorResponse) => {
this.sffMestoTroskas = [];
if (error.status === 403) {
this.ms.addErrorMessage(this.translation.translate('error.coreErrorMessage'), this.translation.translate("error.coreUnauthorizedError"));
}
else {
this.ms.addErrorMessage(this.translation.translate('error.coreErrorMessage'), this.translation.translate("error.coreErrorMessageDescription"));
}
}
);
}
public searchIzvorFinansiranja(event) {
let internaSifra:string=event.query;
let coreSorts: CoreSort[] = [];
let coreSort: CoreSort = { sortField: "internaSifra", sortOrder: SortOrder.ASC };
coreSorts.push(coreSort);
let pretraga: { key: string, value: any }[];
pretraga = [];
pretraga.push({ key: "pretragaInternaSifra", value: internaSifra });
pretraga.push({ key: "idFirma", value: SysKorisnikUtil.getOdabranaFirma().idFirma })
return this.coreBackendService.getResourceForDataTable('/sff-izvor-finansiranja/filter-lov', 0, 20, coreSorts, pretraga).subscribe(
(response: any) => {
this.sffIzvorFinansiranjas = response.content;
},
(error: HttpErrorResponse) => {
this.sffIzvorFinansiranjas = [];
if (error.status === 403) {
this.ms.addErrorMessage(this.translation.translate('error.coreErrorMessage'), this.translation.translate("error.coreUnauthorizedError"));
}
else {
this.ms.addErrorMessage(this.translation.translate('error.coreErrorMessage'), this.translation.translate("error.coreErrorMessageDescription"));
}
}
);
}
onShowLovIzvorFinansiranja() {
this.fgVisibleSffIzvorFinansiranjaLovModalPanel = true;
}
resetIzvorFinansiranja() {
this.selectedSffIzvorFinansiranja = null;
this.editPrpStavkaPlanaForm.controls.izvorFinansiranja.setValue(null);
this.editPrpStavkaPlanaForm.get('izvorFinansiranja').markAsDirty();
}
onHideLovIzvorFinansiranja(sffIzvorFinansiranja: SffIzvorFinansiranja) {
if (sffIzvorFinansiranja) {
this.selectedSffIzvorFinansiranja = sffIzvorFinansiranja;
}
setTimeout(() => { this.fgVisibleSffIzvorFinansiranjaLovModalPanel = false; });
}
markFormAsDirty() {
Object.keys(this.editPrpStavkaPlanaForm.controls).forEach(key => {
this.editPrpStavkaPlanaForm.get(key).markAsDirty();
});
}
}
// full component.html
<p-dialog [modal]="true" [contentStyle]="{'overflow':'visible'}" [(visible)]="fgVisible" (onShow)="onShow();"
(onHide)="onHide()" [responsive]="true" [closeOnEscape]="false" focusFirstDirective>
<p-header>
<label *ngIf="fgUnos" l10nTranslate>new</label>
<label *ngIf="!fgUnos" l10nTranslate>edit</label>
</p-header>
<form [formGroup]="editPrpStavkaPlanaForm" (ngSubmit)="snimi()">
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="brojKonta" l10nTranslate>prpStavkaPlanaRashodaIPrihoda.brojKonta</label>
<label>*</label>
</div>
<input #brojKonta class="ui-md-4 ui-sm-6 first" pInputText type="text" id="brojKonta" name="brojKonta"
formControlName="brojKonta" maxlength="20" />
<div class="ui-md-4 ui-sm-12 ui-message ui-messages-error ui-corner-all"
*ngIf="!editPrpStavkaPlanaForm.get('brojKonta').valid && editPrpStavkaPlanaForm.get('brojKonta').dirty && editPrpStavkaPlanaForm.get('brojKonta').errors">
<span
*ngIf="editPrpStavkaPlanaForm.get('brojKonta').errors && editPrpStavkaPlanaForm.get('brojKonta').errors['required']">
<i class="fa fa-close"></i>
<label for="brojKonta" l10nTranslate>validations.required</label>
</span>
<span
*ngIf="editPrpStavkaPlanaForm.get('brojKonta').errors && editPrpStavkaPlanaForm.get('brojKonta').errors['emptyRequiredField']">
<i class="fa fa-close"></i>
<label for="brojKonta" l10nTranslate>validations.emptyRequiredField</label>
</span>
</div>
</div>
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="iznosDuguje" l10nTranslate>prpStavkaPlanaRashodaIPrihoda.iznosDuguje</label>
<label>*</label>
</div>
<p-spinner class="ui-md-4 ui-sm-6" style="margin-left: -0.6%;" [step]="0.01" #iznosDuguje name="iznosDuguje"
formControlName="iznosDuguje" tabindex="1"
[decimalSeparator]="numberUtil.getDecimalSeparator(lang)" [thousandSeparator]="numberUtil.getThousandSeparator(lang)" [formatInput]="true">
</p-spinner>
<div class="ui-md-4 ui-sm-12 ui-message ui-messages-error ui-corner-all" style="margin-left: 0.6%;"
*ngIf="!editPrpStavkaPlanaForm.get('iznosDuguje').valid && editPrpStavkaPlanaForm.get('iznosDuguje').dirty && editPrpStavkaPlanaForm.get('iznosDuguje').errors">
<span
*ngIf="editPrpStavkaPlanaForm.get('iznosDuguje').errors && editPrpStavkaPlanaForm.get('iznosDuguje').errors['required']">
<i class="fa fa-close"></i>
<label for="iznosDuguje" l10nTranslate>validations.required</label>
</span>
</div>
</div>
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="iznosPotrazuje" l10nTranslate>prpStavkaPlanaRashodaIPrihoda.iznosPotrazuje</label>
<label>*</label>
</div>
<p-spinner class="ui-md-4 ui-sm-6" style="margin-left: -0.6%;" [step]="0.01" #iznosPotrazuje
name="iznosPotrazuje" formControlName="iznosPotrazuje"
[decimalSeparator]="numberUtil.getDecimalSeparator(lang)" [thousandSeparator]="numberUtil.getThousandSeparator(lang)" [formatInput]="true"></p-spinner>
<div class="ui-md-4 ui-sm-12 ui-message ui-messages-error ui-corner-all" style="margin-left: 0.6%;"
*ngIf="!editPrpStavkaPlanaForm.get('iznosPotrazuje').valid && editPrpStavkaPlanaForm.get('iznosPotrazuje').dirty && editPrpStavkaPlanaForm.get('iznosPotrazuje').errors">
<span
*ngIf="editPrpStavkaPlanaForm.get('iznosPotrazuje').errors && editPrpStavkaPlanaForm.get('iznosPotrazuje').errors['required']">
<i class="fa fa-close"></i>
<label for="iznosPotrazuje" l10nTranslate>validations.required</label>
</span>
</div>
</div>
<div class="ui-g" style="margin-bottom: 5px;">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="izvorFinansiranja" translate>prpStavkaPlanaRashodaIPrihoda.izvorFinansiranja</label>
</div>
<p-autoComplete class="ui-md-4 ui-sm-6" formControlName="izvorFinansiranja" [minLength]="1" field="internaSifra"
[placeholder]="'prpStavkaPlanaRashodaIPrihoda.unosIzvorFinansiranja'|translate:lang"
[suggestions]="sffIzvorFinansiranjas" (completeMethod)="searchIzvorFinansiranja($event)"
[forceSelection]="true" [style]="{'width':'100%', 'margin-left': '-0.4vw'}" [inputStyle]="{'width':'100%'}"
[(ngModel)]="selectedSffIzvorFinansiranja" id="izvorFinansiranja" name="izvorFinansiranja">
<ng-template let-value pTemplate="item">
<span>{{value.internaSifra}}</span>
</ng-template>
</p-autoComplete>
<div class="ui-sm-2 ui-md-1">
<button icon="fa fa-list" style="margin-right: 3px;" pButton (click)="onShowLovIzvorFinansiranja()"
type="button" [title]="'choose'|translate:lang"></button>
<button pButton icon="fa fa-close" [title]="'delete'|translate:lang" type="button"
class="ui-button-danger" (click)="resetIzvorFinansiranja()"></button>
</div>
</div>
<div class="ui-g" style="margin-bottom: 5px;">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="mestoTroska" translate>prpStavkaPlanaRashodaIPrihoda.mestoTroska</label>
</div>
<p-autoComplete class="ui-md-4 ui-sm-6" formControlName="mestoTroska" [minLength]="2" field="sifra"
[placeholder]="'prpStavkaPlanaRashodaIPrihoda.unosSifreMestaTroska'|translate:lang"
[suggestions]="sffMestoTroskas" (completeMethod)="searchMestoTroska($event)"
[forceSelection]="true" [style]="{'width':'100%', 'margin-left': '-0.4vw'}" [inputStyle]="{'width':'100%'}"
[(ngModel)]="selectedSffMestoTroska" id="mestoTroska" name="mestoTroska">
<ng-template let-value pTemplate="item">
<span>{{value.sifra}}</span>
</ng-template>
</p-autoComplete>
<div class="ui-sm-2 ui-md-1">
<button icon="fa fa-list" style="margin-right: 3px;" pButton (click)="onShowLovMestoTroska()"
type="button" [title]="'choose'|translate:lang"></button>
<button pButton icon="fa fa-close" [title]="'delete'|translate:lang" type="button"
class="ui-button-danger" (click)="resetMestoTroska()"></button>
</div>
</div>
<!-- <div class="ui-g" style="margin-bottom: 5px;">
<div class="ui-md-2 ui-sm-6 text-right">
<label>"ss"</label>
</div>
<div class="ui-md-4 ui-sm-6">
<input readonly="true" [(ngModel)]= "selectedSffMestoTroska? selectedSffMestoTroska.naziv: selectedSffMestoTroska " [ngModelOptions]="{standalone: true}" />
</div>
</div> -->
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="namena" l10nTranslate>core.namena</label>
<label>*</label>
</div>
<textarea #namena class="ui-md-10 ui-sm-6" pInputTextarea type="text" id="namena" name="namena"
formControlName="namena" maxlength="512"></textarea>
<div class="ui-md-2 ui-sm-6 text-left">
</div>
<div class="ui-md-10 ui-sm-6 ui-message ui-messages-error ui-corner-all"
*ngIf="!editPrpStavkaPlanaForm.get('namena').valid && editPrpStavkaPlanaForm.get('namena').dirty && editPrpStavkaPlanaForm.get('namena').errors">
<span
*ngIf="editPrpStavkaPlanaForm.get('namena').errors && editPrpStavkaPlanaForm.get('namena').errors['required']">
<i class="fa fa-close"></i>
<label for="namena" l10nTranslate>validations.required</label>
</span>
<span
*ngIf="editPrpStavkaPlanaForm.get('namena').errors && editPrpStavkaPlanaForm.get('namena').errors['emptyRequiredField']">
<i class="fa fa-close"></i>
<label for="namena" l10nTranslate>validations.emptyRequiredField</label>
</span>
</div>
</div>
<div class="ui-g">
<div class="ui-md-2 ui-sm-6 text-right">
<label for="napomena" l10nTranslate>core.napomena</label>
</div>
<textarea #napomena class="ui-md-10 ui-sm-6" pInputTextarea type="text" id="napomena" name="napomena"
formControlName="napomena" maxlength="512"></textarea>
<div class="ui-md-2 ui-sm-6 text-left">
</div>
</div>
<br />
<div class="row text-center">
<button pButton icon="fa fa-check" [label]="'save'|translate:lang" type="submit" class="ui-button-primary"
style="margin-right: 5px;"></button>
<button pButton icon="fa fa-close" [label]="'cancel'|translate:lang" type="button" class="ui-button-danger"
(click)="hidePanel()"></button>
</div>
</form>
</p-dialog>
<app-sff-izvor-finansiranja-lov [fgVisible]="fgVisibleSffIzvorFinansiranjaLovModalPanel"
(hideModalPanel)="onHideLovIzvorFinansiranja($event);">
</app-sff-izvor-finansiranja-lov>
<app-sff-mesto-troska-lov-modal-panel [fgVisible]="fgVisibleSffMestoTroskaLovModalPanel"
(hideModalPanel)="onHideLovMestoTroska($event);">
</app-sff-mesto-troska-lov-modal-panel>