Array splice removes the wrong element in AngularJS - javascript

I read all the other questions by others and answers, but still can't figure it out..
HTML:
<table class="table table-striped" ng-show="coffees.length>0">
<thead>
<tr>
<th>Drink</th>
<th>Price</th>
<th>Number per week</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="c in coffees">
<td>{{c.type}}</td>
<td>{{c.price | currency:"£"}}</td>
<td>{{c.numberpw}}</td>
<td><a href ng-click="removeCoffee($index)">X</a></td>
</tr>
</tbody>
</table>
app.js:
var app = angular.module("calculator",[]);
app.controller('pageController',function($scope){
$scope.coffees=[];
});
app.controller('coffeeController',function($scope){
$scope.addCoffee=function(coffee){
$scope.coffees.push(coffee);
$scope.coffee={};
}
$scope.removeCoffee=function(el){
$scope.coffees.splice($scope.coffees[el],1);
}
});
coffeeController is nested within pageController, so I can access $scope.coffees inside the coffeeController. And addCoffee function accepts an object that looks like this:
<select name="CoffeeType" ng-model="coffee.type" ng-options="type for type in
['Espresso','Latte']" class="form-control" required>
<option value="">Please select</option>
</select>
<input type="text" placeholder="£00.00" ng-pattern="/^0|[1-9][0-9]*$/" ng-model="coffee.price" name="CoffeePrice" class="form-control" required />
<select name="NumberPerWeek" class="form-control" ng-model="coffee.numberpw" ng-options="n for n in [1,2,3,4,5]" required>
<option value="">Please select</option>
</select>
<input type="submit" class="btn btn-primary pull-left" value="Add Drink" ng-click="addCoffee(coffee)" />
It adds objects perfectly but removes the wrong object every single time..

splice expects start/count integers. $scope.coffees[el] is an object but you're passing in the $index to the method. Update your remove method as follows:
$scope.removeCoffee=function(el){
$scope.coffees.splice(el,1);
}

Related

Clone Table Row with Bootstrap Selectpicker with Filter

