How to use ngbDatepicker in for loop - html

I have a problem when using "ngbDatepicker" in form array. The date input cannot be opened. I think because the toggle() function cannot be called correctly.
I have tried creating toggleDate function and call toggle() by using this code
toggleDate(event){
var f = new Function(event+'.toggle()');
f();
}
I have also put
(click)="this[toggle]()"
in my html input date but it doesn't work
This is my HTML Code
<div formArrayName="appntTimes" *ngFor="let appnts of
inputForm.controls.appntTimes?.value; let i = index">
<div [formGroupName]="i">
<div class="form-group row">
<label class="col-2 control-label col-form-label">Date</label>
<div class="col-7">
<div class="input-group date" >
<input class="form-control m-b" formControlName="annceDate1" id="{{'annceDate1'+i}}" name="{{'annceDate1'+i}}" ngbDatepicker #annceDate1{{i}}="ngbDatepicker"
placeholder="DD/MM/YYYY" (click)="toggleDate($event)"/>
<span class="input-group-addon" >
<i class="fa fa-calendar"></i>
</span>
</div>
</div>
</div>
</div>
</div>
I have used multiple datepickers in my page and it worked perfectly but when I put it in ngFor loop and use index to define it’s name and id, It doesn’t work.

Related

Angular Js & html

