How to disable a Dynamic forms in Angular2 - javascript

I have created a dynamic form based on data[fields] from JSON, but I need the form to be initially disabled, so that when we click on Edit then only form becomes editable.
Here is my code for form:
<div class="col-md-8 " [ngSwitch]="fieldInfo.dataTypeName">
<input *ngSwitchCase="'Text'"
class="form-control"
[(ngModel)]="pageInfoBeans.nameValueMap[fieldInfo.name]"
name="{{fieldInfo.name}}"
[required]="fieldInfo.preRequiredInd"
[maxLength]="fieldInfo.fieldSize">
<input *ngSwitchCase="'Email Address'"
type="email"
class="form-control"
[(ngModel)]="pageInfoBeans.nameValueMap[fieldInfo.name]"
name="{{fieldInfo.name}}"
[required]="fieldInfo.preRequiredInd"
[maxLength]="fieldInfo.fieldSize">
and in my component HTML which populates from above switch case :
<app-form class="" [fieldInfo]="fieldItem.fieldInfo" [pageInfoBeans]="pageInfoBeans"></app-form>

Initially set the form to disabled.
component.ts
showForm?:boolean = false;
component.html
<button (click)="showForm = !showForm">Edit</button>
<form *ngIf="showForm">
...form markup
</form>

You need to do something like this:
<button class='form-control' (click)='isEditable = !isEditable'>Edit Mode</button>
<div class="col-md-8 " *ngIf='isEditable' [ngSwitch]="fieldInfo.dataTypeName">
<input *ngSwitchCase="'Text'"
class="form-control"
[(ngModel)]="pageInfoBeans.nameValueMap[fieldInfo.name]"
name="{{fieldInfo.name}}"
[required]="fieldInfo.preRequiredInd"
[maxLength]="fieldInfo.fieldSize" />
<input *ngSwitchCase="'Email Address'"
type="email"
class="form-control"
[(ngModel)]="pageInfoBeans.nameValueMap[fieldInfo.name]"
name="{{fieldInfo.name}}"
[required]="fieldInfo.preRequiredInd"
[maxLength]="fieldInfo.fieldSize" />
</div>

[disabled]="!isEditable" where initialize isEditable = 'disabled' this could be added in both the text and email input fields.
Also in your edit button you can add a callback for click where you can set isEditable = ''.

#Directive({
selector : ["canbedisabled"]
})
export class Canbedisabled{
constructor(private el: ElementRef) {
}
#Input()
set blocked(blocked : boolean){
this.el.nativeElement.disabled = blocked;
}
}
<input formControlName="first" canbedisabled [blocked]="isDisabled">
You can solve it with a Directive. A directive named Canbedisabled and a property "blocked", for example. Write a setter for blocked and set it to nativelement.disabled property.
refer: https://github.com/angular/angular/issues/11271

Related

Is it possible assign the checked state to the value of the current checkbox in razor form without onclick method?

I have an ASP.Net Core MVC Web Application project.
I want to send the checkbox's checked state as the value to the model's related parameter on form submit.
I have seen so many examples that using jquery to get/set the value of the checkbox via onchange methods.
What I wonder is that is it possible to assign the current checkbox's checked state to the value in a similar way to the code below.(it doesn't work)
<input type="checkbox" id="IsActive" name="DTO.IsActive" checked="#Model.IsActive" value="(this.checked)"
One of the simplest working examples I found is the following but it returns false if the checkbox is checked by default and its state is not changed.
<input type="checkbox" id="IsActive" name="DTO.IsActive" checked="#Model.IsActive" onchange="if(this.checked) this.value='true'; else this.value='false';" >
I know that there are many ways to achieve what I want but I want the cleanest solution.
Thanks in advance!
Edit: The structure of my code is as follows:
View
#model MyModel
<form id="UpdateForm" class="was-validated" method="post" enctype="multipart/form-data" asp-controller="ControllerName" asp-action="Update">
<div class="modal-body">
<div class="form-group">
<input type="text" class="form-control" id="Name" name="DTO.Name" value="#Model.Name" required>
<input type="checkbox" id="IsActive" name="DTO.IsActive" checked="#Model.IsActive">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" data-save="modal">Update</button>
</div>
</form>
Controller
public async Task<IActionResult> Update(Guid id, UpdateDto DTO)
{
...
}
Solution
https://www.learnrazorpages.com/razor-pages/forms/checkboxes
In View
<input type="checkbox" " id="IsActive" name="DTO.IsActive" checked="#Model.IsActive" value="true">
In DTO Object Set Default
public bool IsActive { get; set; } = false;
Yes you can do it by using an inline razor statement #()
It would look something like this:
<input type="checkbox" id="IsActive" name="DTO.IsActive" #(Model.IsActive ? "checked" : "") />
also you could use the Checkbox helper
#Html.CheckBoxFor(model => model.IsActive )