I have a Laravel application using Bootstrap. I have a form (shown below) where I want to add more rows (via JS) by clicking the Add Row button. I have a Select/Selectpicker ("Opponent") that I want to be able to type and live filter to find the right option.
The Selectpicker works fine in row 1. However, when I clone the row, the Selectpicker does 2 weird things: (1) The new Select loses all its options, so there is nothing to choose from, and (2) It retains the selected value of the cloned element instead of clearing like the rest of the inputs.
Note: In the HTML code below, you'll see a commented-out Select for a static Select that does NOT use filtering. This works perfectly fine; clones successfully, clears the value, and has all the options in the drop-down. Only the Selectpicker has issues cloning.
JavaScript function:
<script>
function cloneRow() {
var table = document.getElementById("gameBody"); // find table to append to
var count = table.rows.length + 1;
var gameStr = "game";
var oppString = "opponent";
var row = document.getElementById("game1"); // find row to copy
var clone = row.cloneNode(true); // copy children too
clone.id = gameStr + count; // change id of new row
table.appendChild(clone); // add new row to end of table
// Clear fields in new row
var newRow = document.getElementById(gameStr.concat(count));
inputs = newRow.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
if(inputs[index].type == "text" || inputs[index].type == "date")
inputs[index].value = '';
}
}
</script>
CSS/JS includes:
<!-- Inside the Head tag -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle#3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.18/dist/css/bootstrap-select.min.css">
<!-- At the bottom of the Body -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle#3.6.1/js/bootstrap4-toggle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.18/dist/js/bootstrap-select.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.18/dist/js/i18n/defaults-*.min.js"></script>
HTML table:
<table class="table table-sm table-striped" id="game_table">
<thead>
<tr>
<th>Date*</th>
<th>Opponent</th>
<th>Name Override</th>
<th>Location*</th>
<th>Site Name</th>
<th>Game Type*</th>
</tr>
</thead>
<tbody id="gameBody">
<tr class="dummy-row" id='game1'>
<!-- Date -->
<td>
<input type="date" name='gameDate[]' id="gameDate1" class="form-control" required/>
</td>
<!-- Opponent -->
<td>
<select name='opponent[]' id="opponent1" class="selectpicker form-control" data-live-search="true" title="Select an opponent" data-hide-disabled="true">
<!--<select name='opponent[]' class="form-control"title="Select an opponent">-->
<option value="">Select a Team</option>
#foreach($allschools as $school)
<option value="{{ $school->id }}">{{ isset($school->nickname) ? $school->nickname : $school->name }}
#if($school->name != $school->city)
({{ $school->city }})
#endif
</option>
#endforeach
</select>
</td>
<!-- Opponent Override -->
<td>
<input type="text" name='opponentOverride[]' id="opponentOverride1" class="form-control"/>
</td>
<!-- Location -->
<td>
<select name='location[]' id="location1" class="form-control" required>
<option value="HOME">Home</option>
<option value="AWAY">Away</option>
</select>
</td>
<!-- Site Name -->
<td>
<input type="text" name='site[]' id="site1" class="form-control"/>
</td>
<!-- Game Type -->
<td>
<select name='gameType[]' id="gameType1" class="form-control" required>
<option value="REGULAR SEASON">Reg. Season</option>
<option value="POSTSEASON">Postseason</option>
<option value="SCRIMMAGE">Scrimmage</option>
</select>
</td>
</tr>
</tbody>
</table>
<table class="table tabls-sm table-borderless">
<tr>
<td class="text-left" width="50%">
<a id='add_row' onclick="cloneRow()" class="btn btn-sm btn-warning">Add Row</a>
</td>
<td class="text-right" width="50%">
<a id='delete_row' onclick="deleteLastRow()" class="btn btn-sm btn-danger">Delete Last Row</a>
</td>
</tr>
</table>
Thank you for your help!
I figured it out using this as a blueprint:
Add Row dynamically with SelectPicker
At a high level, this is what I had to do:
Remove the "selectpicker" class from the Selectpicker ("Opponent")
In the add_row() function, initialize the Selectpicker class
Dynamically append the resulting HTML as the new row
I guess it comes down to how Bootstrap treats the Selectpicker class. I don't fully understand it, but the best I can explain is... When you use <select class="selectpicker"... Bootstrap changes the object so that it is no longer a pure Select with options belonging to it. Rather, it wraps it in other, dynamically-created layers on-the-fly (div=>select=>button=>div=>options, etc). This causes issues when cloning because the object you're cloning (the Select) no longer contains those Options, as they are lost somewhere else in the hierarchy (for lack of better terms). I remember reading that in another post, but didn't really get it until now (kinda).
Here is my functioning code:
HTML Table:
<table class="table table-sm table-striped" id="gameTable">
<thead>
<tr>
<th>Date*</th>
<th>Opponent</th>
<th>Name Override</th>
<th>Location*</th>
<th>Site Name</th>
<th>Game Type*</th>
</tr>
</thead>
<tbody id="gameBody">
<tr id="gameRow">
<!-- Date -->
<td>
<input type="date" name='gameDate[]' id="gameDate1" class="form-control" required/>
</td>
<!-- Opponent -->
<td>
<select name='opponent[]' id="opponent1" class="form-control" data-live-search="true" title="Select an opponent" data-hide-disabled="true">
<!--<select name='opponent[]' class="form-control" title="Select an opponent">-->
<option value="">Select a Team</option>
#foreach($allschools as $school)
<option value="{{ $school->id }}">{{ isset($school->nickname) ? $school->nickname : $school->name }}
#if($school->name != $school->city)
({{ $school->city }})
#endif
</option>
#endforeach
</select>
</td>
<!-- Opponent Override -->
<td>
<input type="text" name='opponentOverride[]' id="opponentOverride1" class="form-control"/>
</td>
<!-- Location -->
<td>
<select name='location[]' id="location1" class="form-control" required>
<option value="HOME">Home</option>
<option value="AWAY">Away</option>
<!--<option value="NEUTRAL">Neutral</option>-->
</select>
</td>
<!-- Site Name -->
<td>
<input type="text" name='site[]' id="site1" class="form-control"/>
</td>
<!-- Game Type -->
<td>
<select name='gameType[]' id="gameType1" class="form-control" required>
<option value="REGULAR SEASON">Reg. Season</option>
<option value="POSTSEASON">Postseason</option>
<option value="SCRIMMAGE">Scrimmage</option>
</select>
</td>
</tr>
</tbody>
</table>
<table class="table tabls-sm table-borderless">
<tr>
<td class="text-left" width="30%">
<a id='add_row' onclick="add_row()" class="btn btn-sm btn-warning">Add Row</a>
</td>
<td class="text-center" width="40%">
<button type="submit" class="btn btn-primary">Create Games</button>
</td>
<td class="text-right" width="30%">
<a id='delete_row' onclick="deleteLastRow()" class="btn btn-sm btn-danger">Delete Last Row</a>
</td>
</tr>
</table>
Function (bottom of Body):
<script>
var cloned = $("#gameTable tbody tr:first").clone() //keep clone for later use..
$("select[name*=opponent]").selectpicker() //intialize your slectpicker
function add_row() {
$(cloned).find("input").val("") //empty any input..
$("<tr>" + $(cloned).html() + "</tr>").appendTo($("#gameTable tbody")) //append to your tbody..
$("#gameTable tbody tr:last select").selectpicker() //intialize newly added selct...
}
</script>

