I have a problem with the value of one input in a bootstrap modal in angular.
I have ngModel on a variable of type ngbDateStruct (for a date picker) but I want replace the placeholder with the current date from my array on my service like the other camps population area and name.
Modal HTML
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modifica Paese</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="tableService.close()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="countryName">Nome Paese</label>
<input type="text" class="form-control" id="countryName" name="countryName"
[(ngModel)]="tableService.country_Copia.name" readonly>
</div>
<div class="form-group">
<label for="countryArea">Area</label>
<input type="number" class="form-control" id="countryArea" name="countryArea"
[(ngModel)]="tableService.country_Copia.area">
</div>
<div class="form-group">
<label for="countryPopulation">Popolazione</label>
<input type="text" class="form-control" id="countryPopulation" name="countryPopulation"
[(ngModel)]="tableService.country_Copia.population ">
</div>
<div class="col-12">
<label for="countryPopulation">Data Censimento</label>
<div class="input-group">
<input readonly class="form-control" placeholder="yyyy-mm-dd" name="dp" [(ngModel)]="model" ngbDatepicker
#d="ngbDatepicker" />
<button class="btn btn-outline-secondary bi bi-calendar3" (click)="d.toggle()" type="button"></button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)="salva_modale()">Salva</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="tableService.close()">Chiudi</button>
</div>
</div>
Modal TS
import { Component, OnInit, } from '@angular/core';
import { TableServiceService } from '../table-service.service';
import { NgbDateStruct, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { DecimalPipe } from '@angular/common';
@Component({
selector: 'app-modal-component',
templateUrl: './modal-component.component.html',
styleUrls: ['./modal-component.component.css']
})
export class ModalComponentComponent implements OnInit {
constructor(public tableService: TableServiceService, private modalService: NgbModal, public decimalPipe: DecimalPipe) {
}
model!: NgbDateStruct;
ngOnInit(): void {
this.model = this.tableService.country_Copia.date;
}
selectedDate: NgbDateStruct | undefined;
openDatePicker(content: any) {
this.modalService.open(content, { centered: true });
}
salva_modale() {
this.tableService.salva_modale_service(this.model, this.tableService.country_Copia.area, this.tableService.country_Copia.population);
}
close() {
this.modalService.dismissAll();
}
}
Service TS
import { Injectable } from '@angular/core';
import { DecimalPipe, formatDate } from '@angular/common';
import { NgbDateStruct, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { DatePipe } from '@angular/common';
@Injectable({
providedIn: 'root'
})
export class TableServiceService {
modalRef!: NgbModalRef;
country_Copia: any = {};
country_modificato = {
id: 0,
name: '',
area: '',
population: '',
date: ''
};
model!: NgbDateStruct;
countries_service_array: any[] = [
{
id: 0,
name: 'Russia',
flag: 'f/f3/Flag_of_Russia.svg',
area: 17075200,
population: 146989754,
date: ""
},
{
id: 1,
name: 'Canada',
flag: 'c/cf/Flag_of_Canada.svg',
area: 9976140,
population: 36624199,
date: ""
},
{
id: 2,
name: 'United States',
flag: 'a/a4/Flag_of_the_United_States.svg',
area: 9629091,
population: 324459463,
date: ""
},
{
id: 3,
name: 'China',
flag: 'f/fa/Flag_of_the_People%27s_Republic_of_China.svg',
area: 9596960,
population: 1409517397,
date: ""
},
];
constructor(private modalService: NgbModal, private decimalPipe: DecimalPipe, private ngbModal: NgbModal, private datePipe: DatePipe) {
this.generateRandomDates();
}
modifica(countryId: number, country: any): void {
const index = this.countries_service_array.findIndex(country => country.id === countryId);
if (index !== -1) {
country = this.countries_service_array[index];
this.country_Copia = { ...country };
this.country_modificato = country;
}
}
openModal(content: any) {
this.modalRef = this.modalService.open(content);
}
close() {
this.ngbModal.dismissAll();
}
generateRandomDates(): void {
const start = new Date(2000, 0, 1).getTime();
const end = new Date().getTime();
this.countries_service_array.forEach(country => {
const randomTimestamp = Math.random() * (end - start) + start;
const randomDate = new Date(randomTimestamp);
const timezoneOffset = randomDate.getTimezoneOffset() * 60 * 1000;
const localDate = new Date(randomDate.getTime() - timezoneOffset);
country.date = localDate.toISOString().split('T')[0];
country.date = this.datePipe.transform(localDate, 'dd-MM-yyyy');
});
}
salva_modale_service(model: NgbDateStruct, area: number, population: number): void {
const index = this.countries_service_array.findIndex(c => c.id === this.country_modificato.id);
if (index !== -1) {
if (isNaN(area) || isNaN(population)) {
alert('Inserire solamente numeri nei campi area e popolazione');
this.close();
return;
}
if (model === undefined) {
alert('Inserire una data valida');
return;
}
const dateString = formatDate(new Date(model.year, model.month - 1, model.day), 'dd-MM-yyyy', 'en-US');
this.countries_service_array[index].date = dateString;
this.countries_service_array[index].area = area;
this.countries_service_array[index].population = population;
}
this.close();
}
}
I've tried for too much time receiving only a frustration for a stupid error
Angular is hard to demo on StackOverflow, but I am building off of my comment above. My suggestion is to make a "dummy" input that shows the initial/placeholder value you want and then switch that out with the real datepicker as soon as the user begins to interact with it.
This is all just example code that is untested, just to give you an idea of how this might be done by what I tried to describe. This may not be perfect.