What Im trying to do:
Use peopleDropdown to add the new person to the person dropdown within createPerson
Use peopleTable to add a new table row within createPerson
main.js:
class Dropdown {
constructor(idSelector) {
this.idSelector = idSelector;}
getCurrentSelection() {
return $(this.idSelector).val();}
appendToDropdown(label, value) {
$(this.idSelector).append(`<option value=${value}>${label}</option>`);}
}
class Table {
constructor(idSelector) {
this.selector = idSelector;
}
appendRow(data) {
let tableRows = `
<td class="name-col"></td>
<td class="balance-col"></td>
<td class="consumed-col"></td>
`;
$(this.selector).append(`<tr id="">${tableRows}</tr>`);
}
modifyRow(/*define inputs*/) {}
}
const peopleDropdown = new Dropdown('#people-dropdown');
const peopleTable = new Table(`#person-table tbody`);
const allPeople = [];
const createPerson = () => {
let name = getNameInput();
allPeople.push(name);
//peopleDropDown code
//peopleTable code
}
I'm stuck on how to add the tables since my regular way of doing this would be using react as the framework. (which is not a option here)
Html:
<div id="creator-row">
<input id="name-input" placeholder="Name" />
<button onclick="createPerson()">Create Person</button>
</div>
<div id="consume-row">
<label for="person-list">Choose a person:</label>
<select name="person-list" id="people-dropdown"></select>
</div>
<table id="person-table">
<thead>
<tr class="header-row">
<th class="name-col">Name</th>
</tr>
</thead>
<tbody></tbody>
</table>
This snippet only answers the question of how to add the rows to the table
const table = document.getElementById("person-table");
const tbody = table.querySelector("tbody");
const tr = document.getElementById("tr");
// some people
const people = [{
"name": "one",
"balance": 1,
"consumed": 1
},
{
"name": "two",
"balance": 2,
"consumed": 2
},
{
"name": "three",
"balance": 3,
"consumed": 3
},
];
// loop through the people and add them to the table
people.forEach(p => {
const newRow = tr.content.cloneNode(true);
const cells = newRow.querySelectorAll("td");
cells[0].textContent = p.name;
cells[1].textContent = p.balance;
cells[2].textContent = p.consumed;
tbody.appendChild(newRow);
});
td {
border: 1px solid #000;
}
<table id="person-table">
<thead>
<tr class="header-row">
<th class="name-col">Name</th>
<th class="balance-col">Balance</th>
<th class="consumed-col">Consumed</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- a template of the row -->
<template id="tr">
<tr>
<td class="name-col"></td>
<td class="balance-col"></td>
<td class="consumed-col"></td>
</tr>
</template>
Related
I want to take data from my local storage and show it dynamically. In this table below is the code that I tried but it is not working.
<script>
var cart= JSON.parse( localStorage.getItem('Mylinklist'));
$.each(Mylinklist, function(key, value){
$('tbody').append(`<tr>
<td>${cart.name}</td>
<td>${cart.url}</td>
</tr>`)
})
</script>
<div id="actionerpanel" class="col col-lg-6 col-12 ">
<div class="rapi-card m-lg-5 m-1">
<b class="rapi-card-colored-header p-3 mb-2">Quick Links <span>+</span></b>
<div class="container">
<div class="row justify-content-center "><table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
You can use insertAdjacentHTML and literals templates for this kind of operation.
var carts = [{
id: 'id1',
name: 'test',
url: 'url'
}, {
id: 'id2',
name: 'test2',
url: 'url2'
}] //Fake localstorage replace it with JSON.parse
carts.forEach(cart => {
let button = `<button onclick="alert('Item id : ${cart.id}')">Click</button>`,
row = `<tr id="item_${cart.id}"><td>${cart.name}</td><td>${cart.url}</td><td>${button}</td></tr>`;
document.querySelector('tbody').insertAdjacentHTML('beforeend', row)
})
//OR
for (let cart of carts) {
let button = `<button onclick="alert('Item id : ${cart.id}')">Click</button>`,
row = `<tr id="item_${cart.id}"><td>${cart.name}</td><td>${cart.url}</td><td>${button}</td></tr>`;
document.querySelector('tbody').insertAdjacentHTML('beforeend', row)
}
<table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>
You can make it with plain JS like this. I had to comment out the places with localstorage. Because access to localStorage is not allowed on SO. As soon as you add them, it works.
const arr = [
{id: 123, name: "google", url: "https://www.google.com"},
{id: 124, name: "bing", url: "https://www.bing.com"},
]
// store to localStorage
// localStorage.setItem('Mylinklist', JSON.stringify(arr));
// get from localStorage
// const data = JSON.parse(localStorage.getItem('Mylinklist'));
const table = document.querySelector('.table');
// change obj.forEach to data.forEach because in SO you cant use localStorage!!!
arr.forEach((e) => {
let tr = document.createElement('TR');
let td_name = document.createElement('TD');
let td_url = document.createElement('TD');
td_name.innerHTML = e.name
td_url.innerHTML = e.url
tr.append(td_name)
tr.append(td_url)
table.append(tr)
})
<div class="row justify-content-center "><table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
This question already has answers here:
vue.js put focus on input
(5 answers)
Closed 2 years ago.
I have dynamic rows where it adds new row by clicking on button OR scan input success, now the issue is that I can't get focus on new row.
Demo
Code
To avoid confusion I've commented all lines in code.
Template
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<td><strong>Serial Number</strong></td>
<td width="50"></td>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in form.barcode_serial_number" :key="index">
<td>
<el-input ref="barcode" v-model="row.barcode_serial_number"></el-input>
</td>
<td>
<el-link v-on:click="removeElement(index);" style="cursor: pointer">Remove</el-link>
</td>
</tr>
</tbody>
</table>
<div>
<button type="button" class="button btn-primary" #click="addRow">Add row</button>
</div>
Script
data() {
return {
form: {
barcode_serial_number: [], //get data of all rows
},
}
},
created() {
//scanner
const eventBus = this.$barcodeScanner.init(this.onBarcodeScanned, { eventBus: true })
if (eventBus) {
eventBus.$on('start', () => {
this.loading = true;
console.log('start')
})
eventBus.$on('finish', () => {
this.loading = false;
console.log('finished')
// add new row when scan succeed
this.$nextTick(function () {
this.form.barcode_serial_number.push({
barcode_serial_number: ''
});
})
})
}
},
methods: {
// add autofocus to new row
focusInput() {
this.$refs.barcode.focus();
},
// add new row by clicking button
addRow: function() {
var barcodes = document.createElement('tr');
this.form.barcode_serial_number.push({
barcode_serial_number: ''
});
},
// remove row by clicking button
removeElement: function(index) {
this.form.barcode_serial_number.splice(index, 1);
},
}
Question
How do I set autofocus on newly added rows?
At the moment the new serial_number is inserted the DOM is not updated so we cant focus it.
We need to use nextTick to run a function when the DOM is updated.
Vue.config.devtools = false;
Vue.config.productionTip = false;
var app = new Vue({
el: '#app',
data: {
form: {
barcode_serial_number: []
}
},
methods: {
addRow() {
this.form.barcode_serial_number.push({
barcode_serial_number: ''
});
this.$nextTick(() => {
const nbBarcodes = this.$refs.barcode.length;
this.$refs.barcode[nbBarcodes - 1].focus();
});
},
removeElement(index) {
this.form.barcode_serial_number.splice(index, 1);
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<tr>
<td><strong>Serial Number</strong></td>
<td width="50"></td>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in form.barcode_serial_number" :key="index">
<td>
<input ref="barcode" v-model="row.barcode_serial_number"></input>
</td>
<td>
<button v-on:click="removeElement(index);">Remove</button>
</td>
</tr>
</tbody>
</table>
<div>
<button #click="addRow">Add row</button>
</div>
</div>
I'm trying to create button event listener that will add the contents of a <tr> element to the <tbody> element. Ive tried multiple methods such as insertRow() and adjacentHtml() and none seem to work. What am I doing wrong? also i am using typescript, could that be the issue as well?
html
<table class="table table-striped table-dark invoice-table">
<thead>
<tr class="head-contents">
<th scope="col">#</th>
<th scope="col-3">Description</th>
<th scope="col">Quanity</th>
<th scope="col">item number</th>
<th scope="col">item price</th>
<th scope="col">total price</th>
</tr>
</thead>
<tbody id="table-contents">
<tr id="item-info">
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
</tr>
</tbody>
</table>
<!-- add item button -->
<button type="button" class="btn btn-primary" id="addItem">Add Item</button>
<!-- delete item button -->
<button type="button" class="btn btn-warning" id="deleteItem">Delete Item</button>
javascript
// event listener to add an item
let addedItem = document.getElementById("addItem").addEventListener("click", () => {
let table = document.getElementById("invoice-table");
let row = document.getElementById("item-info");
});;
<table class="table table-striped table-dark invoice-table">
<thead>
<tr class="head-contents">
<th scope="col">#</th>
<th scope="col-3">Description</th>
<th scope="col">Quanity</th>
<th scope="col">item number</th>
<th scope="col">item price</th>
<th scope="col">total price</th>
</tr>
</thead>
<tbody id="table-contents">
<tr id="item-info">
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
</tr>
</tbody>
</table>
<button id="addItem">Add Item</button>
<script>
document.getElementById('addItem').addEventListener('click', () => {
let body = document.getElementById("table-contents");
let row = document.getElementById("item-info");
var para = document.createElement("tr")
para.innerHTML = `
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
`;
body.appendChild(para);
})
</script>
You need to create a template and then append to it every time you click on the button.
let addedItem = document.getElementById("addItem").addEventListener("click", () => {
let item = document.getElementById("table-contents");
item.insertAdjacentHTML('beforeend', "<tr id='item-info'> <th scope='row'>1</th> <td><input type='text'></td> <td><input type='number'></td> <td><input type='number'></td> <td><input type='number'></td> <td><span></span></td></tr>");
});;
Don't forget the button within your HTML:
<button id="addItem">Add New Row</button>
This worked for me, let me know if you have more questions.
Check out the code snippet. This code worked for me. Depending on what actually you want to archive you can/ should tweak this to your needs. Like adding an id that actually increments with each row, and making an additional function to calculate your Total columns.
But since that wasn't included in the answer, I leave that up to you :)
// ARRAY FOR HEADER.
const arrHead = ['#', 'One', 'Two', 'Three'];
// SIMPLY ADD OR REMOVE VALUES IN THE ARRAY FOR TABLE HEADERS.
// FIRST CREATE A TABLE STRUCTURE BY ADDING A FEW HEADERS AND
// ADD THE TABLE TO YOUR WEB PAGE.
function createTable() {
var empTable = document.createElement('table');
empTable.setAttribute('id', 'empTable'); // SET THE TABLE ID.
var tr = empTable.insertRow(-1);
for (var h = 0; h < arrHead.length; h++) {
var th = document.createElement('th'); // TABLE HEADER.
th.innerHTML = arrHead[h];
tr.appendChild(th);
}
var div = document.getElementById('cont');
div.appendChild(empTable); // ADD THE TABLE TO YOUR WEB PAGE.
}
// ADD A NEW ROW TO THE TABLE
function addRow() {
var empTab = document.getElementById('empTable');
var rowCnt = empTab.rows.length; // GET TABLE ROW COUNT.
var tr = empTab.insertRow(rowCnt); // TABLE ROW.
tr = empTab.insertRow(rowCnt);
for (var c = 0; c < arrHead.length; c++) {
var td = document.createElement('td'); // TABLE DEFINITION.
td = tr.insertCell(c);
if (c == 0) { // FIRST COLUMN.
// ADD A BUTTON.
var button = document.createElement('input');
// SET INPUT ATTRIBUTE.
button.setAttribute('type', 'button');
button.setAttribute('value', 'Remove');
// ADD THE BUTTON's 'onclick' EVENT.
button.setAttribute('onclick', 'removeRow(this)');
td.appendChild(button);
}
else {
// CREATE AND ADD TEXTBOX IN EACH CELL.
var ele = document.createElement('input');
ele.setAttribute('type', 'text');
ele.setAttribute('value', '');
td.appendChild(ele);
}
}
}
// DELETE TABLE ROW.
function removeRow(oButton) {
var empTab = document.getElementById('empTable');
empTab.deleteRow(oButton.parentNode.parentNode.rowIndex); // BUTTON -> TD -> TR.
}
// EXTRACT AND SUBMIT TABLE DATA.
function sumbit() {
var myTab = document.getElementById('empTable');
var values = new Array();
// LOOP THROUGH EACH ROW OF THE TABLE.
for (row = 1; row < myTab.rows.length - 1; row++) {
for (c = 0; c < myTab.rows[row].cells.length; c++) { // EACH CELL IN A ROW.
var element = myTab.rows.item(row).cells[c];
if (element.childNodes[0].getAttribute('type') == 'text') {
values.push(element.childNodes[0].value);
}
}
}
console.log(values);
}
table
{
width: 70%;
font: 17px Calibri;
}
table, th, td
{
border: solid 1px #DDD;
border-collapse: collapse;
padding: 2px 3px;
text-align: center;
color: green;
}
<body onload="createTable()">
<input type="button" id="addRow" value="Add New Row" onclick="addRow()" />
</p>
<!--THE CONTAINER WHERE WE'll ADD THE DYNAMIC TABLE-->
<div id="cont"></div>
<p><input type="button" id="bt" value="Sumbit Data" onclick="sumbit()" /></p>
</body>
what is the best way to save a dynamic table data in to json.
I have two tables that i want to save in to one json file.
i"m able to console the regular table data but i"m unable to locate the td value of a dynamic table.
my plan to save to json and clear the forum for additional DC/pop info adding
so please check the save button and help me understand how to continue
1. save the popisp table
2. clear and make it ready for the next pop entry.
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js">
$(document).ready(function(){
$(".add-row").click(function(){
var name = $("#ispname").val();
var capasity = $("#ispcapasity").val();
var markup = "<tr><td><input type='checkbox' name='record'></td><td>" + name + "</td><td>" + capasity + "</td></tr>";
$('#popisp tr:last').after(markup);
});
$(".delete-row").click(function(){
$('#popisp').find('input[name="record"]').each(function(){
if($(this).is(":checked")){
$(this).parents("tr").remove();
}
});
});
$(".save_asJSON").click(function(){
var pop_name = document.getElementById("popname").value
jsonobj.pops[pop_name] = {
name: document.getElementById("popname").value,
city: document.getElementById("popcity").value,
subnet: document.getElementById("popsubnet").value,
}
console.log(jsonobj);
});
});
var jsonobj = {
pops: {}
};
</script>
<body>
<table id="PoP_Details">
<tr>
<td>Pop name:</td>
<th colspan="2"><input id="popname" name='pops[name]'></input></th>
</tr>
<tr>
<td>City:</td>
<th colspan="2"><input id="popcity" name='pops[name][city]'></input></th>
<tr>
<td>POP Subnet</td>
<th colspan="2"><input id="popsubnet" name='pops[name][subnet]'></input></th>
</tr>
</table>
<form>
<input type="text" id="ispname" placeholder="Name">
<input type="text" id="ispcapasity" placeholder="capasity">
<input type="button" class="add-row" value="Add ISP">
</form>
<div class="wrap">
<table id="popisp">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>capasity</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
<button type="button" class="delete-row">Delete Row</button>
<button type="button" class="save_asJSON">Save</button>
</body>
here is how I like my json to looks like
{
"pops": {
"pop1": {
"name": "pop1",
"city": "blabla",
"subnet": "192.168.1.0/24",
"isps": [
{
"name": "isp1",
"capasity": "10M"
},
{
"name": "isp2",
"capasity": "10M"
}
]
},
"pop2": {
"name": "pop2",
"city": "blabla",
"subnet": "192.168.2.0/24",
"isps": [
{
"name": "isp3",
"capasity": "20M"
},
{
"name": "isp4",
"capasity": "30M"
},
{
"name": "isp5",
"capasity": 500M"
}
]
}
}
}
I can suggest the following guidance :
Save inputs as jQuery variables for further use, not necessary but usefull, ex :
var $input = $('#popname');
Add a function that use the table, iterate through the <tr> in <tbody> and retrieve the <td> to compose object to save for each row, return it as an array.
Add a function that use the inputs to clear the form
Call the two function above when saving the array, the first to add the data to the json saved, the second to clear the form.
I show bellow an update of your snippet with complete modification, but I suggest you use use the guidance to implement it in a way that suits your needs.
$(document).ready(function(){
// Inputs as jQuery variables
var $nameInput = $("#popname");
var $cityInput = $("#popcity");
var $subnetInput = $("#popsubnet");
var $ispNameInput = $("#ispname");
var $ispCapacityInput = $("#ispcapasity");
var $popispTable = $('#popisp');
// array for convenience loop
var inputs = [$nameInput, $cityInput, $subnetInput,
$ispNameInput, $ispCapacityInput];
// function to clear all inputs and remove isp rows
function clearForm() {
inputs.forEach(e => e.val(''));
$popispTable.find('tbody').find('tr').remove();
$popispTable.find('tbody').append($('<tr>'));
}
// function that return an array of isp rows data
function ispTableData() {
var rows = $popispTable.find('tbody').find('tr');
if (!rows.length) return [];
console.log(rows.length);
var data = rows.toArray().reduce((data, e, k) => {
var tds = $(e).find('td');
if (!tds.length) return [];
data.push({
checked: $(tds[0]).find('input').is(":checked"),
name: $(tds[1]).text(),
capasity: $(tds[2]).text()
});
return data;
}, []);
return data;
}
$(".add-row").click(function(){
var name = $("#ispname").val();
var capasity = $("#ispcapasity").val();
var markup = "<tr><td><input type='checkbox' name='record'></td><td>" + name + "</td><td>" + capasity + "</td></tr>";
$('#popisp tr:last').after(markup);
// eventually clear row form inputs here as well
});
$(".delete-row").click(function(){
$('#popisp').find('input[name="record"]').each(function(){
if($(this).is(":checked")){
$(this).parents("tr").remove();
}
});
});
$(".save_asJSON").click(function(){
var pop_name = document.getElementById("popname").value
jsonobj.pops[pop_name] = {
name: $("#popname").val(),
city: $("#popname").val(),
subnet: $("#popsubnet").val(),
// add the isp rows data
isps: ispTableData()
}
console.log(jsonobj);
// clear the form
clearForm();
});
});
var jsonobj = {
pops: {}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table id="PoP_Details">
<tr>
<td>Pop name:</td>
<th colspan="2"><input id="popname" name='pops[name]'></input></th>
</tr>
<tr>
<td>City:</td>
<th colspan="2"><input id="popcity" name='pops[name][city]'></input></th>
<tr>
<td>POP Subnet</td>
<th colspan="2"><input id="popsubnet" name='pops[name][subnet]'></input></th>
</tr>
</table>
<form>
<input type="text" id="ispname" placeholder="Name">
<input type="text" id="ispcapasity" placeholder="capasity">
<input type="button" class="add-row" value="Add ISP">
</form>
<div class="wrap">
<table id="popisp">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>capasity</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
<button type="button" class="delete-row">Delete Row</button>
<button type="button" class="save_asJSON">Save</button>
</body>
Plunker sample
How to hide table column if all json value is null for any property
using angular js
index.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.isArray = angular.isArray;
$scope.data = [{
"Id": null,
"Title": "US",
"Description": "English - United States",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "MX",
"Description": "test",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "SE",
"Description": "Swedish - Sweden",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}]
$scope.cols = Object.keys($scope.data[0]);
$scope.notSorted = function(obj) {
if (!obj) {
return [];
}
return Object.keys(obj);
}
});
index.html
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<th ng-repeat="(k,v) in data[0]">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)">
<table ng-if="isArr" border=1>
<thead>
<tr>
<td>
<button ng-click="expanded = !expanded" expand>
<span ng-bind="expanded ? '-' : '+'"></span>
</button>
</td>
</tr>
<tr>
<th ng-repeat="(sh, sv) in value[0]">{{sh}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in value" ng-show="expanded">
<td ng-repeat="(sk, sv) in sub">{{sv}}</td>
</tr>
</tbody>
</table>
<span ng-if="!isArr">{{value}}</span>
</td>
</tr>
</tbody>
</table>
You can filter out columns that have only null values with:
JavaScript
$scope.cols = Object.keys($scope.data[0]).filter(function(col) {
return $scope.data.some(function(item) {
return item[col] !== null;
});
});
and check in template if this column should be rendered:
HTML
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<!-- Iterate over non-null columns -->
<th ng-repeat="col in cols">{{col}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<!-- Use ngIf to hide redundant column -->
<td ng-if="cols.indexOf(prop)>=0" ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" >
...
Plunker
http://plnkr.co/edit/PIbfvX6xvX5eUhYtRBWS?p=preview
So the id is null for every element in the array, then do
<th ng-repeat="(k,v) in data[0]" ng-show="v">{{k}}</th>
and
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-show="value">
plnkr: http://plnkr.co/edit/rra778?p=preview
You need to make use of the cols property you defined in your $scope, but you also need to make sure its correct and responsive. You do that like this:
var colsFromData = function(data) {
var activeCols = {};
data.forEach(function(o) {
Object.keys(o).forEach(function(k) {
if(null == o[k])
return;
activeCols[k] = 1;
})
});
return Object.keys(activeCols);
}
$scope.cols = colsFromData($scope.data);
$scope.$watchCollection('data', colsFromData);
Then in your template, to use the now correct cols array:
...
<thead>
<tr>
<th ng-repeat="k in cols">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-if="cols.indexOf(prop) >= 0">
...
And the updated plunker