Angular 6 dynamic rows resets while adding - javascript

add purchase html
<div class="d-flex justify-content-center align-items-center">
<div class="col-md-12 border">
<div class="card-header header-elements-inline">
<h4 class="card-title">Add Purchase</h4>
<button [mat-dialog-close]="true" type="button" class="bootbox-close-button close" data-dismiss="modal"
aria-hidden="true">×</button>
</div>
<form action="" #addPurchaseForm="ngForm" class="purchaseForm" (ngSubmit)="addPurchase(addPurchaseForm)" method="POST">
<div class="card-body">
<div class="col-md-12">
<div class="row justify-content-center">
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Select vendor to add product</label>
<ng-select [items]="vendorData" bindLabel="vendor_name" bindValue="vendor_id" name="vendor_name" #vendor_name="ngModel"
[searchable]="false" required appendTo="body" [closeOnSelect]="true" [(ngModel)]="purchaseDetails.vendor_id">
</ng-select>
<span *ngIf="addPurchaseForm.submitted && vendor_name.errors?.required" class="form-text text-danger">Product Sub
Vendor
is
Required</span>
</div>
</div>
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Reciept No</label>
<input [(ngModel)]="purchaseDetails.reciept_no" name="reciept_no" #reciept_no="ngModel" type="text" required class="form-control">
<span *ngIf="addPurchaseForm.submitted && reciept_no.errors?.required" class="form-text text-danger">Product code
is
Required</span>
</div>
</div>
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Purchased At</label>
<mat-form-field>
<input [(ngModel)]="purchaseDetails.purchased_at" name="purchased_at" #purchased_at="ngModel" required class="form-control" matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<!-- <input [(ngModel)]="purchaseDetails.purchased_at" name="purchased_at" #purchased_at="ngModel" type="text" required class="form-control"> -->
<span *ngIf="addPurchaseForm.submitted && purchased_at.errors?.required" class="form-text text-danger">Product code
is
Required</span>
</div>
</div>
</div>
<h4 class="card-title">Purchase Details</h4>
<mat-dialog-content style="max-height:200px">
<div class="row" *ngFor="let purchaseDetail of purchaseDetails; let i = index;">
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Select Product</label>
<ng-select [items]="productData" bindLabel="product_name" bindValue="product_id" name="vendor_name" #product[i]="ngModel"
[searchable]="false" required appendTo="body" [closeOnSelect]="true" [(ngModel)]="purchaseDetails[i].product_id">
</ng-select>
<span *ngIf="addPurchaseForm.submitted && vendor_name.errors?.required" class="form-text text-danger">Product Sub
Vendor
is
Required</span>
</div>
</div>
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Unit Rate</label>
<input mask="0*.0*" value="{{purchaseDetails[i].rate}}" [(ngModel)]="purchaseDetails[i].rate" name="product_rate" #rate[i]="ngModel" type="text" required class="form-control">
<span *ngIf="addPurchaseForm.submitted && code.errors?.required" class="form-text text-danger">Rate
is
Required</span>
</div>
</div>
<div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Quantity</label>
<input mask="0*" value="{{purchaseDetails[i].quantity}}" [(ngModel)]="purchaseDetails[i].quantity" name="product_quantity" #quantity[i]="ngModel" type="text" required class="form-control">
<span *ngIf="addPurchaseForm.submitted && code.errors?.required" class="form-text text-danger">Quantity
is
Required</span>
</div>
</div>
<!-- <div class="col-md">
<div class="form-group form-group-float">
<label class="form-group-float-label is-visible">Price</label>
<input disabled [(ngModel)]="purchaseDetails[i].quantity * purchaseDetails[i].rate" name="product_price" #price="ngModel" type="text" required
class="form-control">
<span *ngIf="addPurchaseForm.submitted && code.errors?.required" class="form-text text-danger">Price
is
Required</span>
</div>
</div> -->
<div class="col-md-1 align-self-md-center">
<i (click)="removePurchaseDetail(i)" class="icon-minus-circle2 cursor-pointer fs-22 text-danger"></i>
</div>
</div>
</mat-dialog-content>
<div class="row justify-content-center mb-25">
<i (click)="addNewPurchaseDetail()" class="icon-plus-circle2 fs-22 cursor-pointer text-indigo-800"></i>
</div>
</div>
<div class="text-center">
<button type="submit" [disabled]="!purchaseDetails.vendor_id" class="btn btn-primary">Add purchase <i class="icon-paperplane ml-2"></i></button>
</div>
</div>
</form>
</div>
</div>
Add purchase component
import { Component, OnInit, Inject } from '#angular/core';
import { MAT_DIALOG_DATA } from '#angular/material';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-add-purchase',
templateUrl: './add-purchase.component.html',
styleUrls: ['./add-purchase.component.css']
})
export class AddPurchaseComponent implements OnInit {
purchaseDetails : any = [{
product_id : '',
rate : '',
price : '',
quantity : ''
}];
vendorData : any;
productData : any;
constructor(#Inject(MAT_DIALOG_DATA) private addPurchaseData : any) { }
ngOnInit() {
console.log(this.addPurchaseData);
console.log(this.purchaseDetails);
this.vendorData = this.addPurchaseData.vendors;
this.productData = this.addPurchaseData.products;
}
addNewPurchaseDetail(){
console.log(this.purchaseDetails);
this.purchaseDetails.push({
product_id: '',
rate: '',
price: '',
quantity: ''
});
}
removePurchaseDetail(index){
this.purchaseDetails.splice(index, 1);
}
}
while adding new purchase details row
i'am able to get the row but my values are resetting
i don't know what i am doing wrong
Is there any right way to achieve this
I am new to angular pls guide me through this
when i console logged the model values it was there but i don't know why the rows has been resetted

Found the issue:
Input name should be like this:
<input name="reciept_no[{{i}}]" [(ngModel)]="purchaseDetails.reciept_no" #reciept_no="ngModel" type="text" required class="form-control">
I had like this :
<input name="reciept_no" [(ngModel)]="purchaseDetails.reciept_no" #reciept_no="ngModel" type="text" required class="form-control">

Related

Multistep form validate steps & display error messages

I have multiple step form to submit project details divided into three sections which is #account_information, #personal_information & #project_information. I'm facing two issues with this approach:
1- If there is an error in validate the section I can not see the field highlighted in red Also not message display below that field.
2- input file field even if you select a file it will still display an error which not allow me to move into next step ?
$(document).ready(function (){
let multiStepsArea = ['#account_information', '#personal_information', '#project_information']
let currentNum = 0;
$('.next').click(function(){
var form = $("#AddProjectForm");
form.validate({
rules: {
stay_address_field: {
required: true,
},
},
messages: {
stay_address_field: {
required: "يجب تحديد مكان الإقامة",
},
}
});
if (form.valid() == true){
if(currentNum === 0) {
current_fs = $(multiStepsArea[currentNum]);
currentNum++;
next_fs = $(multiStepsArea[currentNum]);
next_fs.show();
current_fs.hide();
}else if(currentNum === 1) {
current_fs = $(multiStepsArea[currentNum]);
currentNum++;
next_fs = $(multiStepsArea[currentNum]);
next_fs.show();
current_fs.hide();
}
}
});
$('.previous').click(function(){
if(currentNum === 1) {
current_fs = $(multiStepsArea[currentNum]);
currentNum--;
next_fs = $(multiStepsArea[currentNum]);
next_fs.show();
current_fs.hide();
}else if(currentNum === 2) {
current_fs = $(multiStepsArea[currentNum]);
currentNum--;
next_fs = $(multiStepsArea[currentNum]);
next_fs.show();
current_fs.hide();
}
});
});
<form action="{{ route('StoreProjectUser') }}" id="AddProjectForm" method="POST" enctype="multipart/form-data">
#csrf
<section class="target_box">
<fieldset id="account_information" class="">
<div id="div1" class="target">
<h4 class="mt-3">أولاً: السيرة الذاتية باللغة العربية وتشمل على:</h4>
<h6 class="mt-3">1- بيانات المشارك الشخصية</h6>
<div class="form-group mt-3">
<label class="form-label">الجنس <span class="text-danger">*</span></label>
<div class="form-check">
<input class="form-check-input" type="radio" name="Radiobtn" id="maleRadiobtn" value="M" checked>
<label class="form-check-label" for="maleRadiobtn">
ذكر
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="Radiobtn" id="femaleRadiobtn" value="F">
<label class="form-check-label" for="femaleRadiobtn">
أنثى
</label>
</div>
#error('Radiobtn')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="stay_address_field" class="form-label">مكان الإقامة <span class="text-danger">*</span></label>
<input type="text" name="stay_address_field" id="stay_address_field" class="form-control" placeholder="" value="{{old('stay_address_field')}}" required />
#error('stay_address_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="civil_id_image_field" class="form-label">صورة واضحة وملونة للبطاقة المدنية <span class="text-danger">*</span></label>
<input type="file" name="civil_id_image_field" id="civil_id_image_field" class="form-control" placeholder="" accept=".png, .jpg, .jpeg" required />
#error('civil_id_image_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<div class="hstack gap-2 justify-content-end">
<a class="btn btn-light Single next" target="2">التالي</a>
</div>
</div>
</div>
</fieldset>
<fieldset id="personal_information" class="">
<div id="div2" class="target">
<h4 class="mt-3">أولاً: السيرة الذاتية باللغة العربية وتشمل على:</h4>
<h6 class="mt-3">2- بيانات المشارك الميدانية</h6>
<div class="row mt-3">
<label for="participate_category_field" class="form-label">فئة المشارك <span class="text-danger">*</span></label>
<select class="form-select" aria-label="Default select example" name="participate_category_field" id="participate_category_field" required >
<option selected disabled>--حدد فئة المشارك--</option>
<option value="1">طالب</option>
<option value="2">معلم</option>
<option value="3">موظف</option>
<option value="4">إشرافي</option>
<option value="5">ولي أمر</option>
<option value="6">تربوي متقاعد</option>
<option value="7">غير ذلك</option>
</select>
#error('participate_category_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="governorate_field" class="form-label">المحافظة <span class="text-danger">*</span></label>
<input type="text" name="governorate_field" id="governorate_field" class="form-control" placeholder="" value="{{old('governorate_field')}}" required />
#error('governorate_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="certificate_concern_field" class="form-label">صورة واضحة بنوع لشهادة تزكية من مدير المدرسة / مدير المؤسسة <span class="text-danger">*</span></label>
<input type="file" name="certificate_concern_field" id="certificate_concern_field" class="form-control" placeholder="" accept=".png, .jpg, .jpeg" required />
#error('certificate_concern_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<div class="hstack gap-2 justify-content-end">
<a class="btn btn-light Single previous" target="1">تراجع</a>
<a class="btn btn-light Single next" target="3">التالي</a>
</div>
</div>
</div>
</fieldset>
<fieldset id="project_information" class="">
<div id="div3" class="target">
<h4 class="mt-3">ثانياً: الملف الإنجازي باللغة العربية ويشمل على:</h4>
<h6 class="mt-3">بيانات المشروع وتشمل التالي:</h6>
<div class="row mt-3">
<label for="project_title_field" class="form-label">اسم المشروع <span class="text-danger">*</span></label>
<input type="text" name="project_title_field" id="project_title_field" class="form-control" placeholder="" value="{{old('project_title_field')}}" required />
#error('project_title_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="project_shorts_field" class="form-label">وصف مختصر للمشروع</label>
<input type="text" name="project_shorts_field" id="project_shorts_field" class="form-control" placeholder="" value="{{old('project_shorts_field')}}" required />
#error('project_shorts_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<label for="project_images_field" class="form-label">ملف صوري بنوع ( jpg, png ) يصف المشروع ب 10 صور كبيرة قياس ( 1070*1600 ) ملونة وواضحة. <span class="text-danger">*</span></label>
<input type="file" name="project_images_field[]" id="project_images_field" class="form-control" placeholder="" multiple required />
#error('project_images_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="form-check mt-3 text-right">
<input type="checkbox" name="accept_terms_field" id="accept_terms_field" class="form-check-input" required />
<label for="accept_terms_field" class="form-check-label float-right">أقر بأن جميع البيانات أعلاه صحيحة وأنني صاحب المشروع وتعود ملكيته لي وأتعهد بأن أقدم كافة الوثائق المطلوبة مني من قبل إدارة المشروع كما أقر بموافقتي على نشر مشروعي في وسائل الإعلام الحديثة ووسائل التواصل الإجتماعي.</label>
#error('accept_terms_field')
<span class="text-danger"> {{ $message }} </span>
#enderror()
</div>
<div class="row mt-3">
<div class="hstack gap-2 justify-content-end">
<a class="btn btn-light Single previous" target="2">تراجع</a>
<!--إلغاء-->
<button type="submit" class="btn btn-success" id="add-btn">إرسال</button>
</div>
</div>
</div>
</fieldset>
</section>
</form>

Dynamic clear form Validation not Working inside FormGroup of FormArray angular 11

I'm trying to clear my validation for that particular group based on user input.I have tried like this but not work for me.
this.myForm = this.fb.group({
questions: this.fb.array([
this.fb.group({
question_name: ['', Validators.required],
type: ['', Validators.required],
point: ['', Validators.required],
no_of_answer: [''],
option: this.fb.array([]),
right_answer: ['', Validators.required],
}),
]),
});
this.type = [
{ name: 'Multiple choice choose one( radio)', type: 'radio' },
{ name: 'Multiple choice choose many', type: 'checkbox' },
{ name: 'True / False(radio)', type: 'radio' },
{
name: 'Fill in the blank single input',
type: 'singleInput',
},
{
name: 'Fill in the blank multiple choice',
type: 'multipleInput',
},
];
// when question type is selected
type_selected(comp) {
const value = comp.get('type').value;
switch (value) {
case 'radio':
const control = comp.controls['right_answer'] as FormControl;
control.clearValidators();
break;
case 'checkbox':
console.log('option required');
break;
case 'singleInput':
console.log('Answer Required');
break;
case 'multipleInput':
console.log('Multiple Answer Required');
break;
default:
console.log('');
}
}
component.html
<div class="container-fluid">
<div *ngIf="new_created; else existing">
<div class="container-fluid mt-3">
<form [formGroup]="myForm" (ngSubmit)="create_company_fun()">
<ng-container formArrayName="questions">
<div
class="row"
*ngFor="let comp of questionFormArr.controls; let i = index"
>
<p-divider align="center" class="mt-3">
<div class="p-d-inline-flex p-ai-center">
<i class="pi pi-question p-mr-2"></i>
<b>Question {{ i + 1 }} </b>
</div>
</p-divider>
<ng-container [formGroupName]="i">
<div class="col-12 col-md-9 mt-5">
<span class="p-float-label w-100">
<input
type="text"
id="inputtext"
class="form-control"
pInputText
formControlName="question_name"
/>
<label for="inputtext">Question Name</label>
</span>
</div>
<div class="col-12 col-md-3 mt-5 d-flex">
<div>
<button
pButton
pRipple
type="button"
icon="pi pi-plus"
(click)="addNewQuestion()"
class="p-button-rounded p-button-success"
></button>
</div>
<div style="margin-left: 1rem">
<button
pButton
pRipple
type="button"
icon="pi pi-minus"
(click)="deleteQuestion(i)"
class="p-button-rounded p-button-danger"
></button>
</div>
</div>
<div class="col-12 col-md-4 mt-5">
<span class="p-float-label w-100">
<input
type="text"
id="inputtext"
class="form-control"
pInputText
formControlName="point"
/>
<label for="inputtext">Points</label>
</span>
</div>
<div class="col-12 col-md-4 mt-5">
<span class="p-float-label w-100">
<p-dropdown
inputId="dropdown"
[autoDisplayFirst]="false"
[options]="type"
[style]="{ minWidth: '100%' }"
optionLabel="name"
optionValue="type"
formControlName="type"
(onChange)="type_selected(comp)"
></p-dropdown>
<label for="dropdown">Type</label>
</span>
</div>
<div
class="col-12 col-md-4 mt-5"
*ngIf="comp.get('type').value == 'multipleInput'"
>
<span class="p-float-label w-100">
<input
type="text"
id="inputtext"
class="form-control"
pInputText
formControlName="no_of_answer"
/>
<label for="inputtext">Number of Answer</label>
</span>
</div>
<ng-container
*ngIf="
comp.get('type').value == 'radio' ||
comp.get('type').value == 'checkbox'
"
>
<div class="col-12" formArrayName="option">
<div
class="row"
*ngFor="
let project of comp.get('option')['controls'];
let j = index
"
>
<div class="col-12 col-md-9 mt-5">
<span class="p-float-label w-100">
<input
type="text"
id="inputtext"
class="form-control"
pInputText
[formControlName]="j"
/>
<label for="inputtext">Option {{ j + 1 }} </label>
</span>
</div>
<div class="col-12 col-md-3 mt-5 d-flex">
<div>
<button
pButton
pRipple
type="button"
icon="pi pi-plus"
(click)="addNewOption(comp.get('option'))"
class="p-button-rounded p-button-success"
></button>
</div>
<div style="margin-left: 1rem">
<button
pButton
pRipple
type="button"
icon="pi pi-minus"
(click)="deleteOption(comp.get('option'), j)"
class="p-button-rounded p-button-danger"
></button>
</div>
</div>
</div>
</div>
</ng-container>
<div
class="col-12 col-md-9 mt-5"
*ngIf="comp.get('type').value !== 'multipleInput'"
>
<span class="p-float-label w-100">
<input
type="text"
id="inputtext"
class="form-control"
pInputText
formControlName="right_answer"
/>
<label for="inputtext">Right Answer</label>
</span>
</div>
<div class="col-12 col-md-3 mt-5">
<button class="btn btn-primary" [disabled]="myForm.invalid">
Create
</button>
</div>
</ng-container>
</div>
</ng-container>
</form>
</div>
</div>
<ng-template #existing>
<app-add-from-existing-question></app-add-from-existing-question>
</ng-template>
</div>
What I want is, If the user selected single-input I want to hide options and their validation.
All Works fine except validation. I'm unable to clear or set validation inside my formgroup
Thanks for the StackBlitz link, however, the details are incomplete there and is throwing an error. Please update the link for future purposes.
Straight from the docs, please try using updateValueAndValidity() which recalculates the value and validation status of the control. Call it on your control constant variable as- control.updateValueAndValidity();
Link: https://angular.io/api/forms/AbstractControl#updatevalueandvalidity

jQuery Cloning and incrementing input, textarea, that has name, id and for

I'm still very new to jQuery, and would need help to how to increment 3 elements in this code.
name, id & for.
The name consist of products[0]category, id consist of checkbox[0], for consist of checkbox[0] which is for labels on the checkbox that id use.
I've tried searching for examples. But all them haven't found any good results that i could learn from unfortunately. So in the codes below, they're not there to increase increment as i have totally no idea what else i can do to increase increment numbering.
$(document).ready(function() {
let $append = $('#append');
// append location's data listing
$append.on('change', '.location', function(){
var value = $(this).val();
$('.location_id').val($('#locations [value="'+value+'"]').data('locationid'));
$('.loc_desc').val($('#locations [value="'+value+'"]').data('locdesc'));
});
// enable checkbox for serialnumbers
$append.on('change','.enable-serial', function(){
let $item = $(this).closest('.product-item');
let $checkbox = $item.find('.enable');
$checkbox.prop('disabled', !this.checked);
});
// ctrl for key in checkbox
$append.on('click', '.keyin-ctrl', function() {
let $container = $(this).closest('.product-item');
let $serial = $container.find('.serial');
$container.find('.display').val(function(i, v) {
return v + $serial.val() + ';\n';
});
$serial.val('').focus();
});
// ctrl for del textarea
$append.on('click', '.undo-ctrl', function() {
let $container = $(this).closest('.product-item');
$container.find('.display').val('');
});
// clone product, increment products[x]var
$('#add_product').on('click', function() {
var itemNo = $('.product-item').length + 1;
var index = $('.product-item').length;
var regex = /^(.+?)(\d+)$/i;
let $product = $append.find('.product-item.template')
.clone()
.show()
.removeClass('template')
.insertAfter('.product-item:last');;
$product.find('span').text('#' + itemNo);
$product.find(':checkbox').prop('checked', false);
$product.find('.enable').prop('disabled', true);
$product.find('input, textarea').val('');
$('#append').append($product);
});
// delete product, but remain original template intact
$('#delete_product').on('click', function(){
var itemNo = $('.product-item').length + 1;
let $product = $append.find('.product-item:last:not(".template")');
$product.remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main class="shadow border">
<h4>{{ __('Product Details') }}</h4>
<hr>
<form method="post" action="">
<!-- Multiple Product addition -->
<div class="form-group row">
<label class="col-sm-2 col-form-label font-weight-bold">{{ __('Product Setting') }}</label><br/>
<div class="col-sm-5">
<button type="button" id="add_product" class="btn btn-dark">{{ __('Add Product') }} <i class="fas fa-plus-square"></i></button>
<button type="button" id="delete_product" class="btn btn-dark ml-3">{{ __('Delete Last Product') }} <i class="fas fa-minus-square"></i></button>
</div>
</div>
<hr>
<!-- Frist Group -->
<div class="product" id="append">
<!-- Product Details -->
<div class="product-item template">
<span>#1</span>
<div class="form-group row">
<label class="col-sm-2 col-form-label font-weight-bold">{{ __('Category') }}</label>
<div class="col-sm-2">
<input class="form-control" name="products[0]category" type="text" placeholder="eg. 333" maxlength="3"required>
</div>
<label class="col-sm-1 col-form-label font-weight-bold">{{ __('Code') }}</label>
<div class="col-sm-2">
<input class="form-control" name="products[0]code" type="text" placeholder="eg. 22" maxlength="2" required>
</div>
<label class="col-sm-1 col-form-label font-weight-bold">{{ __('Partnumber') }}</label>
<div class="col-sm-2">
<input class="form-control" name="products[0]partnumber" type="text" placeholder="eg. NGH92838" required>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label font-weight-bold">{{ __('Brand') }}</label>
<div class="col-sm-2">
<input class="form-control" name="products[0]brand" type="text" placeholder="eg. Rototype" required>
</div>
<label class="col-sm-1 col-form-label font-weight-bold">{{ __('Quantities') }}</label>
<div class="col-sm-2">
<input class="form-control" name="products[0]qty" type="number" placeholder="eg. 1" required>
</div>
<label class="col-sm-1 col-form-label font-weight-bold">{{ __("Location") }}</label>
<div class="col-sm-2">
<input class="form-control location" type="text" name="products[0]loc_name" list="locations" value="">
<input type="hidden" class="location_id" name="products[0]location_id" value="">
<input type="hidden" class="loc_desc" name="products[0]loc_desc" value="">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label font-weight-bold">{{ __("Description") }}</label>
<div class="col-sm-8">
<input class="form-control" name="products[0]description" type="text" placeholder="eg. Spare part for CSD2002">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label font-weight-bold">{{ __('Seial Number(s)') }}</label>
<div class="col-sm-5">
<input class="form-control enable serial" maxlength="25" placeholder="Key in Serial Number and hit button 'Key In'" disabled>
</div>
<div class="col-sm-5">
<button class="btn btn-dark enable keyin-ctrl" type="button" disabled>{{ __('Key In') }}</button>
<button class="btn btn-dark enable undo-ctrl" type="button" disabled>{{ __('Del') }}</button>
<input class="form-check-input ml-4 mt-2 pointer enable-serial" id="checkbox[0]" type="checkbox">
<label class="form-check-label ml-5 pointer" for="checkbox[0]">{{ __('tick to enable serialnumber')}}</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label"></label>
<div class="col-sm-5">
<textarea class="form-control display" name="products[0]serialnumbers" rows="5" style="resize: none;" placeholder="eg. SGH8484848" readonly></textarea>
</div>
</div>
<hr>
</div>
<!-- append start -->
</div>
<div class="form-group row">
<div class="col-sm-12 ">
#csrf
<button type="submit" class="btn btn-dark float-right ml-4">Next <i class="fas fa-caret-right"></i></button>
<!--<button type="button" class="btn btn-secondary float-right" onclick="history.back()">Previous</button>-->
</div>
</div>
<datalist id="locations">
#foreach($locations as $location)
<option value="{{ $location->loc_name}}" data-locationid="{{ $location->location_id }}" data-locdesc="{{ $location->loc_desc }}"></option>
#endforeach
</datalist>
</form>
</div>
</main>
So how do I actually achieve this to add increment to the NAME, ID and FOR my clones?
From the original template of products[0]variable to products[1]variable, checkbox[0] to checkbox[1]
If you want to increment either an ID, class, etc. you can't use .clone(), like the documentation warns:
Using .clone() has the side-effect of producing elements with
duplicate id attributes, which are supposed to be unique. Where
possible, it is recommended to avoid cloning elements with this
attribute or using class attributes as identifiers instead.
You'll have to do it "manually", following a very simple example below:
$( "#addrow" ).click(function() {
var count = $("#product").children().length;
$("#product").append("<input id='field[" + count + "]' type='text'>");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="product">
</div>
<input id="addrow" type="button" value="Add field">

how to show validation message on button click?

could you please tell me how to show validation message on button click ? here is my code
https://stackblitz.com/edit/angular-ugdbvg?file=src/app/app.component.html
I want to show required error message when user press submit button.
<form novalidate [formGroup]="searchForm" class="calform">
<section class="col-sm-6 bg-white pl-20 pr-20">
<div class="form-group col-sm-4 pl-0 error">
<label class="field-title mb-5">name<span class="color-red fontWt"> *</span></label>
<input type="text" placeholder="Enter name" formControlName="name">
<p class="message" [hidden]="searchForm.get('name')">Required</p>
</div>
<div class="form-group col-sm-4 pl-0 error">
<label class="field-title mb-5">last name <span class="color-red fontWt"> *</span></label>
<input type="text" placeholder="Enter last name" formControlName="lastName">
<p class="message" [hidden]="searchForm.get('lastName')">Required</p>
</div>
<button (click)="submitHandler()">submit</button>
</section>
</form>
js
this.searchForm = this.fb.group({
name: ['', Validators.required],
lastName: ['', Validators.required]
});
Add the following line to check:
<span class="error" *ngIf="!!searchForm.controls.name.errors.required && (!!searchForm.controls.name.dirty || !!searchForm.controls.name.touched)">
Name is required.
</span>
<span class="error" *ngIf="!!searchForm.controls.lastName.errors.required && (!!searchForm.controls.lastName.dirty || !!searchForm.controls.name.touched)">
lastName is required.
</span>
in your ts file:
submitHandler() {
if(this.searchForm.valid) {
// Logic
}
}
https://stackblitz.com/edit/angular-utvw23
You need to use *ngIf. Updated Stackblitz code . https://stackblitz.com/edit/angular-fzyrji
Try like this:
Use [hidden] or *ngIf
DEMO
<div class="form-group col-sm-4 pl-0 error">
<label class="field-title mb-5">name<span class="color-red fontWt"> *</span></label> {{show}}
<input type="text" placeholder="Enter name" formControlName="name"> {{searchForm.get('name').invalid}}
<p class="message" [hidden]="!(show && searchForm.get('name').invalid)">Required</p>
</div>
<div class="form-group col-sm-4 pl-0 error">
<label class="field-title mb-5">last name <span class="color-red fontWt"> *</span></label>
<input type="text" placeholder="Enter last name" formControlName="lastName">
<p class="message" [hidden]="!(show && searchForm.get('lastName').invalid)">Required</p>
</div>
<button (click)="show = true ; submitHandler();">submit</button>
</section>
</form>

Dynamically update FormBuilder group inputs

When FormGroup instance is created it creates a FormGroup object that has controls and values.
I have one form that has different controls, they activate depending on what type of form was chosen.
The problem is that formGroup instance stays same, so my controls are not read, and I am getting an error that controls are not found.
I will include task.component.ts file where i update a task and read values into input fields:
upateTaskForm(taskBody, taskType) {
this.formActive = true;
if (this.task === 'medication') {
console.log(this.formGroup + "MEDICATION FORMGROUP");
this.formGroup = this.formBuilder.group({
title: taskBody.title,
instructions: taskBody.instructions,
repeatWeekDay: [null],
medication: this.formBuilder.group({
name: taskBody.medication[0].name,
dose: this.formBuilder.group({
quantity: taskBody.medication[0].quantity,
unit: taskBody.medication[0].dose.unit
}),
method: taskBody.medication[0].method,
notes: taskBody.medication[0].notes
})
});
// Reading Form populates from the formbuilder
} if (this.task === 'reading') {
console.log(this.formGroup + "READING FORMGROUP");
this.formBuilder.group({
title: taskBody.title,
reading: this.formBuilder.group({
measureType: taskBody.reading[0].measureType,
measureValue: taskBody.reading[0].measureValue,
measureUnits: taskBody.reading[0].measureUnits,
}),
instructions: taskBody.instructions,
});
} else if (this.task === 'symptoms') {
this.formGroup = this.formBuilder.group({
title: [null, Validators.required],
instructions: [null]
});
}
}
This is HTML code for the task.component.html
formGroup is an instance of the form and, once its submited values are stored in formGroup.value
formGroup is
Copy from library
Search Tasks in Library
Name
Event
Medication
<label class="form-check-label d-block d-md-inline">
<input type="radio" class="form-check-input" (click)="setTask('reading')" name="event" [checked]='task==="reading"' value="measurement"> Measurement</label>
<label class="form-check-label d-block d-md-inline">
<input type="radio" class="form-check-input" (click)="setTask('record-symptoms')" name="event" [checked]='task==="symptoms"'
value="symptoms"> Record Syptoms</label>
</div>
</div>
<!-- Medication Form -->
<div id="medicationForm" formArrayName="medication" *ngIf="task==='medication'">
<div class="form-group row mx-auto mt-4" formArrayName="dose">
<label class="col-md-3" for="response">Dose</label>
<input type="number" name="number" class="form-contol col-md-6 mr-4" placeholder="Quantity" formControlName="quantity">
<select class="col" formControlName="unit">
<option default>Tablet(s)</option>
<option>Pill</option>
<option>Liquid</option>
</select>
</div>
<div class="form-group row mx-auto mt-4">
<label class="col-md-3"></label>
<input type="text" class="form-contol col-md-6 mr-4" placeholder="Unit / eg Melformin 500mg" formControlName="name">
<select class="col" formControlName="method">
<option default>Oral</option>
<option>IV</option>
<option>Tropical</option>
<option>ophthalmic</option>
</select>
</div>
<div class="form-group row mx-auto mt-4">
<label for="notes" class="col">Notes</label>
<input type="text" name="notes" class="form-control col-md-9 ml-auto" placeholder="Take before bed, take before eating" formControlName="notes">
</div>
</div>
<!-- Measurement Form -->
<div id="measurementForm" *ngIf="task==='reading'" formArrayName="reading" >
<div class="form-group row mx-auto mt-4">
<label class="col-md-3">Measurement Type</label>
<input type="text" class="form-contol col" placeholder="Heart_rate, Systolic, Diastolic, Weight" formControlName="measureType">
</div>
<div class="form-group row mx-auto mt-4">
<label class="col-md-3" for="response">Measurement Value</label>
<input type="number" class="form-contol col-md-6 mr-4" placeholder="Value of the measurement" formControlName="measureValue">
<select class="col" formControlName="measureUnits">
<option default>KG</option>
<option>LBS</option>
<option>mmHg</option>
<option>MG/DL</option>
<option>MMOL</option>
<option>STEPS</option>
</select>
</div>
</div>
<div class="form-group row mx-auto">
<label class="col" for="instructions">Instructions</label>
<input class="form-control col-md-9 ml-auto" type="text" formControlName="instructions" placeholder="Anything to say to the patient">
</div>
<div class="modal-footer my-3">
<button class="d-none d-md-block btn btn-secondary btn-sm btn-md-lg mr-auto ml-md-4" data-dismiss="modal">CANCEL</button>
<button class="d-md-none btn btn-secondary btn-sm btn-md-lg mr-auto ml-md-4" data-dismiss="modal">×</button>
<button type="submit" class="d-none d-md-block btn btn-primary btn-sm btn-md-lg mr-md-4">CREATE TASK</button>
<button class="d-md-none btn btn-primary btn-sm btn-md-lg mr-md-4">OK</button>
</div>
</form>
enter image description here
You only need to use the FormBuilder class once, to get an instance of FormGroup. After that, if you need to dynamically add or remove FormControls, you can use the addControl and removeControl methods.

Categories