I have a jsp with a bootstrap wizard, like this:
http://s3.amazonaws.com/creativetim_bucket/products/22/original/wizard_template.png?1407329794
With this wizard, I can add the employees element collected in Javascript array (I also use AngularJS).
After that, in the last step of wizard there is the summary of the employees shown in a table.
For each row of the table, I have been added an href link to delete the current employee element. This href link calls a function managed by AngularJS.
Ok, it work. But, after the deletion, the table is not refresh. And the deleted element is present in table yet, but not in array.
So, how can I refresh the table?
Here's the code of the table:
<table class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<td>#</td>
<td>Nome</td>
<td>Cognome</td>
<td>Matricola</td>
</tr>
</thead>
<tr ng-repeat="employee in listaDipendenti track by $index">
<td>{{$index + 1}}</td>
<td>{{employee.nome}}</td>
<td>{{employee.cognome}}</td>
<td>{{employee.matricola}}</td>
<td><a ng-click="DeleteEmployees($index)" href="#" class="btn btn-simple btn-xs" role="button" style="color: green">Delete</a></td>
</tr>
</table>
Here's the code in JS:
//Classe di tipo Employee
function Employee(nome, cognome, matricola) {
this.nome = nome;
this.cognome = cognome;
this.matricola = matricola;
}
var listEmployees = [];
var nDip = 0;
function Controller($scope) {
$scope.DeleteEmployees = function (n) {
if (n > -1) {
listEmployees.splice(n, 1);
}
};
}
for #charlietfl
It's not right, look the function used to add an employee in JS array.
$scope.AddInList = function () {
var nome = $("#nome").val();
var cognome = $("#cognome").val();
var matricola = $("#matricola").val();
$("#nome").val("");
$("#cognome").val("");
$("#matricola").val("");
nDip = nDip + 1;
listEmployees.push(new Employee(nome, cognome, matricola));
$("#cont").text(nDip);
$scope.listaDipendenti = JSON.parse(JSON.stringify(listEmployees));
};
Related
I was trying to make table using JavaScript.
I have created a function makeTable to generate table data each time it is been called.
My Code -
<table class="table table-striped">
<tr>
<th>User Name</th>
<th>Audio</th>
<th>Video</th>
</tr>
<tbody id="myTable">
</tbody>
</table>
function onMemberListUpdate(members) {
console.log("member updated")
buildTable(members);
}
function buildTable(data){
console.log("build table function called", data);
var table = document.getElementById('myTable');
for(var i =0; i<data.length; i++){
var row = `<tr> <td>${data[i].name}</td> <td>${data[i].audio_muted}</td> <td>${data[i].video_muted}</td> <td><button class="btn btn-primary">Audio</button></td>`
table.innerHTML += row;
}
}
Issue that I am facing here is whenever member list updates and onMemberListUpdate function gets called it calls buildTable function that makes new row each time I don't want to create new row each time instead I want to update the existing table data. How can I achieve this thing please help
Consider marking each row with an attribute that you can use to find it later when you need to update it.
You can (for example) add class="item-id-${data[i].id}" to the tr (as below)
function buildTable(data){
console.log("build table function called", data);
var table = document.getElementById('myTable');
for(var i =0; i<data.length; i++){
var row = `<tr class="item-id-${data[i].id}"> <td>${data[i].name}</td> <td>${data[i].audio_muted}</td> <td>${data[i].video_muted}</td> <td><button class="btn btn-primary">Audio</button></td>`
table.innerHTML += row;
}
}
then you can call updateRow and in that function you can get the row by doing $(".item-id-123") and you can create new html that replaces it, so something like this:
function updateRow(data) {
$(`.item-id-${data.id}`).replaceWith(`
<tr class="item-id-${data.id}">
<td>${data.name}</td>
<td>${data.audio_muted}</td>
<td>${data.video_muted}</td>
<td><button class="btn btn-primary">Audio</button></td>
</tr>`);
}
I'm a beginner at JavaScript and haven't been able to figure this out...
I need to check each row of a table to see if the string "Business Cards" exists in each row. If EVERY row contains this string, I'll proceed with option A, but if even one row doesn't contain the string, I'll stop checking and proceed with option B.
Here is an idea of what the table looks like in HTML (although the number of rows and products in each row will vary, since they're dynamically generated):
<table class="rgMasterTable" border="0" id="ctl00_cphMainContent_dgShippingItems_ctl00" style="width:100%;table-layout:auto;empty-cells:show;">
<thead>
<tr>
<th scope="col" class="rgHeader" style="text-align:center;">Name</th>
<th scope="col" class="rgHeader" style="text-align:center;">No. of Units</th>
</tr>
</thead>
<tbody>
<tr class="rgRow" id="ctl00_cphMainContent_dgShippingItems_ctl00__0" style="text-align:center;">
<td style="width:250px;">
Business Cards - TEST - CA Back
</td>
<td style="width:100px;">
250 Business Cards
</td>
</tr>
<tr class="rgAltRow" id="ctl00_cphMainContent_dgShippingItems_ctl00__1" style="text-align:center;">
<td style="width:250px;">
Business Cards - Joint Venture - TEST
</td>
<td style="width:100px;">
250 Business Cards
</td>
</tr>
</tbody>
</table>
And here's my attempt at the code. I'm trying to make use of the fact that the tr id will always have the index (eg: "ctl00_cphMainContent_dgShippingItems_ctl00__0" for the first row, "ctl00_cphMainContent_dgShippingItems_ctl00__1" for the second, etc), but maybe there's an easier way to do this?
var businessCardItem = 'Business Cards';
var orderItemCount = $('#ctl00_cphMainContent_dgShippingItems_ctl00 tr').length;
var onlyBusinessCards = true;
for (var i = 0; i <= orderItemCount; i++) {
if($('#ctl00_cphMainContent_dgShippingItems_ctl00__' + i).text().indexOf(businessCardItem) >= 0) {
return onlyBusinessCards;
}
else {
onlyBusinessCards = false;
return onlyBusinessCards;
break;
}
}
if (onlyBusinessCards == true) {
//Option A
}
else {
//Option B
}
Any help would be appreciated! Let me know if any more detail or clarification is needed!
Count how many rows contain "Business Cards" and compare to the number of rows:
Note: only count rows within tbody
var table = $("#ctl00_cphMainContent_dgShippingItems_ctl00");
var rows = $("tbody tr",table).length;
var rowsWithBC = $("tbody tr:contains(Business Cards)",table).length;
if( rows == rowsWithBC ) {
// Option A
} else {
// Option B
}
I am trying to filter the rows of a table to display the results of entered text in the search bar. The code below does the job but for some reason filters the column headings as well.
$('#search').keyup(function () {
var data = this.value.split(" ");
var rows = $(".Info").find("tr").hide();
if(this.value ==""){
rows.show();
return;
}
rows.hide();
rows.filter(function(i,v){
var t = $(this);
for (var d = 0; d < data.length; d++) {
if (t.is(":Contains('" + data[d] + "')")) {
return true;
}
}
return false;
}).show();
});
HTML
<input type = "search" name = "search" id = "search">
<table style ="width:95%" class = "Info">
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
</table>
The user adds rows which is why i haven't written any HTML for it.
Any help would be appreciated. Thanks in advance
http://jsfiddle.net/szjhngwm/
It looks like you need to filter using tbody
<table style ="width:95%" class = "Info">
<thead>
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
<thead>
<tbody>
</tbody>
</table>
var rows = $(".Info tbody tr").hide();
Another way to do this would be to use jQuery's :gt() selector.
The only thing that would change is this line:
var rows = $(".Info").find("tr:gt(0)").hide();
Notice the addition of :gt(0) to your tr.
I'm not sure if I'm trying to do too much here, but here is the scenario. I have an asp.net mvc page that, on the first time loading, returns a table of data in a view using the standard foreach mechanisms in the mvc framework. If the user has javascript enabled, I want to use knockout to update the table going forward. Is there a way to have knockout read the data from the dom table and use that data as the initial observable collection. From then on out, I would use knockout and ajax to add, edit, or delete data.
In a nutshell, I need to parse an html table into a knockout observable collection.
I've had a go at coding this up:
Here's the basic markup:
<table id="table" data-bind="template: { name: 'table-template' }">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr>
<td>Richard</td>
<td>Willis</td>
</tr>
<tr>
<td>John</td>
<td>Smith</td>
</tr>
</tbody>
</table>
<!-- Here is the template we'll use for re-building the table -->
<script type="text/html" id="table-template">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody data-bind="foreach: data">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: surname"></td>
</tr>
</tbody>
</script>
Javascript:
(function() {
function getTableData() {
// http://johndyer.name/html-table-to-json/
var table = document.getElementById('table');
var data = [];
var headers = [];
for (var i = 0; i < table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}
// go through cells
for (var i = 1; i < table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
for (var j = 0; j < tableRow.cells.length; j++) {
rowData[headers[j]] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data;
}
var Vm = function () {
this.data = ko.observableArray(getTableData());
};
ko.applyBindings(new Vm(), document.getElementById('table'));
})();
You can extend this concept using the mapping plugin to create observables for each row: http://knockoutjs.com/documentation/plugins-mapping.html
View a demo here: http://jsfiddle.net/CShqK/1/
EDIT: I'm not saying this is the best approach, as it can be costly to traverse a large table to get the data. I would probably just output the JSON in the page as suggested by others in this thread.
How about just feeding your observable array with the data instead of parsing the html table
myArray: ko.observableArray(#Html.Raw(Json.Encode(Model.myTableData)))
If you really need to go the parsing the html way, you can use the following code
var tableData = $('#myTable tr').map(function(){
return [
$('td,th',this).map(function(){
return $(this).text();
}).get()
];
}).get();
$(document).ready(function() {
var myData = JSON.stringify(tableData);
alert(myData)
});
Here is a fiddle showing the code in action:
http://jsfiddle.net/FWCXH/
I have this code as global for the whole page:
<script type="text/javascript">
var data = [];
var VM_FiltroSeguros =
{
seguros: ko.observableArray(data)
};
ko.applyBindings(VM_FiltroSeguros.seguros);
</script>
Then when a succesfull ajax call is made, executed this:
function okFiltrarSeguros(data)
{
var parsedData = parse(data);
if (parsedData.Ok)
{
toastr.success('Se encontraron ' + parsedData.Value.length.toString() + ' Seguros.');
$('#liResultsFiltroSeguro').show();
VM_FiltroSeguros.seguros = parsedData.Value;
};
The Html is these:
<table class="table table-hover">
<thead>
<tr>
<th>Ramo</th>
<th>Poliza</th>
</tr>
</thead>
<tbody data-bind="foreach: seguros">
<tr>
<td><span data-bind="text: NroRamo"></span></td>
<td><span data-bind="text: NroSeguro"></span></td>
</tr>
</tbody>
</table>
After VM_FiltroSeguros.seguros = parsedData.Value; is executed I can see in the debugger that the viewModel is filled whith objects, but the is never updated.
What could be wrong? Thanks!!!!
There's a couple of things you're doing wrong here. First, you need to bind the entire ViewModel:
var data = [];
var VM_FiltroSeguros =
{
seguros: ko.observableArray(data)
};
ko.applyBindings(VM_FiltroSeguros);
Then you need to add data to the 'seguros' property with a function call like this:
VM_FiltroSeguros.seguros(parsedData.Value);