dataTable columnFilter dropdown boxes won't appear - datatables-1.10

I'm having problems getting my dataTable columnFilter select boxes to appear.
I have similar code blocks working on several other pages within the application, but for some reason, the <select> dropdown boxes won't appear. I have validated that the list of values (statusValues and seasonValues) have the correct values in the array and there are no errors in the console.
The column count is correct (I had that problem before). I'm using dataTables 1.10.9.
What am I missing?
Here's my code:
#using ApolloAMS.Business.Models;
#model List<Tournament>
#{
ViewBag.Title = "Manage Tournaments";
ViewBag.TournamentName = "";
List<Season> seasons = ViewBag.Seasons;
}
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-2">
<span style="float: left; font-weight: bold;">Tournament Status:</span>
<span style="float: left; width: 100%;" id="statusFilter" class="filter"></span>
</div>
<div class="col-md-2">
<span style="float: left; font-weight: bold;">Season:</span>
<span style="float: left; width: 100%;" id="seasonFilter" class="filter"></span>
</div>
</div>
<table id="tblData" class="table table-bordered table-hover dataTable">
<thead>
<tr>
<th>Action</th>
<th>Name</th>
<th>Status</th>
<th>Season</th>
<th>Dates</th>
<th># Flights /# Lanes / Max Shooters</th>
</tr>
</thead>
<tbody>
#foreach (Tournament tourn in Model)
{
Season season = seasons.Where(s => s.ID.Equals(tourn.SeasonID)).FirstOrDefault();
<tr>
<td>
#{Html.RenderPartial("TournamentActions", tourn.ID);}
</td>
<td>#tourn.Name</td>
<td><span class="statusCell">#tourn.TournStatusName</span></td>
<td><span class="seasonCell">#season.Name</span></td>
<td>#tourn.DateStart.ToShortDateString() - #tourn.DateEnd.ToShortDateString()</td>
<td>#tourn.NumberOfFlights / #tourn.NumberOfLanes / #tourn.MaxShooters</td>
</tr>
}
</tbody>
</table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
#section Scripts
{
<script type="text/javascript">
var statusValues = [];
var seasonValues = [];
$('.statusCell').each(function () {
var found = false;
var text = $(this).text();
for (i = 0; i < statusValues.length; i++) {
if (statusValues[i] == text) {
found = true;
break;
}
}
if (!found) {
statusValues.push(text);
}
});
$('.seasonCell').each(function () {
var found = false;
var text = $(this).text();
for (i = 0; i < seasonValues.length; i++) {
if (seasonValues[i] == text) {
found = true;
break;
}
}
if (!found) {
seasonValues.push(text);
}
});
statusValues.sort();
seasonValues.sort();
$("#tblData").dataTable(
{
"aLengthMenu": [[10, 25, -1], [10, 25, "All"]]
, "iDisplayLength": -1
, "scrollX": true
, "stateSave": true
, "oLanguage": {"sSearch": "Search: "}
, "order": [[4, "desc"]]
}).columnFilter({
aoColumns: [
null,
null,
{ type: "select", values: statusValues, sSelector: "#statusFilter" },
{ type: "select", values: seasonValues, sSelector: "#seasonFilter" },
null,
null,
]
});
//addl layout/config for datatable
$('input[type=search]').css("background-color", "yellow");
$('input[type=search]').css("font-weight", "bold");
$('input[type=search]').css("font-size", "large");
$('#tblData_filter label').css("font-size", "large");
$('#tblData_filter label').css("font-weight", "bold");
</script>
}

What am I missing? Clearly, my brain is what's missing. Gotta have the footer elements with matching columns.
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>

Correct you need to have the <tfoot></tfoot> with matching columns. If you have the names of the columns in the <thead></thead> it might be helpful to have the names also in the <tfoot></tfoot>.
And since you have solved your problem please mark your answer as correct so that everyone can see that the question has an answer.

Related