What is the easiest way to make editForm in Angular?

In my database i have many users which has many recipes.
Every recipe has some properties and collection of ingredients.
Below is screenshot
Recipe with all properties
So when user display recipe to edit on page should appear (form) recipe with loaded current data. This is kind of working because i can see the data but i think it's no done good.
I have form which is working fine without array (ingredients). Could you tell me how i should add ingredients to my edit form?
I'd be grateful if you see at my code and give me feedback and hints what i should change.
export class RecipeEditComponent implements OnInit {
#ViewChild('editForm') editForm: NgForm;
recipe: IRecipe;
photos: IPhoto[] = [];
ingredients: IIngredient[] = [];
uploader: FileUploader;
hasBaseDropZoneOver = false;
baseUrl = environment.apiUrl;
currentMain: IPhoto;
constructor(private route: ActivatedRoute, private recipeService: RecipeService,
private toastr: ToastrService) { }
ngOnInit(): void {
this.loadRecipe();
}
loadRecipe() {
this.recipeService.getRecipe(this.route.snapshot.params.id).subscribe(recipe => {
this.recipe = recipe;
this.initializeUploader();
})
}
updateRecipe(id: number) {
this.recipeService.editRecipe(id, this.recipe).subscribe(next => {
this.toastr.success('Recipe updated successfully');
this.editForm.reset(this.recipe);
}, error => {
this.toastr.error(error);
});
}
}
HTML
<div class="container mt-4 border" *ngIf="recipe">
<form #editForm="ngForm" id="editForm" (ngSubmit)="updateRecipe(recipe.id)" >
<h5 class=" text-center mt-2">Recipe details:</h5>
<div class="form-group mt-3">
<label for="city">Name</label>
<input class="form-control" type="text" name="name" [(ngModel)]="recipe.name">
</div>
<div class="form-group">
<app-ingredient-editor [ingredients] = "recipe.ingredients"></app-ingredient-editor>
<div *ngFor="let ingredient of recipe.ingredients; let i = index">
<input class="form-control" type="text" name="{{ingredient.name}}" [(ngModel)]="ingredient.name">
<input class="form-control" type="text" name="{{ingredient.amount}}" [(ngModel)]="ingredient.amount">
</div>
</div>
<div class="form-group">
<br>
<p>Add recipes</p>
</div>
<h5 class=" text-center mt-4">Description</h5>
<angular-editor cols=100% rows="6" [placeholder]="'Your description'" [(ngModel)]="recipe.description" name="description"></angular-editor>
</form>
<button [disabled]="!editForm.dirty" form="editForm" class="btn btn-success btn-block mb-5 mt-5">Save changes</button>
</div>
For now it's look like:
Form on page
When i delete ingredient name while changing on the console i have following error:
recipe-edit.component.html:12 ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form
control must be defined as 'standalone' in ngModelOptions.
Problem is that part of code:
<div *ngFor="let ingredient of recipe.ingredients; let i = index">
<input class="form-control" type="text" name="{{ingredient.name}}" [(ngModel)]="ingredient.name">
<input class="form-control" type="text" name="{{ingredient.amount}}" [(ngModel)]="ingredient.amount">
</div>
</div>
But i don't know how to make it working..
How to add add array to template-driven form?
In my case i need to display current ingredients and be able to edit them.
I have tried something like this :
<input class="form-control" type="text" name="ingredient[i].name" [(ngModel)]="ingredient[i].name">
<input class="form-control" type="text" name="ingredient[i].amount" [(ngModel)]="ingredient[i].amount">
But id doesn't work
The problem is that the property name on the form must be defined in order for angular to know which input to update. You're binding name to the same property that the editable model is set to which means the user can edit it and in fact delete it, which isn't good.
The solution is to change it to a unique value that doesn't change. This should work:
<div *ngFor="let ingredient of recipe.ingredients; let i = index">
<input class="form-control" type="text" name="name{{ingredient.id}}" [(ngModel)]="ingredient.name">
<input class="form-control" type="text" name="amount{{ingredient.id}}" [(ngModel)]="ingredient.amount">
</div>
</div>
Link to stackblitz showing it working: https://stackblitz.com/edit/angular-10-base-template-q243lw?file=src%2Fapp%2Fapp.component.html
Edit: fixed bug in original post and added link to stackblitz