not able to clear the data using angular Js. I have assigned the value to null and empty. when i debug it the values are getting cleared but in front end the values are not clearing
$scope.callCancel = function() {
$scope.riskObj.areaName ="";
$scope.areaName ="";
$scope.riskObj.areaDesc ="";
$scope.areaDesc =""
html code:
<div ng-if="type == 1"class="col-md-3">
<h5><strong>Risk Area Name</strong></h5>
<div class="form-group">
<input type="text" class="form-control input-sm text-field" data-ng-model="areaName" ng-keyup="getChangedAreaName(areaName)" ng-disabled="type == 2">
</div>
</div>
<div ng-if="type == 1" class="col-md-6">
<h5><strong>Risk Area Description</strong></h5>
<div class="form-group">
<input type="text" class="form-control input-sm text-field" data-ng-model="areaDesc" ng-keyup="getChangedAreaDesc(areaDesc)" ng-disabled="type == 2">
</div>
</div>
<div ng-if="type == 1" style="text-align:right;">
<img src="core/static/images/submit-btn.png" data-ng-click="updateRiskArea(areaName,areaDesc,this)" />
<img src="core/static/images/cancel-btn.png" data-ng-click="callCancel()"/>
</div>
I need to clear the values I enter in the front end. Using the above code I am able to clear already entered data. But once I modify the value and call cancel function the values are not getting cleared
The main issue is you're not setting your ng-model accurately. For example, it should bind to riskObj.areaName as that is your data model, not just areaName. Additionally, you should be initializing these objects in your scope somewhere, like $scope.riskObj = {areaName:'', areaDesc:''};
There are a few issues with your code other than that.
Utilize your anchor tags to be ng-click. Don't have an anchor with a hash for HREF and then put an ng-click inside on an image. Instead, just do something like <a href ng-click="...
You have 3 divs in a row with ng-if="type==1" - why not just put those 3 in a <div class="row" ng-if="type==1"> - cleaner and easier to read/maintain
Inside those conditionals, you have a ng-disabled="type==2" -- that will never ever do anything since the div will ONLY show if type=1
angular.module('selectExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.type = 1;
$scope.riskObj = {
areaName: '',
areaDesc: ''
};
$scope.callCancel = function() {
$scope.riskObj.areaName = "";
$scope.areaName = "";
$scope.riskObj.areaDesc = "";
$scope.areaDesc = ""
}
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.10/angular.min.js"></script>
<div ng-app="selectExample">
<div ng-controller="ExampleController">
<div class='row' ng-if="type == 1">
<div class="col-md-3">
<h5><strong>Risk Area Name</strong></h5>
<div class="form-group">
<input type="text" class="form-control input-sm text-field" data-ng-model="riskObj.areaName">
</div>
</div>
<div class="col-md-6">
<h5><strong>Risk Area Description</strong></h5>
<div class="form-group">
<input type="text" class="form-control input-sm text-field" data-ng-model="riskObj.areaDesc">
</div>
</div>
<div style="text-align:right;">
<a href data-ng-click="callCancel()">cancel</a>
</div>
</div>
</div>

jQuery Form Repeater - Dynamically Show inner repeater based on a value set in the outer repeater

What I am trying to do:
I am building a form repeater, Now I have the plugin working and able to add fields etc, The main form is for setting up a survey with the following logic:
OUTER REPEATER:
Question: input type text \ **Question Type: **input type select
INNER REPEATER:
Choice (can add multiple choices)
On Question Type users can choose a question type and have the option to choose a Single / multiple choice input: at this point I want the nested inner field to be visible (Choice)
So if the choice type is a rating, or a text answer, do not show the nested Choices repeater field only show it when the choice is a single or multiple choice answer.
CODE:
HTML
<!--begin::Repeater-->
<div id="survey">
<div class = "card card-flush shadow-sm">
<div class = "card-header">
<h3 class = "card-title">Survey Questions</h3>
</div>
<div class = "card-body py-2">
<!--begin::Form group-->
<div class="form-group">
<div data-repeater-list="survey">
<div data-repeater-item>
<div class="form-group row">
<div class="col-md-5">
<label class="form-label">Question:</label>
<input type="text" class="form-control form-control-solid mb-5" placeholder="Enter question..." name = "survey[questions][name]"/>
</div>
<div class="col-md-5">
<label class="form-label">Answer Type:</label>
<select class = 'form-select form-select-solid' placeholder = "Choose a question type..." id = "questionType" name = "survey[questions][type]">
<option disabled selected>Choose a question type</option>
<option value = "STANDARD">Open-Ended</option>
<option value = "BOOLEAN">Yes/No Question</option>
<option value = "RATING">Rating</option>
<option value = "SLIDER">Slider</option>
<option value = "SINGLE" id = "additionalSurveyOptions">Single Choice</option>
<option value = "MULTIPLE" id = "additionalSurveyOptions">Multiple Choice</option>
<option value = "NUMBER">Number Input</option>
</select>
</div>
<div class="col-md-2">
<a href="javascript:;" data-repeater-delete class="btn btn-light-danger mt-3 mt-md-8 w-100">
<i class="la la-trash-o"></i>Delete
</a>
</div>
</div>
<div class="inner-repeater mb-5">
<div class = "row">
<div class = "col-7 offset-5">
<div data-repeater-list="choices">
<div data-repeater-item>
<label class="form-label">Choice:</label>
<div class="input-group pb-1">
<input type="text" class="form-control form-control-solid" placeholder="Enter choice here..." name = "choice"/>
<button class="border border-secondary btn btn-icon btn-light-danger" data-repeater-delete type="button">
<i class="la la-trash-o fs-3"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class = "row">
<div class = "col-7 offset-5">
<button class="btn btn-light-primary mt-3 mt-md-8 w-100" data-repeater-create type="button">
<i class="la la-plus"></i> Add a Choice
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!--end::Form group-->
</div>
<div class = "card-footer">
<a href="javascript:;" data-repeater-create class="btn btn-light-primary w-100">
<i class="la la-plus"></i>Add a Question
</a>
</div>
</div>
</div>
<!--end::Repeater-->
JAVASCRIPT
<!-- Tools :: Repeater (Begin) -->
<script>
$('#survey').repeater({
repeaters: [{
selector: '.inner-repeater',
show: function () {
$(this).slideDown();
},
hide: function (deleteElement) {
$(this).slideUp(deleteElement);
}
}],
show: function () {
$(this).slideDown();
},
hide: function (deleteElement) {
$(this).slideUp(deleteElement);
}
});
</script>
<!-- Tools :: Repeater (End) -->
I'm not 100% sure where to start
So I guess to summarise:
How do I hide / show the inner repeater based on the selected option in the outer-repeater
Thanks
I have tried wrapping the repeaters in an if statement (if this.value === "SINGLE") ...
repeaters: [{
selector: '.inner-repeater',
show: function () {
$(this).slideDown();
},
hide: function (deleteElement) {
$(this).slideUp(deleteElement);
}
}],
No luck
I tried setting the display visibility to hidden on the main div itself, then when the input value is SINGLE / MULTIPLE display the inner block... this worked (but it showed the option for every repeated form input) - I just want it to show on the element with the option selected

Angular reactive form display

I'm trying to do an reactive form but I have some problem with the visual part ^^
Here is my html :
<form class="text-center" [formGroup]="requeteModif" (ngSubmit)="modifier()" *ngIf="tableSelect != null">
<h5>Ajouter des informations</h5>
<div class="row">
<div class="col" *ngFor="let modification of modif.controls; let nomCol of nomColonne; let j=index" formArrayName="modif">
<label class="text-center">
{{nomCol}}
</label>
<div *ngFor="let infoTable of infoTable; let i = index;">
<input type="text" class="form-control" [formControlName]="i">
</div>
<div><button class="btn btn-primary" type="submit">Modifier</button></div>
</div>
</div>
</form>
What I want :
Col1 Col2
true A Button (get true, A)
false B Button
[EDIT]
I have find a way to display it the way I want but I don't know how to arrange my code since I'm suppose to use variable..
<div *ngFor="let infoTable of infoTable; let i = index;">
<input *ngIf="j==0" type="text" class="form-control" [formControlName]="i">
<input *ngIf="j==1" type="text" class="form-control" [formControlName]="i+5">
</div>
j id the number of the columns, as you can see it's depend on the number of columns, using this way it's too static but I have no idea about how to fix it...
Sorry for my english
Thank you !
I have find the answer, I just have use the data_binding but I didn't knew how it works ^^' [ngModel]

Multiple FormArrays on Reactive form

I'm new to angular, working on a small project. I completed the UI for the component and that is fine. I'm using reactive form.
this.questionForm = this._formBuilder.group({
question : ['',[Validators.required]],
options : this._formBuilder.array([
this._formBuilder.control({value:'',disabled:false},[Validators.required]),
this._formBuilder.control({value:'',disabled:false},[Validators.required])
]),
answers : this._formBuilder.array([
this._formBuilder.control({value:'',disabled:false}),
this._formBuilder.control({value:'',disabled:false})
])
})
And this is UI part where I'm facing this problem
<div formArrayName="options" class="form-group col-sm-6" *ngFor="let option of options.controls;let i=index;let temp=option as FormGroup">
<div class="d-flex">
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" [formControlName]="i" value="some" aria-label="Checkbox for following text input">
</div>
</div>
<input type="text" [formControlName]="i" class="form-control" [class.is-invalid]="option.invalid && option.touched" [placeholder]="'option '+(i+1)">
</div>
<button class="text-danger remove-btn" (click)="removeOption(i)" *ngIf="enableRmBtn">X</button>
</div>
<small *ngIf="option.invalid && option.touched" class="text-danger">Oops!! Cannot be an empty option</small>
</div>
The text input is working fine, but for implementing the checkbox I have no idea how to achieve it.I cannot give the same value for the formControlName for checkbox input. I just want the checkboxes that are select by the user.
Hoping for a solution. Thanks in advance.

Entered text value is replicating in dynamic generated textbox through ngFor loop in angular 2

I have created a dynamic textbox using ngFor where number of textbox is generated by typing number in another textbox.
HTML.
<div class="input-group col-sm-3">
<span class="input-group-addon">Num of columns: </span>
<input class="form-control"
(change)="addColumnLength($event.target.value)"
[(ngModel)]="workModel.columnLength"
placeholder="Enter num of columns">
</div>
</div>
<div class="column-content col-sm-3">
<div class="input-group col-sm-12" *ngFor="let column of workModel.columnData; let i= index ">
<span class="input-group-addon">Column {{i + 1}} </span>
<input class="form-control"
[value]="workModel.columnData[i]"
(change)="assignColumnData($event.target.value, i)">
</div>
</div>
And this is my .ts file.
addColumnLength( length : number ) {
this.workModel.columnData = [];
for ( let i = 0; i < length; i++ ) {
this.workModel.columnData[i] = undefined;
}
}
assignColumnData( length : number, index : number ) {
this.workModel.columnData[ index ] = length;
}
Here I'm able to generate the number of textbox inserted. But when I enter value in anyone of the textbox it is replicated in all other textbox which is dynamically generated.
I tried also using ngModel as follows
<div class="input-group" *ngFor="let column of workModel.columnData; let i= index ">
<span class="input-group-addon">Column {{i}} </span>
<input class="form-control"
name="index_{{i}}"
[(ngModel)]="workModel.columnData[i]">
</div>
This is also causing the same. Is there anything missed here. Thanks in advance.
Update: When I decrement the length in the text box whole array is resetting as I have given this.workModel.columnData = []. How to not erase the data entered in textbox ?
This issue can be solved by using trackBy.
<div class="column-content col-sm-3">
<div class="input-group col-sm-12" *ngFor="let column of workModel.columnData; let i= index; trackBy:trackByFn ">
<span class="input-group-addon">Column {{i + 1}} </span>
<input class="form-control"
[value]="workModel.columnData[i]"
(change)="assignColumnData($event.target.value, i)">
</div>
</div>
...........
trackByFn(index: any) {
return index;
}
You can refer https://angular.io/api/common/NgForOf for more info