Fairly new to stack overflow but I needed assistance.
I did a backend and the API is working fine after tests from postman.
I can add employee and I can retrieve employee. However, what I am trying to do is, when I click on the card, I want the card I clicked on to display information about the employee in the textboxes and allow me to change and update. I am failing to retrieve and update my HTML. Please help.
In MY TS, I have this:
updateEmployee(employee: Employee){this.load = true;this.users.updateEmployee(employee).subscribe(res => {this.load = false;this.onPrimaryOutline("Employee has been updated");this.getEmployee();},err=>{console.log(err);this.load = false;this.onErrorOutline("Failed to update Employee, please try again");});}
onOpenModal(employee: Employee, mode: string): void {const containerUpdate = document.getElementById('update-container');const button = document.createElement('button');button.type = 'button';button.style.display = 'none';button.setAttribute('data-toggle', 'modal');if (mode === 'save'){this.updateEmployee = employee;button.setAttribute('data-target', '#update-container');}if (mode === 'delete'){button.setAttribute('data-target', '#deleteEmployeeMasterModal');} containerUpdate.appendChild(button);
button.click()}
service:
public updateEmployee(employee: Employee): Observable<Employee>{ return this.http.put<Employee>(${this.updateEmployee_url}/employee/update, employee) }
HTML:
<div class="card" id="update-container" [hidden]="!showForm" data-toggle="modal" data-target="#updateEmployeeModal"><span aria-hidden="true">×</span><ng-template #template><ngx-loading-x [show]="load"></ngx-loading-x><div NgxLoadingXBlur [show]="load"><div class="modal-header">
<div>
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
<span aria-hidden="true">×</span> </button>
</div>
<div class="modal-body">
<div class="card mb-4">
<div class="card-body">
<h6 class="mb-4">{{ 'forms.external-components' | translate }}
</h6>
<form [formGroup]="commonForm" #editForm="ngForm" (ngSubmit)="updateEmployee()" novalidate class="tooltip-label-right">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ngModel="{{editEmployee?.name}}" formControlName="name">
<small>Only letters and at least 2 characters</small>
<div *ngIf="commonForm.get('name')?.errors?.required && !form.submitted" class="invalid-tooltip">Name is required!</div>
</div>
<div class="form-group">
<label>Surname</label>
<input type="text" class="form-control" name="airlineCode" ngModel="{{editEmployee?.surname}}" formControlName="surname">
<small>Only letters and at least 2 characters</small>
<div *ngIf="commonForm.get('surname')?.errors?.required && !form.submitted" class="invalid-tooltip">Code is required!</div>
</div>
<div class="form-group">
<label>Number</label>
<input type="text" class="form-control" name="phonenumber" ngModel="{{editEmployee?.phonenumber}}" formControlName="phonenumber">
<div *ngIf="commonForm.get('phonenumber')?.errors?.required && !form.submitted" class="invalid-tooltip">Number is required!</div>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!commonForm.valid" (click)="updateEmployee(employee, Employee)" (click)="modalRef.hide()">Update</button>
<button type="button" class="btn btn-danger" style="display: inline-block;margin-left: 20px;" (click)="delete()" (click)="modalRef.hide()">Delete</button>
</form>
</div>
</div>
</div>
</div>
I just need to retrieve the values for the specific card when I click on it and be able to update it. But I cannot see what I am omitting. Inspect element says:
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
formGroup's partner directive "formControlName" instead
Related
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
Here i'm using Angular2 i implement some html code for user access but why this data is not binding at Angular2 Source code side
Htmlcode
<form class="form-horizontal" novalidate [formGroup]="EmployeeForm">
<fieldset>
<div class="form-group" [ngClass]="{'has-error': (EmployeeForm.get('EmpName').touched ||
EmployeeForm.get('EmpName').dirty) &&
!EmployeeForm.get('EmpName').valid }">
<label for="name">Name</label>
<input type="text" class="form-control" formControlName="EmpName" [(ngModel)]="EmpName" />
<span>{{EmpName}}</span>
<span class="help-block" *ngIf="(EmployeeForm.get('EmpName').touched ||
EmployeeForm.get('EmpName').dirty) &&
EmployeeForm.get('EmpName').errors">
<span *ngIf="EmployeeForm.get('EmpName').errors.required">
Please enter your first name.
</span>
<span *ngIf="EmployeeForm.get('EmpName').errors.minlength || EmployeeForm.get('EmpName').errors.maxlength ||
EmployeeForm.get('EmpName').pattern">
The first name must be longer than A3 and max5 characters.
</span>
</span>
</div>
<button type="submit" class="btn btn-success" [disabled]="!EmployeeForm.valid" (click)="SaveDetails(EmployeeForm)">SaveDetails</button>
</fieldset>
</form>
component.ts
Here its pinging but data is not binding its showing as
zain = FormGroup {asyncValidator: null, _pristine: false, _touched: true, validator: function, _onCollectionChange: function…}
SaveDetails(Employee) {
}
try to change code from
<button type="submit" class="btn btn-success" [disabled]="!EmployeeForm.valid" (click)="SaveDetails(EmployeeForm)">SaveDetails</button>
to
<button type="submit" class="btn btn-success" [disabled]="!EmployeeForm.valid" (click)="SaveDetails(EmployeeForm.value)">SaveDetails</button>
I am validating my template using angular2, but meanwhile it shows this error:
Cannot read the property 'errors' of undefined.
Here is my template:
<h3 class = "head">{{title}}</h3>
<form [ngFormModel]="form" #f="ngForm">
<div class="row">
<div class="form-group">
<label class="formHeading">Facebook</label>
<input type="text" id="facebook" class="form-control col-xs-3" ngControl="facebook" #facebook="ngForm" >
</div>
<div *ngIf ="facebook.touched && facebok.errors">
<div class="form-row btn">
<button type="submit" class="btn btn-primary pull-right butspace" [disabled]="!f.valid">Save</button>
</div>
</div>
</form>
I dont know why it shows this error. Can anyone fix it?
First of all, you have facebok instead of facebook on the error property.
If that doesn't fix it you're probably using the facebook object before it is assigned, which can happen if it's an #Input() for example.
Use the Elvis operator:
*ngIf ="facebook?.touched && facebook?.errors"
I'm using this code for a form in HTML:
<div class="login-wrapper">
<form>
<div class="popup-header">
<span class="text-semibold"><i class="fa fa-sign-in"></i> Logging in</span>
</div>
<div class="well">
<div class="form-group has-feedback">
<label>Username</label>
<input type="text" name="user" class="form-control" placeholder="e.g. andre#mail.de">
<i class="icon-users form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Password">
<i class="icon-lock form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>reCaptcha</label>
<div class="g-recaptcha" data-sitekey="..."></div>
</div>
<div class="form-actions text-right">
<input type="submit" id="loginbutton" name="loginbutton" value="Login" class="btn btn-primary">
</div>
</div>
</form>
</div>
<!-- /login wrapper -->
However, when I press the submit button, it does nothing but giving me a very strange url in my browser's address bar:
http://localhost/?user=&password=&g-recaptcha-response=&loginbutton=Login
Whenever I fill out fields, it kind of puts the content into the URL:
http://localhost/?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
The intended PHP code which should be run when pressing the button won't even run or load, since this HTML stuff apparently screws things up. I don't know what I have done the wrong way. Any suggestions?
In order for the form to submit somewhere else, you need to set the form elements action parameter.
<form action="some_file.php">
Alternatively, you can take the query string and append it directly to the file path to test your script.
http://localhost/some_file.php?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
Inside of some_file.php, you would then pull out each of the variables like
$user = $_GET['user'];
$password = $_GET['password'];
The very strange url is actually the result of a GET request.
The parameters are separated by an & so you have:
user=peter%40griffin.com&password=somepass&g-recaptcha-response=
"User" is the attribute name of your input and "peter%40griffin.com" is the value
First you need to send your form to an action using the attribute action="save.php", for example an pass the parameters using the method="POST", so the user can't see the values in the URL.
<form action="save.php" method="post">
Below form is for modal window I have two fields if i select the values and without saving or even after save if i open modal window again i see all the required field messages, How can i reset the validation messages every time i open the modal window ?
main.html
<form name="addChallengeForm" id="addChallengeForm" novalidate ng-controller="challengesCtrl" class="border-box-sizing">
<div class="modalForm">
<div class="row">
<div class="form-group col-md-12 fieldHeight">
<label for="originatingGroup" class="required col-md-4">Originating group:</label>
<div class="col-md-8">
<select
kendo-drop-down-list
data-text-field="'text'"
data-value-field="'id'" name="originatingGroup"
k-option-label="'Select'" ng-model-options="{updateOn: 'blur'}"
ng-model="challengesDTO.originatingGrpLkupCode"
k-data-source="challengeGroupOptions"
id="originatingGroup" required>
</select>
<p class="text-danger" ng-show="addChallengeForm.originatingGroup.$touched && addChallengeForm.originatingGroup.$error.required">Originating group is required</p>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label for="challangeDes" class="required col-md-4">Description of challenge:</label>
<div class="col-md-8">
<textarea rows="4" class="form-control"
name="challangeDes" id="challangeDes"
ng-model="challengesDTO.challengeDescription" required
placeholder="Description of challenge" ng-model-options="{updateOn: 'blur'}">
</textarea>
<p class="text-danger" ng-show="addChallengeForm.challangeDes.$touched && addChallengeForm.challangeDes.$error.required">Description of challenge is required</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary pull-right" ng-disabled="addChallengeForm.$invalid" ng-click="submit()">Save</button>
</div>
</form>
mainCtrl.js
$scope.addChallenge = function (opCheckList,checklistSessionKey) {
challengesGridConfig.challengemodalWinConfig.title = 'Add challenge';
$scope.viewChallengeWin.setOptions(challengesGridConfig.challengemodalWinConfig);
$scope.$broadcast('addChallenge', $scope.riskAssessmentDTO.riskAssessmentKey,opCheckList,checklistSessionKey);
};
childCtrl.js
$scope.$on('addChallenge', function (s,id,opCheckList,checklistSessionKey){
$scope.viewChallengeWin.open().center();
$scope.editMode = false;
$scope.clearFields = clearForm();
});
var clearForm = function(){
$scope.challengesDTO = {
themesKyList: null
};
$scope.challengeGroupOptions = kendoCustomDataSource.getDropDownDataSource('RA_ASES_CHLNG_GRP');
$scope.challengThemesDataSource = kendoCustomDataSource.getDropDownDataSource('RA_CHLNG_THEME');
$scope.challengOutComeOptions = kendoCustomDataSource.getDropDownDataSource('RA_CHLNG_OUTCOME');
};
I think, when you are opening the modal you should reset conditions you're using in ng-show (for errors) to default. You're checking if input was touched, why don't you set it untouched when opening modal?
$scope.addChallengeForm.originatingGroup.$setUntouched();
$scope.addChallengeForm.challangeDes.$setUntouched();