Unable to assign the document.getElementById value to ng-model in ng- repeat

<select class="form-control" name="suppliername" ng-model="suppliername" data-ng-change="supplier_data1(suppliername)" required>
<option value="">Select</option>
<option ng-repeat="custids in supp_nmArray" value="{{custids.Supplier_Id}}" >{{custids.name}}
</option>
</select>
<table class="table table-striped" >
<thead>
<tr>
<th>Product Name</th>
<th>Qty</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="p in products">
<td>{{ p.Product_Name }}
<input type="hidden" class="form-control" name="sname" ng-model="sname" required>
</td>
<td>
<input type="text" class="form-control" name="finalqty" ng-model="p.finalqty" ng-change="change_qty(p.productrate,p.finalqty)"/>
</td>
<td>
<span ng-init="GetProdcutDetails(p.Product_Name,sname,'productrate'+$index)"></span>
<input type="text" class="form-control" name="purches_rate" ng-model="p.purches_rate" id="productrate{{$index}}">
</td>
</tr>
</tbody>
</table>
var app=angular.module("myapp",['ui.bootstrap']);
app.controller("ctrl",function($scope,$http)
{
$scope.supplier_data1 = function(suppliername)
{
$scope.sname=suppliername;
}
$scope.GetProdcutDetails = function(Product_Name,sname,productrate)
{
$http.post("get_prodcut_rate.php",{'Product_Name':Product_Name,'suppliername':$scope.sname})
.success(function(data)
{
var x = document.getElementById(productrate);
document.getElementById(productrate).value = data[0].purches_rate;
});
}
});
I'am getting product rate value in ng repeat by use of javascript(getElementById).
How to assign the document.getElementById to ng-model in ng-repeat ?
I need to pass the value in another function. kinldy help me
Thanks you in Advance.

How to add more row after selecting plus button inside a table using Angular.js