ng-table: check box selection in each row

I have a ng-table where i am trying to implement selection using check box in each row.
<table id="List" class=" table table-bordered table-striped"
ng-table="tableParams" show-filter="true" template-pagination="custom/pager">
<tbody>
<tr ng-repeat="item in $data" >
<td style="width: 35px">
<input type="checkbox" name="selectedIds[]" value="{{item.id}}" ng-checked="isRowSelected(item.id)" ng-click="toggleSelection(item.id)" />
</td>
<td data-title="'Name'" sortable="'Name'" filter="{ 'Name': 'text' }" >
{{ item.Name}} </a>
</td>
<td data-title="'Email'" sortable="'Email'" >
{{ item.Email}}
</td>
<td data-title="'Phone Number'" sortable="'PhoneNumber'">
{{ item.PhoneNumber}}
</td>
</tr>
this is the controller:
angular.module("umbraco").controller("ListController",
function ($scope, $http, $routeParams) {
$scope.selectedIds = [];
$scope.toggleSelection = function (val) {
var idx = $scope.selectedIds.indexOf(val);
if (idx > -1) {
$scope.selectedIds.splice(idx, 1);
} else {
$scope.selectedIds.push(val);
}
};
$scope.isRowSelected = function (id) {
return $scope.selectedIds.indexOf(id) >= 0;
};
$scope.isAnythingSelected = function () {
return $scope.selectedIds.length > 0;
};
});
i am trying to select individual rows however the above code selecting all the rows on any row click.
any suggestion on this please?
You are not using the power of angular correctly :)
You should try something like that in your view:
<input type="checkbox" ng-checked="item.isRowSelected" ng-click="toggleSelection(item)" />
and in the controller:
$scope.toggleSelection = function(item){
item.isRowSelected = !item.isRowSelected;
}
$scope.isAnythingSelected = function () {
for(var i = 0; i < $scope.data.length; i++){
if($scope.data[i].isRowSelected === true){
return true;
}
}
return false;
};

Insert items into table in angularJs

