8

I am using angular powered bootstrap ngbDatepicker. I have created my own custom control which will be used in different pages for date capturing as follows.

<form-date 
  [label]="'Date of birth'" 
  [name]="'inputCPDDOB'"
  [(ngModel)]="birthDate"
  placeholder="mm/dd/yyyy"
  required
  >
</form-date>

Here I have passed birthDate as my model object.

I want

  1. User should be able to choose the date by clicking the CAL button (beside the text box),
  2. User should be able to type a date in format 'MM/DD/YYYY' in the textbox.
  3. After selecting or typing the date, the model should be updated as string with format 'YYYY-MM-DD' by two way data binding.

I have successfully did point#1 and point#2 the date format of text box as MM/DD/YYYY by inheriting NgbDateParserFormatter

But I am not able to change the model structure. While I need to communicate with my web service as 'YYYY-MM-DD' format.

Please help me to achieve the same. Here is the plunker attached.

2
  • value is an object {year:####,month:##,day:##}. when you send to your service, send ''+value.year+'-'+value.month+'-'+value.day Commented Dec 21, 2017 at 8:02
  • It is not possible. I will use this component as reusable component through out my application. So I can not ask my all developers while you are sending any date object pare this pobject to string then send it. Since through out the application I have different model structure and that is drivven by two way data binding. I just send the entire model data. It you suggesting it to process first then send which is quite heavy for this project. Commented Dec 21, 2017 at 12:40

1 Answer 1

14

So I think the easiest way to solve your problem is to provide your own implementation of NgbDateAdapter and inject that into you component. You will need to add

{provide: NgbDateAdapter, useClass: NgbUTCStringAdapter}

to you components providers array and define the NgbUTCStringAdapter somewhere:

@Injectable()
export class NgbUTCStringAdapter extends NgbDateAdapter<string> {

  fromModel(date: string): NgbDateStruct {
    return (date && Number(date.substring(0, 4)) && Number(date.substring(5, 7) + 1) && Number(date.substring(8, 10))) ?
                {year: Number(date.substring(0, 4)),
                    month: Number(date.substring(5, 7)),
                    day: Number(date.substring(8, 10))} : null;
  }

  toModel(date: NgbDateStruct): string {
    return date ? date.year.toString() + '-' + String('00' + date.month).slice(-2)
                            + '-' + String('00' + date.day).slice(-2) : null;
  }
}

The other way to do it would be to put this code into your custom form control something like this:

@Component({
selector: 'app-date',
templateUrl: './date.component.html',
providers: [
    {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => DateComponent),
        multi: true
    },
    {provide: NgbDateParserFormatter, useClass: NgbDateOmniParserFormatter}]
})

export class DateComponent implements ControlValueAccessor {

  model;

  writeValue(value: any) {
    this.model =  (value && Number(value.substring(0, 4)) && 
                        Number(value.substring(5, 7) + 1) &&
                        Number(value.substring(8, 10))) ?
                            {year: Number(value.substring(0, 4)),
                             month: Number(value.substring(5, 7)),
                             day: Number(value.substring(8, 10))} : null;
  }

  propagateChange = (_: any) => {};

  registerOnChange(fn) {
    this.propagateChange = fn;
  }

  registerOnTouched() {}

  change() {
    const date = this.model ? this.model.year.toString() + '-' + 
                   String('00' + this.model.month).slice(-2) + '-' +
                   String('00' + this.model.day).slice(-2) : null;

    this.propagateChange(date);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.