I have problem with ng-repeat and [$index]. My problem is that I would like values from all inputes (look on fiddle and click "+") store in one array and next save in database. The problem is at the very beginning that I can't insert inputs values in one array (first array isn't insert into array). I try use:
ng-repeat="input in inputs track by $index"
fiddle:
https://jsfiddle.net/j6uwhb6v/4/
It's not working because the first input is outside of the ng-repeat so it doesn't have an $index... Here's a simple fix:
HTML:
<div ng-app="productController" ng-controller="productCtrl" class="row-fluid">
<div class="col-md-12">
<div class="form-group">
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
<div class="input-group-addon">
<i class="fa fa-pencil"></i>
</div>
<input ng-disabled="product.disabled" type="text" ng-model="description[0]" name="description" class="form-control" placeholder="Description..." required>
<div class="input-group-addon">
<a ng-click="addfield()" class="add-field">
<i class="fa fa-plus"></i>
</a>
</div>
</div>
<div ng-repeat="item in inputs track by $index">
<div class="input-group mb-2 mr-sm-2 mb-sm-0 repeat-input">
<div class="input-group-addon">
<i class="fa fa-pencil"></i>
</div>
<input ng-disabled="product.disabled" type="text" name="description" ng-model="description[$index+1]" class="form-control" placeholder="Description..." required>
</div>
</div>
</div>
</div>
{{description}}
</div>
JavaScript:
$scope.inputs = [];
$scope.addfield = function(){
$scope.inputs.push({})
}
$scope.description = [];
Working Code: JSFiddle
Related
How can i load the JSON array saved in the database to the edit form input field ?
Here's how my create form looks like
Here's the form Code
<div class="card">
<h5 class="card-header">
Manage Extras
</h5>
<div class="card-body">
<div class="optionBox">
<div class="block main">
<div class="form-row pb-2">
<div class="col">
<input type="text" class="form-control" name="extras_name[]" value="" placeholder="Name">
</div>
<div class="col">
<input type="text" class="form-control" name="extras_price[]" placeholder="Price">
</div>
<div class="col">
<button type="button" class="remove btn btn-danger"><i class="fas fa-trash-alt"></i></button>
</div>
</div>
<div class="block mt-2 ">
<button type="button" class="add btn btn-success">Add Extras</i></button>
</div>
</div>
</div>
</div>
</div>
Here's the Script to Add Extra input field and delete button
<script>
$('.add').click(function() {
$('.block:last').before('<div class="form-row pb-2"><div class="col"><input type="text" class="form-control" name="extras_name[]" placeholder="Name"></div><div class="col"><input type="text" class="form-control" name="extras_price[]" placeholder="Price"></div><div class="col"><button type="button" class="remove btn btn-danger"><i class="fas fa-trash-alt"></i></button></div></div>');
});
$('.optionBox').on('click','.remove',function() {
$(this).parent().parent().remove();
});
</script>
Here's how it saves in the database
Here's the edit function in the Controller
public function edit(CustomProduct $customProduct)
{
$data = [
'customProduct'=>$customProduct,
];
return view('manage.custom-products.edit')->with($data);
}
I was able to load the data into the form using a foreach as below
<div class="row">
<div class="col">
<strong>Names</strong>
#foreach ($customProduct['extras_name'] as $item)
<li>{{ $item }}</li>
#endforeach
</div>
<div class="col">
<strong>Prices</strong>
#foreach ($customProduct['extras_price'] as $item)
<li>{{ $item }}</li>
#endforeach
</div>
</div>
And here's how it was looking like
I just want to load the json data into the input fields on edit and should be able to remove a pacific input by clicking the delete icon,
How can i do make this happen, Please help me out
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"
I just take a simple array and there is add more button in which i just push one more object to that array.
The array is ng-repeat which renders all the fields. My code are given below.
<div ng-init="core.iv=[{email:'',name:''}];">
<div ng-repeat="n in core.iv track by $index">
<div class="col-sm-6 pad0">
<div class="form-group">
<input type="email" class="form-control mIn" ng-model="n.email" placeholder="Email id" />
<span class="bar"></span>
</div>
</div>
<div class="col-sm-6 pad0">
<div class="form-group">
<input type="text" class="form-control mIn" ng-model="n.name" placeholder="Name" />
<span class="bar"></span>
</div>
</div>
</div>
<div class="col-xs-12 pad0 text-right">
<button class="btn btn-t-primary btn-sm" ng- click="core.iv.push({email:'',name:''});">add more</button>
</div>
</div>
I have two tables: site and ip.
site: site_id,name
ip: ip_id,site_id,ip_adress
I have to show a list of ip_adress of a site.
html
<div class="form-group" style="margin-bottom: 0px;">
<label class="col-sm-6 control-label">
<button style="margin-bottom:5px;" ng-click="addIp($index)">
<span class="glyphicon glyphicon-plus"></span>
</button>
</label>
<div class="col-sm-6">
<ul style="list-style-type: none">
<li ng-repeat="ip in site.ips track by $index">
<div class="input-group" >
<input type="text" class="form-control input-sm" name="ip_adress" style="display: inline;" ng-model="ip.ip_adress" required />
<div class="input-group-addon">
<i class="glyphicon glyphicon-remove-circle" ng-click="removeIp(site, ip, $index)"></i>
</div>
</div>
</li>
</ul>
</div>
</div>
JavaScript
$scope.addIp = function(index){
$scope.sites[index].ips[index].ip_adress.push("");
}
It throws this error:
$scope.sites[index].ips[index].ip_adress.push is not a function
Ips is a Set of Ip object, and ip_adress is a String.
How can i resolve this ?
You should push to your array like: $scope.sites[index].ips.push(<here_goes_your_object_with_ip_string>);
if ips is an array
Use
$scope.addIp = function(index){
$scope.sites[index][ips[index]]['ip_adress'].push("");
}
When I click duplicate it duplicates the row fine, but when I click it again I get another 2, then 4 etc, how can I stop this from happening and just clone one div on each click...
Jquery:
<script>
$(".clonable-button").bind('click', function(e){
e.preventDefault();
var section = $(this).data('clone');
var parent = $('[data-id="' + section + '"]');
var sequence = 0;
if(!$(this).data('last')) {
sequence = $(parent).find('.cloneable').last().data('id');
} else {
sequence = $(this).data('last');
}
$(this).data('last', ++sequence);
$(parent).append(parent.html());
});
$('.clone-wrapper').on('click', '.clone-remove',function(){
var parent = $(this).parents('.cloneable');
$(parent).remove();
});
</script>
html:
<div class="clone-wrapper" data-id="skill">
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>
</div>
<div class="white-space-20"></div>
<div class="row text-right">
<div class="col-md-12">
<div class="btn btn-default btn-sm clonable-button" id="skill">
<i class="fa fa-plus"></i> Add Skill </div>
</div>
</div>
I just want the following code duplicated once on each click
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>
The problem is in this line:
var parent = $('[data-id="' + section + '"]');
Each time you append new block with the same data-id number of elements that match this selector increases. So to avoid this you have make the selector more specific. Like:
var parent = $('[data-id="' + section + '"]:last');
Also there is a jQuery method to clone the element. So change your line from:
$(parent).append(parent.html());
to:
parent.append(parent.clone());
That will fix the issue.
You are binding the click event multiple times somehow, You should either use a delegated event handler or use the off method like below.
$(".clonable-button").off('click').on('click', function(e){