How to restrict ngModel changes effect to other inside ng-template in angular7?

This is my code
<ng-template #rowDetailsTmpl let-row="row">
<div class="row" style="padding: 10px 30px;">
<div class="col-sm-5 form-group">
<label> Add Operator </label>
<input type="string" id={{row.DeskId}} name={{row.DeskId}} (ngModelChange)="onChangeOperator($event)" class="form-control"
placeholder="Search Operator" [(ngModel)]="selectedOperatorEmail">
</div>
#ViewChild('rowDetailsTmpl', { static: true }) rowDetailsTmpl: TemplateRef<any>;
this._dataTableService.rowDetailsTemplate = this.rowDetailsTmpl;
In my code input text field using inside ng-template , i set id and name dynamically , but when i change value in textbox it automatically reflect to other input fields. so how to solve this problem in angular7.
in component define the model like array:
selectedOperatorEmail: Array<any> = [];
in html define ngModel define like this:
[(ngModel)]="selectedOperatorEmail[row.DeskId]"

Riot.js: Toggle class on label if input has value

I need to toggle class .has-data on label if input has some data
<label>
<input type="text">
</label>
Can it be done just using some markup without writing javascript?
No, you'll have to write some JavaScript, but the JavaScript is pretty minimal. Change the HTML to this:
<label class="{ has-data: entry }">
<input type="text" onkeyup="{updateEntry}">
</label>
And add this section to the component's script:
<script>
this.entry = '';
updateEntry(e) {
this.entry = e.target.value;
}
</script>

AngularJS: ng-model not clearing input

I have a dynamic input for CPFs (Brazilian 'social security' number).
Every time I enter one CPF, another input should be displayed, and so on..
But for some reason, the ng-model is not being cleared after the CPF is added.
Here's my HTML (inside a directive with isolate scope):
<div ng-repeat="cpf in cpfs" class="field-input">
<input type="text" class="field" ng-model="cpf.number" required>
<label>added CPF</label>
</div>
<div class="field-input">
<input type="text" class="field" ng-model="cpf.number" required>
<label>add new CPF</label>
<button ng-click="addCpf(cpf)" class="btn btn-primary">add</button>
</div>
Here's my controller (inside a directive with isolate scope):
$scope.cpfs = [];
$scope.addCpf = function(cpf) {
$scope.cpfs.push(angular.copy(cpf));
delete $scope.cpf;
};
instead of delete $scope.cpf; use $scope.cpf.number = "";
we can't delete an model, we have to set it to blank, because its linked with our View part

Categories