I'm working on a page which has a nested Formarray.
constructor(private fb: FormBuilder) {
this.buildForm();
}
private buildForm() {
this.trialBudgetForm = this.fb.group({
clients: this.fb.array([])
})
}
addCustomer() {
this.clients.push(this.initCustomer());
}
initCustomer() {
return this.fb.group({
earnedIncomes: this.fb.array([this.initIncome()]),
thirtyAndOneThirdYN: [],
thirtyYN: [],
earnedIncomeExpenseType: [],
earnedIncomeExpense: [],
dependentCareExpense: []
})
}
initIncome() {
return this.fb.group(new ScrAmountType());
}
ngOnInit() {
this.populateData();
}
populateData() {
const clients = this.TrialBudgetData.clients;
const customerFGs = clients.map(customer => this.fb.group({
earnedIncomes: this.populateIncome(customer.earnedIncomes),
thirtyAndOneThirdYN: [this.utilService.YNConvert(customer.thirtyAndOneThirdYN)],
thirtyYN: [this.utilService.YNConvert(customer.thirtyYN)],
earnedIncomeExpenseType: [customer.earnedIncomeExpenseType],
earnedIncomeExpense: [customer.earnedIncomeExpense],
dependentCareExpense: [customer.dependentCareExpense]
}));
const customerFormArray = this.fb.array(customerFGs);
this.trialBudgetForm.setControl('clients', customerFormArray);
}
for demo purpose, i didn't post the entire ts file, coz there are almost 600 lines. But i can provide more detail if needed.
here's the html page (also only a snippet)
<form novalidate [formGroup]="trialBudgetForm" (ngSubmit)="save(trialBudgetForm)">
<div class="settingsPage-box">
<h3 class="box-border-bottom">Earned Income
<span class="float_right add-field add-margin hand" (click)="addCustomer()">
<i class=" fa fa-plus-circle fa-lg plusIconColor"></i>
<span>
Add Earned Income
</span>
</span>
</h3>
<div formArrayName="clients">
<div *ngFor="let earnedIncomeCustomer of clients.controls; let i = index" [formGroupName]="i" class="row-view box-border-bottom">
<div class="box-border-bottom row-view">
<div class="col-sm-3 padding0">
<label for="customer{{i+1}}" class="pushDown">Customer {{i+1}}:</label>
</div>
<div class="col-sm-9 grid-block padding0">
<div class="col-sm-1 float_right" (click)="deleteCustomer(i)">
<span class="delete-row hand">
<i class="fa fa-trash-o"></i>
</span>
</div>
</div>
<div class="col-sm-3">
<label class="pushDown">Earned Income</label>
</div>
<div class="col-sm-9 grid-block">
<div class="row">
<div class="col-sm-6 u-justifyEnd">
<span class="add-margin float-left hand" (click)="addEarnedIncome(i)"><i class=" fa fa-plus-circle fa-lg plusIconColor"></i><span> Add Income</span></span>
</div>
</div>
<div class="row grid-block pd-left amount-grid" formArrayName="earnedIncomes" >
<div class="row-view" *ngFor="let earnedIncome of earnedIncomeCustomer.controls.earnedIncomes.controls; let j = index"
[formGroupName]="j">
<div class="col-sm-5 padding5">
<span class="label-type" *ngIf="j==0">Type</span>
<select class="form-control" formControlName="type" (change)="checkForDuplicateEarnedIncomeType(this.trialBudgetForm.controls.clients.controls[i].controls.earnedIncomes.controls[j].value.type)">
<option value="">Select</option>
<option *ngFor="let optionEntity of this.constantsService.getDropDownFromLookup(this.constantsService.getText('EarningType'))"
value="{{optionEntity.lookupBean.code}}">{{optionEntity.lookupBean.longLabel}}</option>
</select>
</div>
<div class="col-sm-6 pd-left padding5 amount-bg">
<span class="label-type" *ngIf="j==0">Amount</span>
<div class="search-container">
<input (keypress)="this.customValidatorsService.validateNumberOnly($event)" formControlName="amount" class="form-control amount-input search-box"
placeholder="$0.00" currencyMask [options]="{ allowNegative: false,prefix: '$',hundreds: ',' }" maxlength="12"
(keyup)="calculateTotalIncome(earnedIncomeCustomer, i)" />
</div>
<div class="clearfix"></div>
</div>
<div class="col-sm-1 pd-left">
<span class="label-type" *ngIf="j==0"> </span>
<span class="delete-row hand" (click)="deleteIncome(earnedIncomeCustomer, i, j)"> <!-- G.S Income.controls.amount -->
<i class="fa fa-trash-o"></i>
</span>
</div>
</div>
<div class="row-view">
<div class="col-sm-5">
<span class="total-info text-right">Total Earned Income</span>
</div>
<div class="col-sm-6 pd-left amount-bg">
<span class="total-info text-right">${{ earnedIncomeCustomer.totalEarnedIncome | number : '1.2-2'}}
</span>
<div class="clearfix"></div>
</div>
</div>
<div class="row-view">
<div class="col-sm-12 text-center">
<div class="clearfix"></div>
</div>
</div>
</div>
<span *ngIf="duplicateEarnedIncomeType" class="red-font-color">Choose a different use type</span>
</div>
<div class="clearfix"></div>
</div>
<div class="box-border-bottom row-view">
<div class="col-sm-3">
<label class="pushDown">Earned Income Options</label>
</div>
<div class="col-sm-8 grid-block">
<div class="col-sm-5 form-group label-check display-check">
<input type="checkbox" id="check-1" formControlName="thirtyAndOneThirdYN">
<label for="check-1">30+1/3</label>
</div>
<div class="col-sm-6 form-group label-check display-check">
<input type="checkbox" id="check-2" formControlName="thirtyYN">
<label for="check-2">$30</label>
</div>
</div>
<div class="clearfix"></div>
</div>
<div class="box-border-bottom row-view">
<div class="col-sm-3">
<label class="pushDown">Earned Income Expenses</label>
</div>
<div class="col-sm-8 grid-block">
<div class="col-sm-5 form-group padding_right">
<div class="control-label">Type</div>
<select class="form-control" formControlName="earnedIncomeExpenseType">
<option value="-1">Select</option>
<option *ngFor="let optionEntity of this.constantsService.getDropDownFromLookup(this.constantsService.getText('EIexpenseType'))"
value="{{optionEntity.lookupBean.code}}">{{optionEntity.lookupBean.longLabel}}</option>
</select>
</div>
<div class="col-sm-6 padding0 padding_custom">
<div class="control-label">Amount</div>
<input formControlName="earnedIncomeExpense" currencyMask (keypress)="numberOnly($event)" class="form-control" [options]="{ allowNegative: false, prefix: '$',hundreds: ',' }"
placeholder="$0.00" maxlength="10" />
</div>
</div>
<div class="clearfix"></div>
</div>
<div class="row-view">
<div class="col-sm-3">
<label class="pushDown">Dependent Care Expenses</label>
</div>
<div class="col-sm-8 grid-block">
<div class="col-sm-5">
<div class="control-label">Expenses</div>
<input (keypress)="numberOnly($event)" currencyMask formControlName="dependentCareExpense" class="form-control" maxlength="10"
placeholder="$0.00" [options]="{ allowNegative: false, prefix: '$',hundreds: ',' }" />
</div>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</form>
I have been trying to debug this for couple days now. The issue happens after constructor executed and before ngOnInit was called. this error only occur when I added more than one customer, and come back to this page. (adding customer won't cause any problem, only when I comeback to this page that's when the error this.validator is not a function is shown.
It's strange because the error happen between constructor and ngOnInit, and populateData is called in ngOnInit, which means error occured before the page know how many customers will I load. But if only the error occur because I add more than one customer, it seems that applicaiton has to get that info within constructor, in which i didn't load the data yet.
Update 1: Sept 25 3:39PM EST
updated with populateData function
Update 2: full stack error: Sept 25 4:09PM EST
TrialBudgetComponent_Host.html:1 ERROR TypeError: this.validator is not a function
at FormControl.webpackJsonp.../../../forms/#angular/forms.es5.js.AbstractControl._runValidator (forms.es5.js:2645)
at FormControl.webpackJsonp.../../../forms/#angular/forms.es5.js.AbstractControl.updateValueAndValidity (forms.es5.js:2613)
at new FormControl (forms.es5.js:2936)
at FormBuilder.webpackJsonp.../../../forms/#angular/forms.es5.js.FormBuilder.control (forms.es5.js:5780)
at FormBuilder.webpackJsonp.../../../forms/#angular/forms.es5.js.FormBuilder._createControl (forms.es5.js:5822)
at forms.es5.js:5804
at Array.forEach (<anonymous>)
at FormBuilder.webpackJsonp.../../../forms/#angular/forms.es5.js.FormBuilder._reduceControls (forms.es5.js:5803)
at FormBuilder.webpackJsonp.../../../forms/#angular/forms.es5.js.FormBuilder.group (forms.es5.js:5762)
at TrialBudgetComponent.webpackJsonp.../../../../../src/app/trial-budget/trial-budget.component.ts.TrialBudgetComponent.toFromGroup (trial-budget.component.ts:102)
Update 3 question closed: thanks to #yurzui's comment
I just realized that the architecture is messed up for this page. This component has a parent which only has (current component selector) in its template. The two component has exactly the same name just under different folder. The parent is at /trial-budget and children is at /trial-budget/trial-budget-main. The TrialBudgetComponent.toFromGroup is actually a function inside the parent. For some reason, it's being called inside ngInit instead of constructor. Still haven't figure out why error only happen with 2 customer.
But lesson learned:
1. read error message carefully especially first and last couple lines. I didn't read the last line.
2. always construct form inside constructor and populate data inside ngOnInit()
Related
Does anyone know, How to resolve this issue of the crashed javascript script?
I am using 2 checkboxes to load some DOM.
1st checkbox is to expand textarea with the CKEditor script which is loaded with the JS but I have a wire model to send data to the controller.
Here is HTML for 1st checkbox:
<div class="form-group mt-25 d-flex flex-row">
<label class="checkbox-container form-group__label">
{{ __('Extended description') }}
<input type="checkbox" name="extended-description-checkbox" id="extended-description-checkbox" class="checkbox">
<span class="checkmark"></span>
</label>
</div>
<div class="form-group mt-25 cke d-none" id="extended-description-checkbox-div">
<label class="form-group__label" for="extended-description">{{ __('Extended description') }}</label>
<textarea wire:ignore.self wire:model.debounce.250ms.defer="extendedDescription" name="extended-description" id="extended-description" cols="30" rows="10"></textarea>
</div>
2nd checkbox is also handled with the JS and has a temporary URL method since the expanded DOM element should contain uploaded images for the gallery.
Here is HTML of the 2nd checkbox:
<div class="form-group mt-25 d-flex flex-row">
<label class="checkbox-container form-group__label">
{{ __('Use default images') }}
<input type="checkbox" name="use-default-images" id="use-default-images" class="checkbox">
<span class="checkmark"></span>
</label>
</div>
<div class="d-none" id="use-default-images-div">
<div class="form-group mt-25">
<label class="form-group__label">{{ __('Service images') }}</label>
<div class="form-group__uploaded-images">
#if ($additionalImages)
#foreach($additionalImages as $image)
<img src="{{ $image->temporaryUrl() }}" alt="Temporary image">
#endforeach
#endif
</div>
</div>
<div class="custom-file ml-auto">
<button type="button" class="ml-auto styled-link">{{ __('Add images') }}</button>
<div class="row mt-25">
<div class="col-4 col-md-8"></div>
<div class="col-8 col-md-4">
<input wire:ignore.self wire:model.defer="additionalImages" type="file" multiple>
#error('images.*') {{ $message }} #enderror
</div>
</div>
</div>
</div>
Here are the scripts for expanding of the both DOM elements:
const extendedCheckbox = document.querySelector('#extended-description-checkbox');
const extendedDiv = document.querySelector('#extended-description-checkbox-div');
extendedCheckbox.addEventListener('change', function() {
if(extendedCheckbox.checked) {
extendedDiv.classList.remove('d-none');
} else {
extendedDiv.classList.add('d-none');
}
});
const defaultImagesCheckbox = document.querySelector('#use-default-images');
const defaultImagesDiv = document.querySelector('#use-default-images-div');
defaultImagesCheckbox.addEventListener('change', function() {
if(defaultImagesCheckbox.checked) {
defaultImagesDiv.classList.remove('d-none');
} else {
defaultImagesDiv.classList.add('d-none');
}
});
Getting a HTML select value and and input value from form submit ,
in here i get only undefined for the select value, and gives error on
Cannot read property 'target' of undefined
at RightcomponentComponent.push../src/app/rightcomponent/rightcomponent.component.ts.RightcomponentComponent.formSubmit
rightcomponent.component.html
<!--Form start-->
<form >
<div class="row">
<div class="form-group row">
<div style="margin-left: 60px;margin-right:50px ">
<select class="form-control" (ngModelChange)="onSelected($event)" id="sel1">
<option *ngFor="let stock_name of stock_names" [value]="stock_name.stockName">{{stock_name.stockName}}</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="container set_buttons_div" >
<div class="form-group row">
<div class="col-xs-2">
<input class="form-control" id="ex1" type="text">
<br>
</div>
</div>
</div>
</div>
<br>
<div class="row">
<a class="btn btn-sq-lg btn-success b_s_buttons" (click)="formSubmit(e)">
<i class="glyphicon glyphicon-thumbs-up fa-5x"></i><br/>
Buy
</a>
</div>
<br>
</form>
rightcomponent.component.ts
formSubmit(e){
var stock = this.onSelected(e);
console.log(stock);
var quantity = e.target.elements[0].value;
console.log(quantity);
}
onSelected(e){
var stock_company_name = e;
return stock_company_name;
}
I would have created component in this way, i dont know how to create a plunker / fiddler, but two way binding will work for you now. I created this way. :D
<!--Form start-->
<form #myForm="ngForm" novalidate>
<div class="row">
<div class="form-group row">
<div style="margin-left: 60px;margin-right:50px ">
<select class="form-control" (change)="onSelected($event)" id="sel1" name="stock" [(ngModel)]="Model.stockname">
<option *ngFor="let stock_name of stock_names" [value]="stock_name.stockName">{{stock_name.stockName}}</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="container set_buttons_div" >
<div class="form-group row">
<div class="col-xs-2">
<input class="form-control" id="ex1" type="text" name="companyName" [(ngModel)]="Model.companyname">
<br>
</div>
</div>
</div>
</div>
<br>
<div class="row">
<a class="btn btn-sq-lg btn-success b_s_buttons" (click)="formSubmit()">
<i class="glyphicon glyphicon-thumbs-up fa-5x"></i><br/>
Buy
</a>
</div>
<br>
</form>
rightcomponent.component.ts
// create an Object model with form fields as key
Model = {
stockname: '',
companyname: ''
}
formSubmit(){
console.log(this.Model);
}
I'm trying to do the following : When you click on "Add Package" its pushes to an array a package where I can specify e.g. Package one, but within that I want to push multiple items (products) "Add Item". The problem is when I create a new package it works, but the items in each package is the same so when I add more to either dynamic package the items within is the same. I assume that's because the array is the same each time, how to I track that by index?
HTML:
<div class="col-12 order-box" ng-repeat="orderpackage in orderproductspackages track by $index">
<div class="col-12">
<label for="name_{{$index}}">Package Name</label>
<input type="text" ng-model="orderpackage.orderpackagename" name="name_{{$index}}" required>
</div>
<div class="col-12" ng-repeat="ordercontent in orderproductscontents track by $index">
<div class="col-2">
<label for="name_{{$index}}">Product</label>
<select ng-model="ordercontent.ordercontentname" name="name_{{$index}}" ng-change="onProductChange(ordercontent.ordercontentname,$index)">
<option ng-repeat="product in productResponse | orderBy:'productname'" value="{{product.productname}}">{{product.productname}}</option>
</select>
</div>
<div class="col-2">
<label for="name_{{$index}}">Quantity</label>
<input type="text" ng-model="ordercontent.ordercontentquantity" name="name_{{$index}}" ng-keyup="onProductChange(ordercontent.ordercontentname,$index)" required>
</div>
<div class="col-2">
<label for="name_{{$index}}">Price</label>
<input type="text" ng-model="ordercontent.ordercontentprice" name="name_{{$index}}" ng-change="onPriceChange(ordercontent.ordercontentname,$index)" disabled required>
</div>
<div class="col-2">
<label for="name_{{$index}}">Per {{ordercontent.ordercontentmeasurement}}</label>
<input type="text" ng-model="ordercontent.ordercontentpriceper" name="name_{{$index}}" disabled required>
</div>
<div class="col-2">
<label for="name_{{$index}}">Total</label>
<input type="text" ng-model="ordercontent.ordercontenttotal" name="name_{{$index}}" required disabled>
</div>
<div class="col-2">
<label for="name_{{$index}}">Options</label>
<a class="button critical small" ng-click="removeOrderContent($index)"><span class="fa fa-minus"></span> Remove</a>
</div>
</div>
<div class="col-12 m20-top p15 text-center add-api" ng-click="addOrderContent()">
<span class="fa fa-plus"></span> Add Item</a>
</div>
</div>
<div class="col-12 m20-top p15 text-center add-api" ng-click="addOrderPackage()">
<span class="fa fa-plus"></span> Add Package</a>
</div>
CODE SNIPPETS :
_this.addOrderPackage = function() {
_this.orderproductspackages.push({ ordernumber:_this.order.ordernumber });
}
_this.addOrderContent = function() {
_this.orderproductscontents.push({
ordercontentname:'',
ordercontentquantity:'1',
ordercontentprice:'',
ordercontentpriceper:'',
ordercontenttotal:''
});
}
Of course, all items in your packages are the same, because you use the same content array inside packages: ng-repeat="ordercontent in orderproductscontents". If I understand you right, you need this array orderproductscontents to be distinctive in each package. To do this store this array in package object, like this:
_this.addOrderPackage = function() {
_this.orderproductspackages.push({
ordernumber: _this.order.ordernumber,
contents: []
});
}
and then just ng-repeat="ordercontent in orderpackage. contents"
Below is the attached picture of the form constructor. As you can see it has {{service.name}} in it instead o fthe name itself.
I have a form inside that I have two ng-repeats with custom filters on it and inside that I have an input field. I am trying to have a unique name for my input field by adding an index or by using a field from the html response. Regardless of that, when I have name="{{customitem.name}}" or name="{{$index}}" the form generates a constructor with {{customitem}} or {{$index}} instead of the value it self. Also this form turned on and off using ng-if.
<form name="selectServiceForm">
<div data-ng-show="showAddServices">
<section class="content-header">
<div class="row">
<div class="col-lg-5 col-sm-5">
<h1>
Services
<small>Add or Modify Services</small>
</h1>
</div>
<div class="col-lg-7 col-sm-7 text-right btn-container">
<button type="button" class="btn btn-primary btn-sm" data-ng-disabled="selectServiceForm.$invalid" data-ng-click="selectServiceForm.$valid && save(true)">
<i class=" fa fa-save"></i>
<span class="indent-xs">Save</span>
</button>
<button type="button" class="btn btn-primary btn-sm" data-ng-click="backToAddServices()">
<i class=" fa fa-arrow-circle-left"></i>
<span class="indent-xs">BACK</span>
</button>
</div>
</div>
</section>
<section class="content group-container">
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="">Industry<sup style="color: red">*</sup></label>
<select class="form-control" id="select1" name="" data-ng-model="selectedIndustry" data-ng-change="onChangeIndustry(selectedIndustry)"
data-ng-options="industry.CategoryName for industry in Industry">
<option value="">Select Industry</option>
</select>
</div>
<div data-ng-show="isSecondLevelCategory">
<div class="form-group">
<label for="">
Category<sup style="color: red">*</sup>
</label>
<select class="form-control" id="selectCategory" name="" data-ng-model="selectedService" data-ng-change="showServices(selectedService)"
data-ng-options="service.CategoryName for service in ServiceTypes">
<option value="">Select Category</option>
</select>
</div>
</div>
</div>
</div>
<hr />
<div class="selectServ">
<div class="pad20B p-relative">
<div data-ng-repeat="item in innerCategoryList | orderBy: 'SortOrder'" class="">
<div class="form-row pad10B mrg0A pad0B mrg5T">
<label>
<input class="wauto float-left mrg5R" type="checkbox" data-ng-model="item.checked" data-ng-checked="item.checked" data-ng-click="categorySelected(item)" />
<strong class="float-left">{{item.CategoryName}}</strong>
</label>
</div>
<div data-ng-show="item.checked" style="padding-left: 25px" class="pad15L">
<div data-ng-repeat="service in serviceList | servicelistfilter:item.ShortName | orderBy: 'SortOrder' ">
<div class="form-row mrg0A pad10B">
<div class="row">
<div class="col-lg-8 col-md-6 col-sm-6">
<div class="service-amount-label pad5L mrg5T">
<label>
<input class="wauto float-left mrg5R" type="checkbox" data-ng-model="service.checked"
data-ng-checked="service.checked" data-ng-click="selectService(service)" />
<strong class="float-left">{{service.Name}}</strong>
</label>
</div>
</div>
<!--TAP-4394
<div class="col-lg-4 col-md-6 col-sm-6">
<div class="service-amount float-right" data-ng-show="service.checked && !service.hideRange">
<input type="text" placeholder="$50" data-ng-model="featureDetail.minAmount" name="minAmount" data-ng-required="featureDetail.isSelected">
<span class="mrg5R mrg5T">$</span>
<decimal-text-box class="mrg5R" max-value="service.MaxAmount" min-value="'invalid'" min-max-error="service.minMaxError" input-placeholder="'$min'" input-class="'selectService'" input-value="service.MinAmount"></decimal-text-box>
<span class="dash mrg5R mrg5T">–</span>
<span class=" mrg5R mrg5T">$</span>
<decimal-text-box class=" " max-value="'invalid'" min-value='service.MinAmount' min-max-error="service.minMaxError" input-placeholder="'$max'" input-class="'selectService'" input-value="service.MaxAmount"></decimal-text-box>
<div data-ng-show="service.checked && !service.hideRange" class="new-error-style">
<span data-ng-show="service.minMaxError" class="font-white">min should not be greater than max</span>
</div>
</div>
</div>-->
<!-- <div class="col-lg-5">
<div data-ng-show="service.checked && !service.hideRange">
<span data-ng-show="service.minMaxError" class="font-red">min should not be greater than max</span>
</div>
</div>-->
</div>
</div>
<div class="form-row pad10B mrg0A service-custom-text"
data-ng-repeat="customitem in customServiceList | listfilter:service.ShortName "
data-ng-show="service.checked" data-ng-model="customServiceList" ng-init="">
<!--data-ng-click="showEditCustomService(customSvc.CustomText,customSvc.Amount)"-->
<div class="col-md-5 col-sm-5">
<span class="pad0L pointer" data-ng-click="removeCustomService(service,customitem.Id)"><i class="fa fa-fw fa-minus-circle"></i></span>
<input type="text" data-ng-model="customitem.CustomText" placeholder="Custom Service" class="selectService w40 mrg5Bxs" />
<span class="mrg20L">
<decimal-text-box min-value="'invalid'" max-value="'invalid'" min-max-error="'invalid'" input-placeholder="'Amount'" input-class="'selectService w40 '" input-value="customitem.Amount"></decimal-text-box>
</span>
<textarea class="selectDescription" cols='60' rows='8' data-ng-model="customitem.CustomDescription" placeholder="Description (Optional)"></textarea>
</div>
<div ng-hide="businessModel.name == 'Book Now'">
<div class="center-bor" style="height: 231px;"></div>
<div class="float-left col-md-5 col-sm-5 activate-bundle-container gray">
<div class="activate-bundle-button" ng-hide="customitem.CustomServiceBundle && !customitem.isDeleteBundle" ng-click="activateBundle(customitem)">Activate Bundle Rates</div>
<div ng-show="customitem.CustomServiceBundle && !customitem.isDeleteBundle">
<div class="cancel-bundle-button" ng-click="cancelBundle(customitem)">Cancel</div>
<input name="customBundleQuantity" type="number" class="selectService mrg70T" placeholder="# of Bundles" ng-model="customitem.CustomServiceBundle.BundleQuantity" ng-change="change(customitem.CustomServiceBundle.BundleQuantity, customitem)" />
<div class="font-red" ng-if="selectServiceForm.customBundleQuantity.$error.pattern">Quantiy must be more than 1.</div>
<input type="number" step="0.5" name="{{service.name}}"
class="selectService mrg20T" placeholder="Price (per Unit)"
ng-model="customitem.CustomServiceBundle.BundlePrice"
ng-change="change(customitem.CustomServiceBundle.BundlePrice, customitem)" compare-price price-to-compare="customitem.Amount" />
<div class="font-red" ng-if="selectServiceForm.customBundlePrice.$error.priceValid">Bundle Price must be less than Original Price..</div>
<!--<decimal-text-box min-value="'2'" max-value="'invalid'" min-max-error="'invalid'" input-placeholder="'# of Bundles'" input-class="'selectService mrg70T'" input-value="customitem.CustomServiceBundle.BundleQuantity" change="Change"></decimal-text-box>-->
<!--<decimal-text-box min-value="'1'" max-value="'invalid'" min-max-error="'invalid'" input-placeholder="'Price'" input-class="'selectService mrg20T'" input-value="customitem.CustomServiceBundle.BundlePrice"></decimal-text-box>-->
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-9">
<div class="custom-service" data-ng-show="service.checked">
<div class="pad10B pad0T pad0L">
<i class="fa fa-fw fa-plus-circle"></i>Add a Service
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--End of selectServiceForm-->
</div>
</section>
</div>
</form>
My project is using Angular v1.3.15, I know its an old version but it will be too much to jump forward from this version.
I would like to ask about posting problem, actually I have a form below, in that form, I have using ng-submit and ng-click for the function but it didn't work, can anyone help me?
<form method="post" class="sky-form" name="form">
<div class="row">
<div class="col col-12"><img src="public/images/icon_namapasien.png" alt=""/> Nama Pasien</div>
</div>
<div class="row">
<div class="col col-10">
<div ng-repeat="profile in profil">
<label class="input disabled">
<input type="text" ng-model="profile.name">
</label>
</div>
</div>
<div class="col col-2">
<a class="btnstatus"> </a>
</div>
</div><!-- /row -->
<div class="row">
<div class="col col-12"><img src="public/images/icon_tgl.png" alt=""/> Tanggal Lahir</div>
</div>
<div class="row">
<div class="col col-3">
<label class="select">
<div ng-repeat="profile in profil">
<select name="gender" ng-model="profile.birth_date">
<option ng-repeat="n in range(01,31)" value="{{n}}">{{n}}</option>
</select>
<i></i>
</div>
</label>
</div>
<div class="col col-4">
<label class="select">
<div ng-repeat="profile in profil">
<select name="gender" ng-model="profile.birth_month">
<option value="01">Januari</option>
<option value="02">Februari</option>
<option value="03">Maret</option>
<option value="04">April</option>
<option value="05">Mei</option>
<option value="06">Juni</option>
<option value="07">Juli</option>
<option value="08">Agustus</option>
<option value="09">September</option>
<option value="10">Oktober</option>
<option value="11">November</option>
<option value="12">Desember</option>
</select>
<i></i>
</div>
</label>
</div>
<div class="col col-3">
<label class="select">
<div ng-repeat="profile in profil">
<select name="gender" ng-model="profile.birth_year">
<option ng-repeat="n in range(1910,2016)" value="{{n}}">{{n}}</option>
</select>
<i></i>
</div>
</label>
</div>
<div class="col col-2">
<a class="btnstatus"> </a>
</div>
</div><!-- /row -->
<div class="row">
<div class="col col-12"><img src="public/images/icon_gender.png" alt=""/> Jenis Kelamin</div>
</div>
<div class="row">
<div class="col col-10">
<div class="select">
<label class="select">
<div ng-repeat="profile in profil">
<select name="gender" ng-model="profile.gender">
<option value="1">Pria</option>
<option value="0">Wanita</option>
</select>
<i></i>
</div>
</label>
</div>
</div>
<div class="col col-2">
<a class="btnstatus"> </a>
</div>
</div><!-- /row -->
<div class="row">
<div class="col col-12"><img src="public/images/icon_alamat.png" alt=""/> Alamat</div>
</div>
<div class="row">
<div class="col col-10">
<div ng-repeat="profile in profil">
<label class="input disabled">
<input type="text" ng-model="profile.address"/>
<input type="hidden" name="name" value="0" ng-model="kodekota">
</label>
</div>
</div>
<div class="col col-2">
<a class="btnstatus"> </a>
</div>
</div><!-- /row -->
<div class="row">
<div class="col col-12"><img src="public/images/icon_telp.png" alt=""/> Nomor Telepon / Hp</div>
</div>
<div class="row">
<div class="col col-10">
<div ng-repeat="profile in profil">
<label class="input disabled">
<input type="text" value="" ng-model="profile.phone"/>
</label>
</div>
</div>
<div class="col col-2">
<a class="btnstatus"> </a>
</div>
</div><!-- /row -->
<p> </p>
<button class="btn-yellow" type="submit" name="submit" ng-click="postProfil()">Simpan Perubahan</button>
</form>
Here is the angularjs code
$scope.getProfil = function(){
$http.get('/getUrl').success(function(data){
$scope.profil = data;
})
}
$scope.getProfil();
$scope.profile = {};
$scope.postProfil = function(){
$http.post('/postUrl').success(function(data){
$scope.getProfil();
}).error(function(data){
console.log(data);
})
}
$scope.range = function(min, max, step){
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step) input.push(i);
return input;
};
one thing for sure, I know that http.post using only link is a bad idea, but before I do that, I have debug it using alert javascript function, for example I want to get the data from profile.name so I alert it (profile.name) inside the postProfil function but it returns undefined.
here is the key that should be inputed in the http.post
address
phone
birth
gender
name
I would like to use the http array structure such as
$http.post({
method: 'POST',
url: '/postUrl',
data: {
//data is here
}
})
what do you guys think? Thanks
EDIT:
Maybe I will change my questions, do you know the code for updating data from previous data in an apiUrl using AngularJS? So my problem is that getProfil and postProfil is in the same key and value (but I think some of the keys are different).
Just use the ng-model $scope.profile:
$scope.postProfil = function(){
$http.post('/postUrl', $scope.profile).success(function(data){
$scope.getProfil();
}).error(function(data){
console.log(data);
})
}
$http.post('api/create/something', yourData)
should do the trick for your problem.
$http.post accepts (url, data?, options?)
$http on the other hand accepts (options) directly. You can use it like
$http({
url: 'api/create/something',
data: yourData,
method: 'POST'
}).then(....)
This code works the same with the code above.
Regarding the inaccurate data binding. It might be case sensitivity issues, or serialization issues coming from your rest api configuration. Sometimes PascalCased variable does not bind to camelCased variables as it is. Some configurations are needed to be done.