Nothing of events are not working for ng-pick-datetime
<label class="fieldlabel">{{ attribute.attribute.displayName }}: </label>
<label>
<mat-form-field class="field-full-width">
<input [owlDateTimeTrigger]="datePicker" placeholder="Date" [owlDateTime]="datePicker"
[dateTimeInput]="emitValue()" [(ngModel)]="value.value">
<owl-date-time #datePicker></owl-date-time>
</mat-form-field>
</label>
Also I import needed modules:
import { OwlDateTimeModule, OwlNativeDateTimeModule } from 'ng-pick-datetime';
https://www.npmjs.com/package/ng-pick-datetime
I have the same errors for other events: afterPickerOpen,
yearSelected, monthSelected, dateTimeChange
dateTimeInput is an output (event) not an input. Hence, you need to use () instead of [].
(dateTimeInput)="emitValue()"
For further information on outputs, read the official Angular docs.
Related
I want to create custom rules for a form.
The example would be this:
<label class="form-label">Price range from</label>
<validation-provider rules="required_if:price_to" name="Price range from"
v-slot="{ errors }">
<input v-model="price_range_from" type="number"
ref="price_from">
<span class="validation-error form-span">{{ errors[0] }}</span>
</validation-provider>
</div>
<div class="ml-2 w-100">
<label class="form-label">Price range to</label>
<validation-provider name="Price range to"
v-slot="{ errors }">
<input v-model="price_range_to" type="number" class="form-control"
ref="price_to" name="price_range_to">
<span class="validation-error form-span">{{ errors[0] }}</span>
</validation-provider>
Out of this part of form I want to create a rule which has logic of this:
input of price_range_from is required if the price_range_to
field is not null.
input of price_range_from cannot be greater
then price_range_to.
And vice versa.
Script:
import {ValidationProvider, ValidationObserver, extend} from 'vee-validate';
import * as rules from "vee-validate/dist/rules";
import {required} from 'vee-validate/dist/rules';
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
extend('required', {
...required,
message: 'This field is required'
});
Tried to read the documentation on [https://logaretm.github.io/vee-validate/guide/forms.html]
But couldn't find the answer how to make custom rules.
Would be glad if someone showed and example that I could understand and move forward and make more custom rules.
You can do this by targeting other fields: https://vee-validate.logaretm.com/v3/advanced/cross-field-validation.html#targeting-other-fields
import { extend } from 'vee-validate';
extend('password', {
params: ['target'],
validate(value, { target }) {
return value === target;
},
message: 'Password confirmation does not match'
});
...
<ValidationObserver>
<ValidationProvider rules="required|password:#confirm" v-slot="{ errors }">
<input type="password" v-model="password">
<span>{{ errors[0] }}</span>
</ValidationProvider>
<ValidationProvider name="confirm" rules="required" v-slot="{ errors }">
<input type="password" v-model="confirmation">
<span>{{ errors[0] }}</span>
</ValidationProvider>
</ValidationObserver>
Read the docs to see more writing about how it works. Basically #confirm turns into target in the custom rule, and it corresponds to the name attribute on the input.
The validate function in the custom rule just returns a boolean for whether the field is valid or not, so you can add any custom logic in there and just make sure it returns a boolean.
In your case, it sounds like you want two different error messages, so you could consider making two custom rules.
I'm following this tutorial and any time it references an input element it defines them as so:
{{input type="text action='actionname'... }}
I'm told this is out of date and indeed the docs don't use that format, instead using this format:
<input type="text" {{action 'actionname' ... }}
I'm at the point of the tutorial where I'm saving data to the store. I've amended the tutorial to use angle brackets instead of curly braces like so:
<input type="text" value={{model.name}} class="form-control" placeholder="The name of the Library" />
<input type="text" value={{model.address}} class="form-control" placeholder="The address of the Library" />
<input type="text" value={{model.phone}} class="form-control" placeholder="The phone number of the Library" />
<button type="submit" class="btn btn-default" {{action 'saveLibrary' model}}>Add to library list</button>
My route looks like:
import Route from '#ember/routing/route';
export default Route.extend({
model() {
return this.store.createRecord('library');
},
actions: {
saveLibrary(newLibrary) {
newLibrary.save().then(() => this.transitionTo('libraries'));
},
willTransition() {
this.controller.get('model').rollbackAttributes();
}
}
});
When I call the route action saveLibrary and open the debugger, newLibrary doesn't have any data from the model properties. Whenever I change the handlebars template to use curly braces like the tutorial, it works fine; newLibrary contains name, address & phone.
What is the syntax for using angle brankets and having it propagate to route.js?
The angle bracket component should be <Input> not <input>.
Is there a way to disable and make all fields non editable
(input / mat-select / textfield / option/input/mat-checkbox etc) inside a Form
by telling only the parent div name in Angular / Angular-material ?
(cannot editing them)
#Component({
templateUrl: './leaseholder.component.html'
})
export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {
leaseholderForm: FormGroup;
constructor(private router: Router, private formBuilder: FormBuilder) {
this.createLeaseholderForm();
}
createLeaseholderForm() {
this.leaseholderForm = this.formBuilder.group({
civility: [this.identityModel.civility],
firstName: [this.identityModel.firstName, Validators.compose([Validators.pattern("[^\\d]+")])],
lastName: [this.identityModel.lastName, Validators.compose([Validators.pattern("[^\\d]+")])],
birthName: [this.identityModel.birthName, Validators.compose([Validators.pattern("[^\\d]+")])],
birthDate: [this.identityModel.birthDate],
birthPlace: [this.identityModel.birthPlace, Validators.compose([Validators.pattern("[^\\d]+")])],
nationality: ['FR', this.identityModel.nationality],
endOfStay: [this.identityModel.endOfStay]
});
}
<form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
<div class="mat-radio-group-inverted">
<mat-radio-group formControlName="civility">
<mat-radio-button color="primary" value="MR">M.</mat-radio-button>
<mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
</mat-radio-group>
</div>
<mat-form-field>
<input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
</mat-form-field>
...........................
.......... example
</form>
Disabled and not editable are not necessarily the same thing. A disabled input is of course also not editable, but it has a distinct appearance - greyed out and looks 'disabled'. A read-only input looks the same as a normal input, but is not editable. So you have to ask whether you want your controls actually disabled or just read-only.
If you just want read-only, you can simply use the readonly property of <input> and bind it to a variable in your controller. For example:
export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {
#Input() editable: boolean = false; // doesn't have to be an #Input
...
}
<form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput [readonly]="!editable" upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
</mat-form-field>
...
</form>
Note that the editable property doesn't need to be an #Input, but that could be useful if you are using the form as a reusable component and need to make the editable/read-only decision at the DOM level.
For other components like radio buttons, where no readonly property is available, you should probably rethink the layout. It might make more sense to use a different component to display the radio option in read-only mode, rather than the complete list of options. For example, use a label and value pair:
<div *ngIf="editable; else readonlyRadio" class="mat-radio-group-inverted">
<mat-radio-group formControlName="civility">
<mat-radio-button color="primary" value="MR">M.</mat-radio-button>
<mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
</mat-radio-group>
</div>
<div #readonlyRadio>
<label>Civility</label>
<span>{{ leaseholderForm.controls['civility'].value }}</span>
</div>
If you are using reactive form you can achieve this programmatically like this (one-by-one approach):
this.formGroupName.controls[controlNmae].disable();
Eg: this.formGroupName.controls['lastName'].disable()
To disable all at once:
this.formGroupName.disable()
In your case do: this.leaseholderForm.disable()
And to turn it back do: this.leaseholderForm.enable()
What you can do is create a function like this and call it after you have called createLeaseholderForm():
disableForm() {
this.leaseholderForm.disable()
}
for more info read this.
Since disabled attribute doesn't work on some components, what I did is - I set the pointer-events:none on the css to cover all the components inside the div content.
Here's my CSS code:
.disabledDiv {
pointer-events: none;
opacity: 0.4; }
Here's my HTML:
<div class="content-area" [ngClass]="{disabledDiv: !isActiveDiv}">
<!-- other components here (input/select/etc.) -->
<div>
And on my TS:
editData() {
this.isActiveDiv = true;
}
Create a FormGroup as explained here:
https://angular.io/guide/reactive-forms#add-a-formgroup
Then, grab the formGroup instance programmatically and call .disable() on it, like this:
this.leaseholderForm.disable()
Use disable attribute in the html template.
<mat-form-field>
<input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName" disable>
</mat-form-field>
Use readonly attribute in the HTML file inside the input tag.
this.formGroupName.controls['lastName'].disable()
Did not work for me in Angular 8. So I made it work by adding a 'readonly' attribute inside the HTML and then change its value in .ts file.
inside .html file
<input formControlName="email" matInput type="email" #email email="true" [readonly]="email_readonly" />
inside .ts file
email_readonly = false;
yourFunction()
{
this.email_readonly = true;
}
I've got a problem with input type date. I want to bind data from component. Here's my field:
<div class="col-md-6">
<label for="dateOfReport">Data zgłoszenia błędu:</label>
<input type="date" formControlName="dateOfReport" id="dateOfReport" class="form-control" [value]="report.dateOfReport | date:'dd.MM.yyyy'"> {{report.dateOfReport | date:'dd.MM.yyyy'}}
</div>
Here's how variable dateOfReport look:
new Date().toJSON().slice(0, 10)
Where I fail? {{ .. }} shows good date, but my field doesn't take it as default.
When using Reactive Forms, you should not bind data directly to the control, instead use setValue() or patchValue() of FormGroup.
I found an answer to bind the date to the input when creating a form using reactive forms.
I'm using Angular 11.
Here is the HTML
<div class="form-group">
<label for="dateOfReport">Report Date</label>
<input type="date" class="form-control" name="dateOfReport" id="dateOfReport" formControlName="dateOfReport" />
</div>
And here is my angular component
// ...other imports
import { formatDate } from "#angular/common";
// ...
//... creating the form
this.form = this.formBuilder.group({
dateOfReport: [formatDate(new Date(), "yyyy-MM-dd", "en"), [Validators.required]],
// other form fields
});
So I have a multiple codes like this:
<input id="data" type="text" v-model="data">
<label for="data">Data</label>
And I tried to make a property out of it so that I won't repeat it every time:
Vue.component('textbox', {
template: `
<div>
<input :id="id" type="text" v-model="value">
<label :for="id">{{ label }}</label>
</div>
`,
props: [
"id", "value", "label", "for"],
watch: {
value: function(newVal){
this.$emit('input', newVal)
}
}
})
and access it in my html like this:
<textbox v-model="data" id="someID" label="Data"></textbox>
Everything works fine but every time I type in the textbox I get this warning in the console:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
(found in component <textbox>)
Is there a way to remove that warning message? Or am I doing it the wrong way? Any help would be much appreciated.
You don't need to use watch at all. And instead of using v-model, try this:
<input :id="id" type="text" :value="value" #input="$emit('input', $event.target.value)">
working example: http://codepen.io/CodinCat/pen/dNQopR?editors=1010