HTML/JS: How to make an input date change another input date? - javascript

So I'm working on an Angular app and I have these two date input fields:
<div class="col-lg-3">
<div> {{ dataInizioLabel }} </div>
<input required type="datetime-local" name="dataInizio" id="dateInput"
[ngModel]="serverEvent.dataInizio | date:'yyyy-MM-ddTHH:mm'"
(ngModelChange)="manageDateChange($event, dataInizio)" #dataInizio="ngModel">
<small class="text-danger" *ngIf="dataInizio.errors">Campo obbligatorio</small>
</div>
<div class="col-lg-3">
<div> {{ dataFineLabel }} </div>
<input required type="datetime-local" name="dataFine" [ngModel]="serverEvent.dataFine | date:'yyyy-MM-ddTHH:mm'" id="dataFine"
(ngModelChange)="manageDateChange($event, dataFine)" #dataFine="ngModel">
<small class="text-danger" *ngIf="dataFine.errors">Campo obbligatorio</small>
</div>
manageDateChange() JS (incomplete):
manageDateChange(date, inputField) {
if (date) {
this.serverEvent[inputField.name] = new Date(date);
}
let inizio = new Date(date.val())
console.log(inizio)
}
I can't find a way to make so the dataInizioLabel uptades the dataFineLabel field with his same date when it gets changed. For example, if dataInizioLaber gets set to 24/04/2022, I'd need dataFineLabel to self update to the same date.
Also, console says date.val() can't work and gives an error, so I don't think that's the right way to get the date value from the input field.

You might want to try to use a two-way binding on your ngModel like this:
[(ngModel)]="serverEvent.dataInizio | date:'yyyy-MM-ddTHH:mm'"

Related

Setting current date and default time in angular datepicker

I want to set the default date to current date and customize default time in a datepicker using Angular, e.g Current date: 07-02-2020 and default custom time should be 08:00 AM. How can i achieve this please. Here is my html code which only shows date and time based on value selected.
<label class="col-sm-12 col-md-8 form-control-label ml-2" for="date_from">{{'From Date' |
translate}} <span class="danger">*</span>:</label>
<div class="col-md-12">
<input type="datetime-local" [(ngModel)]="leaveList.date_from"
[max]="leaveList.date_to" class="form-control input-md" id="date_from"
name="date_from" (change)="onChangeDate()" max="9999-12-31">
</div>
.component.ts file
You need to use moment library for date/time formatting
1-install moment using npm i moment
2-You have to assign value to date_from in your .ts, just like that
leaveList.date_from = moment().format('MM-DD-YYYY 8:30A')
<input required class="form-control" [(ngModel)]="myDate" type="datetime-local" name="myDate" id="myDate"/>
you can customize the date as you want instead of using new Date()
this.myDate = this.datepipe.transform(new Date(), 'yyyy-MM-ddThh:mm'),
so you have to import DatePipe
import {DatePipe} from '#angular/common'
and initialize in the constructor
constructor(public datepipe: DatePipe){
}
and also add it int the app.module.ts as a provider
providers: [
DatePipe,
....
],
read more https://angular.io/api/common/DatePipe

ngModel is reflecting to all textareas

I have multiple textareas (looping with ngFor and adding new divs with textareas inside). What i need is for every textarea to have separate ngModel and i don't want to directly bind this to property from object in dataArray - for example:
[(ngModel)]='data.note' or [(ngModel)]='data.feedback' .
This works but I don't have feedback property in dataArray so it won't for work for second textarea.
For example with my current implementation change in one textarea is reflecting in all other textareas. I tried with index approach but getting error:
ERROR TypeError: Cannot read property '1' of undefined
<div *ngFor="let data of dataArray; let index=index;trackBy:trackByIndex;">
<div class="card-body">
<form class="form">
<div class="form-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<textarea name="note" [(ngModel)]='selectedNote' class="form-control"
rows="2"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<textarea name="feedback" [(ngModel)]='selectedFeedback' class="form-control" rows="4"></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
With current code if i add some text in first textarea with name 'note' that change is reflected for all textareas with name 'note'. As mentioned tried with adding
[(ngModel)]='selectedFeedback[index]' but i am getting error.
Also tried with giving different names to textareas:
<textarea name="note{{index}}" [(ngModel)]='dataArray[index]' rows="2"></textarea> OR
<textarea name="note{{index}}" [(ngModel)]='selectedNote' rows="2"></textarea>
but change is reflecting for each textarea again.
You can try it with any array, I am using data(n) function to return an Array of length n. In this example it's just for iteration
<div *ngFor="let item of data(8); let i = index">
<textarea [(ngModel)]='values[i]'></textarea>
</div>
// To reflect changes
<div *ngFor="let item of data(8); let i = index">
<div>{{ values[i] }}</div>
</div>
With TS
export class AppComponent {
values = [];
data(n) {
return Array(n);
}
}
Working example in Stackblitz.com
ngModel binds with the name property. So if you want to use multiple textarea try using different name attribute. You can iterate over like -
<ng-container *ngIf="let data of dataArray; index as i">
<textarea name="feedback_{{i}}" [(ngModel)]='selectedFeedback' class="form-control" rows="4"></textarea>
</ng-container>

Watch is not firing when v-model changes