I need one help.I need to generate a row dynamically after click on plus button using angular.js and that new created row should contain the id and model dynamically.I am explaining my code below.
<table class="table table-bordered table-striped table-hover" id="dataTable" >
<thead>
<tr>
<th>Day</th>
<th>Category</th>
<th>Sub Subcategory</th>
<th>Comments Or special promotion</th>
<th>Add More</th>
</tr>
</thead>
<tbody id="detailsstockid">
<tr ng-repeat="d in days">
<td>{{d.day_name}}</td>
<td> <select class="form-control" name="catagory[$index]" id="{{'catagory'+$index}}" ng-model="answers['catagory'+$index]" ng-options="cat.name for cat in listOfCatagory track by cat.value " ng-change="removeBorder('catagory',$index,answers['catagory'+$index].value,answers['cata'+$index].value,answers['catagory'+$index].name,answers['cata'+$index].name);" >
<option value="">Select Category</option>
</select>
<select class="form-control" name="cata[$index]" id="{{'cata'+$index}}" ng-model="answers['cata'+$index]" ng-options="cat.name for cat in listOfCatagory track by cat.value " ng-change="setCatagory($index,answers['catagory'+$index].value,answers['cata'+$index].value,answers['catagory'+$index].name,answers['cata'+$index].name);">
<option value="">Select Category</option>
</select>
</td>
<td>
<select class="form-control" name="subcatagory[$index]" id="{{'subcatagory'+$index}}" ng-model="answers['subcatagory'+$index]" ng-options="sub.name for sub in listOfSubCatagory[$index] track by sub.value " ng-change="setSubCatagory($index,subcatagory[$index].value);" >
<option value="">Select Subcategory</option>
</select>
<select class="form-control" name="subcata[$index]" id="{{'subcata'+$index}}" ng-model="answers['subcata'+$index]" ng-options="sub.name for sub in listOfSubCatagory1[$index] track by sub.value ">
<option value="">Select Subcategory</option>
</select>
</td>
<td><input type="text" name="comment[$index]" id="{{'comment'+$index}}" class="form-control oditek-form" placeholder="Add Comment" ng-model="answers['comment'+$index]" ng-keyup="comment($index,comment[$index]);">
<input type="text" name="comm[$index]" id="{{'comm'+$index}}" class="form-control oditek-form" placeholder="Add Comment" ng-model="answers['comm'+$index]">
</td>
<td><input type="submit" name="plus" id="plus" value="+" style="width:20px; text-align:center;" onclick="cloneRow(this)"></td>
</tr>
</tbody>
</table>
The out put of the above table is given below.
my controller file is given below.
$scope.answers={};
$scope.days=[];
$http({
method:'GET',
url:"php/customerInfo.php?action=day",
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function successCallback(response){
//console.log('day',response.data);
angular.forEach(response.data,function(obj){
$scope.days.push(obj);
})
},function errorCallback(response) {
})
Here i need when user will click on plus button for one day one new row will add for that same day with different id and model name dynamically.please help me.
I have created a plunker demo for you which describe my idea. Hope it may help you.
https://plnkr.co/edit/JiieQZ?p=preview

JQuery cloning a Select2 input

I have some HTML like so
<table class="table table-bordered table-hover" id="actionTable">
<thead>
<tr >
<th class="text-center">Action</th>
<th class="text-center">Responsibility</th>
<th class="text-center">Completion Date</th>
</tr>
</thead>
<tbody>
<tr id='actionRow'>
<td>
<input type="text" name='actionInput' placeholder='Action' class="form-control"/>
</td>
<td>
<select class="responsibility" name="responsibilityInput" id="responsibilityInput">
<option value="OptionOne">Option One</option>
<option value="OptionTwo">Option Two</option>
<option value="OptionThree">Option Three</option>
<option value="OptionFour">Option Four</option>
</select>
</td>
<td>
<input type="text" name='dateInput' placeholder='Completion Date' class="form-control"/>
</td>
</tr>
</tbody>
</table>
<a id="add_row" class="btn btn-default pull-right">Add Row</a>
<a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
When the Add Row button is clicked, I need it to clone actionRow. I have this working to some point. This is my JSFiddle
As you can see, a row is successfully cloned. However, on cloned rows, the Select box no longer works. This is because I need to destroy the cloned select before I clone it. This answer here explains this problem better
Stack Overflow Answer
How could I apply this in my situation though? I am cloning the whole row, not a single select input? How can I clone the select seperately but still have it where I need it to be?
Any help appreciated.
Thanks

How to access javascript value in jsp?

Hi i am using jquery. like,
<script type="text/javascript">
$(function() {
$('#usertype').change(function() {
$.post("<%=request.getContextPath()%>/CommonServlet", {utype:$('#usertype').val(),funName:'getConfigMast'}, function(j){
$("input#it").html(j);alert(j);
});
});
});
</script>
in this j contians some model object i have to iterate his object in my same jsp page and those values i have to show in text fields in <table>. here the jquery function will called when i selected the the value from combobox of same <table>
and jsp table:
<table >
<tr>
<td><input name="filetype" type="text" class="formTxtBox_1" id="filetype"/></td>
</tr>
<tr>
<td>
<select name="usertype" id="usertype" >
<option >- Select Type of User -</option>
<option value="admin"> administrator </option>
<option selected="true" > normal</option>
<option> member</option>
</select> </td>
</tr>
<tr>
<td><input name="singlefile" type="text" id="singlefile"/></td>
</tr>
<tr>
<td><input name="totalfile" type="text" id="totalfile"/></td>
</tr>
<table>
The value of an input field needs to be set using val() function, not html().
$('#singlefile').val(value);

Categories

Resources