I need your help, I new in angularJs. My question is how can I add items into table.
This is my index.html code:
<div class="col-md-5">
<table class="table">
<tr>
<th>Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr ng-repeat="product in products" class="quantity">
<td>{{product.name}}</td>
<td> <sapn class="plus-icon glyphicon glyphicon-minus" ng-click="minusOne($index)"></sapn>
{{product.quantity}}
<sapn class="minus-icon glyphicon glyphicon-plus" ng-click="plusOne($index)"></sapn>
</td>
<td>{{product.price }} </td>
<td>{{product.price * product.quantity}}</td>
</tr>
</table>
<span>Total: {{ getTotal() }}</span>
</br>
<button>first product</button>
<button>second product</button>
</div>
and this is controller.js file:
app.controller('MainController', ['$scope', function ($scope) {
$scope.appName = 'diyetSahovatKafe';
$scope.products = [
{
name: 'Обычный котлет',
quantity: 0,
price: 3500,
}
];
$scope.getTotal = function(){
var total = 0;
for(var i = 0; i < $scope.products.length; i++){
var product = $scope.products[i];
total += (product.price * product.quantity);
}
return total;
}
$scope.plusOne = function(index){
$scope.products[index].quantity += 1;
};
$scope.minusOne = function(index){
$scope.products[index].quantity -= 1;
};
and this is appearance
appearance
by clicking the button items should be added, can anybody help me with this?
Adding an item to products should automatically update your table since it is constructed with ng-repeat. Angular will detect the modification of products and refresh the table's rows since they are based on it.
$scope.products.push({ name : "I don't speak russian", quantity: 0, price : 4200 });

How to set checkAll for in angularjs ng-repeat table

I have a complex ng-repeat table,which I need to set the select all function for the checkbox of each row.He is my code:
JS:
$scope.getCCGenie = function(){
CCGenieService.transactionList().then(function(list){
$scope.CreditCardsList = list;
$scope.CorporateCardsNum = $scope.CreditCardsList.transactionInfo.corpCardCount;
$scope.PersonalCardsNum = $scope.CreditCardsList.transactionInfo.personalCardCount;
});
}
$scope.hasExpenseTypeLabel = false;
$scope.getCCGenie();
$scope.checkAllcorp = function(copcards) {
console.log(copcards);
if (copcards.selectedAllcorp) {
copcards.selectedAllcorp = true;
$scope.hasSelectedExpense = true;
} else {
copcards.selectedAllcorp = false;
$scope.hasSelectedExpense = false;
}
angular.forEach('copcards.transactions',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
// I need to loop the selected table to reset each corpisSelected,assign them the new value selectedAllcorp. but how?
};
Html:
<ul>
<li ng-repeat='copcards in CreditCardsList.transactionInfo.corporateCards'>
<span class='creditcardsubtitle'>{{copcards.cardName}} (****{{copcards.cardNumber}})</span>
<table class='table col-xs-12 col-md-12 col-lg-12' border="0" cellpadding="10" cellspacing="0" width="100%">
<thead>
<th class='text-center'><input type="checkbox" ng-model="copcards.selectedAllcorp" ng-change="checkAllcorp(copcards)"/></th>
<th class='text-left'>Date</th>
<th class='text-left'>Merchant</th>
<th class='text-right'>Amount</th>
<th class='text-center'>Expense Type</th>
<th class='text-left'><input type="checkbox" ng-model="selectedAllBill" ng-change="checkAllBillable()" style='margin-right:3px;'/> Billable</th>
<th class='text-center'>Attachment</th>
<th class='text-center'>Description</th>
</thead>
<tbody><tr ng-show='noExpense'><td colspan="8" align="center" style="text-align: center;" >No any Personal Cards!</td>
</tr>
<tr ng-repeat='componentObject in copcards.transactions' ng-class="{'selectedrow':componentObject.corpisSelected}">
<td type='checkbox' class='text-center'><input type='checkbox' ng-model='componentObject.corpisSelected' class='deletebox'/>{{componentObject.corpisSelected}}</td>
<td class='text-left tdwidth'>{{componentObject.transactionDateString | parseDateFormat | date}}</td>
<td class='text-left tdwidth'>{{componentObject.merchant}}</td>
<td class='text-right tdwidth'>${{componentObject.amount}}</td>
<td class='text-center tdwidth'><smart-expense-type></smart-expense-type></td>
<td class='text-left tdwidth'><input type='checkbox' ng-model='componentObject.isBillable'/></td>
<td class='text-center tdwidth'>{{componentObject.hasImage}}</td>
<td class='text-center tdwidth'><input type='text'ng-model='componentObject.description'/></td>
</tr>
</tbody>
</table>
</li>
</ul>
As you can see, I use nasted ng-repeat the loop data, there may be many tables over there, I want each table has his own selectAll function which works independently. Now the code is partly working fine, the problem is if you check the single checkbox in row, the checkall function will not work.I know I need to do something like this:
$scope.checkAllcorp = function() {
if (this.selectedAllcorp) {
$scope.hasSelectedExpense = true
this.selectedRow = true;
this.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
this.selectedRow = false;
this.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = this.selectedAllcorp;
})
};
But how can I access this 'selectedTable'?
Pass copcards to your function and then operate on that object instead of this:
ng-change="checkAllcorp(copcards)"
And then in your controller:
$scope.checkAllcorp = function(copcards) {
if (copcards.selectedAllcorp) {
$scope.hasSelectedExpense = true
copcards.selectedRow = true;
copcards.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
copcards.selectedRow = false;
copcards.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
you can pass the object you are on by calling it thru the function itself like this
ng-change="checkAllcorp(copcards)
and then use it as a parameter for you checkAllcorp function instead of this in you function
example :
<div ng-repeat="name in names"><button ng-click="msg(name)"></button></div>
controller scope :
$scope.msg = function(name) { alert(name.first)};

ng-Repeat going through 3 arrays with different properties

I am making a table where I can show data from 3 arrays (2 has identical properties, 1 different).
<table class="table table-striped table-condensed table-hover">
<thead>
<tr ng-bind-html="head">
</tr>
</thead>
<tbody>
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind="{{row.item1}}"></td>
<td ng-bind="{{row.item2}}"></td>
<td ng-bind="{{row.item3}}"></td>
<td ng-bind="{{row.item4}}"></td>
<td ng-bind="{{row.item5}}"></td>
<td ng-bind="{{row.item6}}"></td>
<td ng-bind="{{row.item7}}"></td>
</tr>
</tbody>
</table>
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.row = { item1: "item.num", item2: "item.name", item3: "item.category", item4: "item.location.name", item5: "item.toloc.name", item6: "item.department", item7: "item.adm", item8: "item.person.name" };
First array has 7 properties (num,name,category,location,department,adm,person) and other 2 arrays has 2 properties (code,name)
The problem lies in that when I use 2 of cells in a row, then other cells are still visible without any content. Is there a way to have one table which can ngRepeat arrays with different properties and property count?
Solution:
<table class="table table-striped table-condensed table-hover">
<thead>
<tr ng-bind-html="head"></tr>
</thead>
<tbody ng-include=activeTable>
</tbody>
</table>
<script type="text/ng-template" id="assets.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.num></td>
<td ng-bind=item.name></td>
<td ng-bind=item.category></td>
<td ng-bind=item.location.name></td>
<td ng-bind=item.department></td>
<td ng-bind=item.adm></td>
<td ng-bind=item.person.name></td>
</tr>
</script>
<script type="text/ng-template" id="persons.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.code></td>
<td ng-bind=item.name></td>
</tr>
</script>
<script type="text/ng-template" id="locations.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.code></td>
<td ng-bind=item.name></td>
</tr>
</script>
$scope.assetshow = function () {
$scope.asse = true;
$scope.pers = false;
$scope.loca = false;
$scope.bigTotalItems = $scope.copy.data.assets.length;
$scope.book = PageItems($scope.copy.data.assets, 17);
console.log($scope.bigCurrentPage)
$scope.row = { item1: "item.num", item2: "item.name", item3: "item.category", item4: "item.location.name", item5: "item.toloc.name", item6: "item.department", item7: "item.adm", item8: "item.person.name" };
$scope.head = '<th>Asset code</th><th>Asset name</th><th>Category</th>'
+ '<th>Location</th><th>Department</th><th>Administration</th><th>Person in charge</th>';
$scope.activeTable = "assets.html";
},
$scope.locationshow = function () {
$scope.asse = false;
$scope.pers = false;
$scope.loca = true;
//produce pages.
$scope.bigTotalItems = PageItems($scope.copy.data.locations);
$scope.book = PageItems($scope.copy.data.locations, 17);
$scope.head = '<th>Kods</th><th>Nosaukums</th>';
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.activeTable = "locations.html";
},
$scope.personshow = function () {
$scope.asse = false;
$scope.pers = true;
$scope.loca = false;
//produce pages.
$scope.bigTotalItems = PageItems($scope.copy.data.persons);
$scope.book = PageItems($scope.copy.data.persons, 17);
$scope.head = '<th>Kods</th><th>Nosaukums</th></tr>';
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.activeTable = "persons.html";
};
By changing activeTable string value table content changes.
DEMO: plnkr

Dragging a table column using HTML5 and AngularJS

http://jsfiddle.net/asutosh/82qum/
<div ng-app='myApp'>
<div ng-controller="myCtrl">
<table border="4">
<thead>
<th ng-repeat="hd in heads">
<div draganddrop drag="handleDrag()">{{hd}}</div>
</th>
</thead>
<tr ng-repeat="row in myData">
<td ng-repeat="hd in heads">
{{row[hd]}}
</td>
</tr>
</table>
</div>
Here is the JS:
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',function($scope){
$scope.handleDrag=function()
{
}
$scope.heads=['name','age','company','tech'];
$scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
{ name:'Rayn',age:30,company:'XYZ',tech:'.net'}]
});
myApp.directive('draganddrop',function(){
return{
scope:{
drag:'&'
},
link: function(scope, element) {
// this gives us the native JS object
var el = element[0];
el.draggable=true;
el.addEventListener(
'dragstart',
function(e) {
e.dataTransfer.effectAllowed = 'move';
// this.classList.add('drag');
return false;
},
false
);
el.addEventListener(
'dragend',
function(e) {
this.classList.remove('drag');
return false;
},
false
);
}
};
});
In the above fiddle I want to create a table having column reordering, I am able to set the column header to draggable however while dragging only the header's image is getting dragged, I want the the image of the whole column should come as the dragging image, any suggestion on that will be helpful.
The following solution works with Chrome's latest version, and this solution is implemented using AngularJS 1.4 version:
The change in the code is:
var headerElem=e.target.closest('th');
var textOfHeader=angular.element(headerElem).find("a");
scope.$apply(function() {
scope[dropfn](data, textOfHeader[0]);
});
http://plnkr.co/VDygHR
If you want to use a plugin instead of implementing it yourself you can choose from:
http://ng-table.com/
http://ui-grid.info/
http://lorenzofox3.github.io/smart-table-website/
http://ekokotov.github.io/object-table/
They all support column reorder and a lot of other features, I believe there are a lot of other solutions around.
http://jsfiddle.net/asutosh/82qum/142/
Following is HTML Code:
<div ng-app='myApp'>
<div ng-controller="myCtrl">
<table ng-hide={{dragStart}} id="hidtable" border="4" >
<thead>
<th>{{dragHead}}</th>
</thead>
<tr ng-repeat="row in myData">
<td>{{row[dragHead]}}</td>
</tr>
</table>
<div class='dragstyle' id="coverup"></div>
<table border="4">
<thead>
<th ng-repeat="hd in heads">
<div draganddrop drag="handleDrag">{{hd}}</div>
</th>
</thead>
<tr ng-repeat="row in myData">
<td ng-repeat="hd in heads">
{{row[hd]}}
</td>
</tr>
</table>
</div>
</div>
Following is the CSS:
.dragstyle{
background: white;
width:200px;
color:white;
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
#hidtable{
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
Following is the JS:
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',function($scope){
$scope.handleDrag=function(columnName)
{
$scope.dragHead=columnName;
};
$scope.dragHead='name';
$scope.heads=['name','age','company','tech'];
$scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
{name:'Rayn',age:30,company:'XYZ',tech:'.net'}]
});
myApp.directive('draganddrop',function(){
return{
scope:{
drag:'='
},
link: function(scope, element,attrs) {
var el = element[0];
el.draggable=true;
el.addEventListener(
'dragstart',
function(e) {
e.dataTransfer.effectAllowed = 'move';
var columnName=e.target.innerHTML;
scope.$apply(function(self){
console.log(self);
scope.drag(columnName);
});
e.dataTransfer.setDragImage(document.getElementById('hidtable'), 0, 0);
;
return false;
},
false
);
el.addEventListener(
'dragend',
function(e) {
this.classList.remove('drag');
return false;
},
false
);
}
};
});
So this way I have created a box with width of 200px and having background color as white, under that the 'hidetable' element is present, so it's visible to the browser but not to the user.
When the drag event occurs at any column head element, the 'hidetable' element is set as the drag image.
This drag'n'drop library will do it for you:
https://github.com/lorenzofox3/lrDragNDrop
Just include it in your app, and make your <th> say this:
<th lr-drag-src="headers" lr-drop-target="headers" ng-repeat="hd in heads" >

Resources