I'm trying to trigger a method when a date is changed in my HTML. When I change the date it is updating the model selectedDate on the screen but its like my watch method just isn't seeing the change at all.
<div class="col-md-8">
<h3>Daily Summary - {{ selectedDate }}</h3>
</div>
<div class="col-md-4">
<p>Change date</p>
<input type="date" name="date" v-model="selectedDate">
</div>
My watch code:
data() {
return{
selectedDate: null
}
},
watch: {
selectedDate: function(){
console.log('date changed');
}
},
Edit: To give more context to the question, I'm running this code inside a template using export like so:
<template>
<div>
<div class="col-md-8">
<h3 v-on:click="testEvent(event)">Daily Summary - <span v-if="data.nxt_summary">{{ selectedDate }}</span></h3>
</div>
<div class="col-md-4">
<p>Change date</p>
<input type="date" name="date" v-model="selectedDate">
</div>
</div>
</template>
<script>
export default {
data() {
return{
selectedDate: null
}
},
watch: {
selectedDate: function(){
console.log('date changed');
}
},
}
</script>
It doesn't look like type="date" fires an input event till there's a whole date in the input. If you use the picker it'll fire, but if you update each piece separately it won't fire till the month, day AND year is filled in. https://jsfiddle.net/tg2s4kkq/1/
What I'd do it set selectedDate to a default value and mark the field required so the user can't empty it.
https://jsfiddle.net/tg2s4kkq/3/

How to call a function on click of date in html 5 datepicker input type

I had a html5 date-time picker.Now on mouseclick(select) of date from date picker I want to call a function.I wonder how can we do that in angular js ...can
someone help me.
html:
<div class="col-lg-4">
<input class="form-control" type="datetime" date-time auto-close="true" view="date"
min-view="date" format="dd/MM/yyyy" ng-model="$root.Details.date" value = "{{dob}}">
</div>
Js
class CreateCustomerCtrl {
constructor($scope,$rootScope,$http,$state,$reactive,$timeout,Notification)
{
//logic here
}
export default angular.module('createCustomer', [
angularMeteor
])
.component('newCustomer', {
templateUrl: 'client/customer/new-customer.html',
controller:['$scope','$rootScope','$http','$state','$reactive','$timeout','Notification'
,customerCtrl]});
So on select of date I want to call a function.
Thanks
You could use ng-change="yourFunc()" event on input with ng-model="myDate" for binding value and inside function you can put your logic.
You should try <input type="date" onchange="return function(this) />;" and return your function to do whatever you want to.

Validate a form field with a dynamically given name in angular

I create a form dynamically in the view by iterating through an object that has the different questions to be asked to the user. One of the attributes of every question is formFieldName which is a a random string I use to give each form field a different name.
<form name="includedForm.newRequestForm" class="form-horizontal" role="form" novalidate>
<div ng-if="message.question.attributes.structure.type == 'object'">
<div ng-repeat="(index,objField) in message.question.attributes.structure.properties">
<div ng-if="objField.type == 'array'" class="form-group" show-errors>
<label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}
<br /><i><small>{{objField.description}}</small></i></label>
<div class="col-sm-6">
<select class="form-control" name="{{objField.formFieldName}}" multiple ng-model="objField.userValue" ng-required="objField.required">
<option ng-repeat="option in objField.items.enum" value="{{option}}">{{option}}</option>
</select>
</div>
</div>
<div ng-if="objField.type == 'boolean'" class="form-group" show-errors>
<label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}</label>
<div class="col-sm-6">
<input class="form-control" name="{{objField.formFieldName}}" ng-model="objField.userValue" type="checkbox" ng-value="option" ng-checked="message.question.attributes" />
</div>
</div>
</div>
</div>
<div class="col-sm-12">
<button ng-click="markAsDone(message)" class="btn btn-primary">Done</button>
</div>
<form>
In the controller I'm able to get the formFieldName attribute but I can't figure out how to use it to do the validation.
var MarkAsDone = function(message) {
$scope.includedForm = {};
var formField = message.question.attributes.formFieldName;
if ($scope.includedForm.newRequestForm.{{formField}}.$valid){
//submit the form
}
}
to answer you question:
first, {{}} is === $scope so you don't use that anywhere other than HTML. You use $scope in your JS and {{}} in HTML which creates a pipe (2-way binding) so that $scope.variable.property has bidirectional binding to {{variable.property }} in HTML.
$scope.includeForm.email === {{ includeForm.email }} === ng-model="includeForm.email" === ng-bind="includeForm.email"
if you set anyone of those all are set so if you set $scope it will show up in HTML and obviously as user input gets captured it is already in $scope ... all connected
when attempting to get the value from HTML back into JS you would need create and set a $scope i.e so if you create $scope.dataModel.dataProperty and use that in ng-model=dataModel.dataProperty (example) you again have two way binding ... you don't need to do anything as angular is taking care of the data pipeline. So if you want to extract the value to var, which is probably a waste as the $scope is already set as soon as the user checks the box
var formField = $scope.dataModel.dataProperty;
// but like I said no need as $scope.dataModel.dataProperty; is your var
In JS if you want to use a dynamic property as an object property key you would place the dynamic value in [] e.g.
$scope.variable[dynamicProperty].method;
// you can set a static property as a key with dot notation i.e.
$scope.variable.staticProperty = val;
Hope that helps

Categories