Reputation: 176
Here, I'm trying to insert a tr tag under a selected tr tag.I managed to insert the tr in the table but it was in the bottom. This is a sample code:
"use strict";
(function(angular) {
var app = angular.module('app', []);
app.controller('MainController', MainController);
MainController.$inject = ['$compile', '$scope', '$templateCache'];
function MainController($compile, $scope, $templateCache) {
var publishShown = false;
var lastItemAppned;
var vm = this;
vm.targets = ['Single passenger', 'Single driver', 'All passengers', 'All drivers'];
vm.items = ["Cheese", "Pepperoni", "Black Olives"];
vm.cancel = cancel;
vm.fruits = [{
name: 'Orange',
color: 'Orange',
tree: 'Orange Tree!',
origin: 'China'
}, {
name: 'Apple',
color: 'Green',
tree: 'Apple Tree!',
origin: 'Moon'
}];
vm.message = 'Fruit store!';
function appendTemplate(event) {
if (publishShown) {
removeLastAppend();
}
publishShown = true;
var template = $templateCache.get('template.html');
var compiledHtml = $compile(template)($scope);
var parent = event.currentTarget.parentElement.parentElement.parentElement;
parent.append(compiledHtml[0]);
}
vm.showOptions = function(event) {
appendTemplate(event);
}
function removeLastAppend() {
angular.element('#publish-template').remove();
}
function cancel() {
removeLastAppend();
}
}
})(window.angular);
<!DOCTYPE html>
<html ng-app="app">
<head>
<link data-require="bootstrap-css@3.*" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
<link data-require="bootstrap@*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
<script data-require="jquery@*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="Tether@*" data-semver="1.4.0" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script data-require="bootstrap@*" data-semver="4.0.5" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<script data-require="[email protected].*" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
<script data-require="[email protected].*" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular-animate.js"></script>
<script data-require="[email protected].*" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular-touch.js"></script>
<script data-require="ui-bootstrap@*" data-semver="2.5.0" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-2.5.0.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController as vm">
<script type="text/ng-template" id="template.html">
<tr id="publish-template">
<td colspan="5">
<div class="row">
<div class="col-sm-3">
<button class="btn btn-sm btn-success" ng-click="vm.command()">Command</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-primary" ng-click="vm.sell()">Sell</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-warning" ng-click="vm.eatSome()">Eat some!</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-danger" ng-click="vm.cancel()">Cancel</button>
</div>
</div>
</td>
</tr>
</script>
<div class="container-fluid">
<h1>{{vm.message}}</h1>
<table class="table">
<thead>
<th>Name</th>
<th>Color</th>
<th>Tree</th>
<th>Origin</th>
<th>Action</th>
</thead>
<tbody>
<tr ng-repeat="fruit in vm.fruits">
<td>{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptions($event)">Options</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
As you see, if you click the second options button, you'll not notice the problem, but if you click the first one, it adds a tr tag always in the bottom of the table!
My aim is to add the new tr under the selected on. Thanks in advance
Upvotes: 1
Views: 189
Reputation: 361
The ng-repeat is running on the tr element and you are looking to break the loop and insert another tr in the middle based on the row that was clicked on. To achieve this you need to break the table into 3 parts
Initially, you will need to assign all the fruits to topFruits and keep the bottomFruits null. Also keep the tr row with the option buttons hidden.
When the show Options button is clicked on a row, get the index of the row and then divide the fruits between topFruits and bottomFruits based on the index. Also make the row with buttons visible.
Here is a working demo
Here is the HTML body
<body ng-controller="MainCtrl as vm">
<div class="container-fluid">
<h1>{{vm.message}}</h1>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
<th>Tree</th>
<th>Origin</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="fruit in vm.topFruits">
<td style="background:#bbb">{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptionsTop($index)">Options</button>
</td>
</tr>
<tr id="publish-template" style="display:none">
<td colspan="5">
<div class="row">
<div class="col-sm-3">
<button class="btn btn-sm btn-success" ng-click="vm.command()">Command</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-primary" ng-click="vm.sell()">Sell</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-warning" ng-click="vm.eatSome()">Eat some!</button>
</div>
<div class="col-sm-3">
<button class="btn btn-sm btn-danger" ng-click="vm.cancel()">Cancel</button>
</div>
</div>
</td>
</tr>
<tr ng-repeat="fruit in vm.bottomFruits">
<td style="background:#fcc">{{fruit.name}}</td>
<td>{{fruit.color}}</td>
<td>{{fruit.tree}}</td>
<td>{{fruit.origin}}</td>
<td>
<button class="btn btn-primary" ng-click="vm.showOptionsBottom($index)">Options</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
Here is the controller code
vm.fruits = [{
name: 'Orange',
color: 'Orange',
tree: 'Orange Tree!',
origin: 'China'
}, {
name: 'Apple',
color: 'Green',
tree: 'Apple Tree!',
origin: 'Moon'
}];
vm.topFruits = vm.fruits;
vm.bottomFruits = [];
vm.message = 'Fruit store!';
function appendTemplate(index) {
if (vm.publishShown) {
removeLastAppend();
}
vm.publishShown = true;
vm.topFruits = [];
vm.bottomFruits = [];
document.getElementById('publish-template').style.display="block";
for(i=0;i<vm.fruits.length;i++) {
if(i<=index) {
vm.topFruits[i] = vm.fruits[i];
} else {
vm.bottomFruits[i-vm.topFruits.length] = vm.fruits[i];
}
}
}
vm.showOptionsTop = function(index) {
appendTemplate(index);
}
vm.showOptionsBottom = function(index) {
appendTemplate(index+vm.topFruits.length);
}
function removeLastAppend() {
document.getElementById('publish-template').style.display="none";
vm.publishShown = false;
}
function cancel() {
removeLastAppend();
}
Upvotes: 1