I have a basic html table where i need to have all the rows initially highlighted when the table is created. Also, if the user clicks the row it un highlights and clicked again highlights.
I have the click on a row, and it highlights. If you click again it un highlights.
I just need to initially highlight all rows possibly by ng-repeat. It also needs to release the highlighting when the row is clicked again and then highlight back. userData is just a line of text for each row
HTML
<table class="superusertable" cellpadding="5" cellspacing="0">
<tbody class="table-font">
<tr ng-init="" ng-repeat="source in userData"
ng-model="source.fromSourceID"
ng-class="{'sourcesSelected': source.sourcesSelected}"
ng-click="select(source)">
<td width="290px">
<div class="action-checkbox"; width="290px">{{source.fromSourceID}}
</div>
</td>
</tr>
</tbody>
</table>
angular
$scope.select = function(item) {
item.sourcesSelected ? item.sourcesSelected = false : item.sourcesSelected = true;
};
You can just add a function to the ng-init attribute on your tr. Just pass in your item and set it to true. Then like Aluan said in a comment, you can just make your ng-click function simpler by doing item.sourcesSelected = !item.sourcesSelected.
html
<table class="superusertable" cellpadding="5" cellspacing="0">
<tbody class="table-font">
<tr ng-init="init(source)"
ng-repeat="source in userData"
ng-model="source.fromSourceID"
ng-class="{'sourcesSelected': source.sourcesSelected}"
ng-click="select(source)">
<td width="290px">
<div class="action-checkbox"; width="290px">{{source.fromSourceID}}</div>
</td>
</tr>
</tbody>
</table>
angular
$scope.select = function(item) {
item.sourcesSelected = !item.sourcesSelected;
};
$scope.init = function(item) {
item.sourcesSelected = true;
}
On a side note, you can completely eliminate the ng-init and init function by setting item.sourcesSelected = true when you are retrieving your data.
There are too many errors i can observe.
ng-init="" not required
ternary operator is wrong you should do something following:
item.sourcesSelected = item.sourcesSelected ? false : true;
Related
I have a large table in WordPress, I need to change the order of the columns, but I have to do it manually every time, when I need. Is there any plugin out there, in which all table loads up and I drag and drop the whole column from there as my choice?
The website is here
Based on your question, i can give you a demo to show you how to move forward with your requirements.
Please check this UPDATED FIDDLE. As you requested we are using Dragtable js.
Once sorting is completed we checks each row of the table finds each column of the respective row and create a json tree structure.
Html
<table id="sort_table">
<thead>
<tr>
<th></th>
<th class="draggable">Col1</th>
<th class="draggable">Col2</th>
<th class="draggable">Col3</th>
<th class="draggable">Col4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row1</td>
<td>Data11</td>
<td>Data12</td>
<td>Data13</td>
<td>Data14</td>
</tr>
<tr>
<td>Row2</td>
<td>Data21</td>
<td>Data22</td>
<td>Data23</td>
<td>Data24</td>
</tr>
<tr>
<td>Row3</td>
<td>Data31</td>
<td>Data32</td>
<td>Data33</td>
<td>Data34</td>
</tr>
<tr>
<td>Row4</td>
<td>Data41</td>
<td>Data42</td>
<td>Data43</td>
<td>Data44</td>
</tr>
</tbody>
</table>
JS (UPDATED)
$(document).ready(function() {
$('#sort_table').dragtable({
dragaccept: '.draggable',
beforeStop: function() {
var tree = {};
var rows = [];
$('#sort_table tr').each(function() {
var col_count = 0;
var cols = [];
$(this).children().each(function() {
cols[col_count] = $(this).html();
col_count++;
});
rows.push(cols);
});
tree.data = rows;
var tree_json = JSON.stringify(tree); // use the variable to save to DB
console.log(tree_json);
}
});
});
You can save the variable tree_json to database (Call ajax to php and save to DB)
On each page load you could take the value from database to a variable and using json_decode to make the string a json object
$table_structure = ; // Code to take from db
$table_structure = json_decode($table_structure);
You can copy and paste json from console to check if its valid using JSONLint
I have a scenario to bind a html table using angular js. In my table i need to show an a tag based on another column value(Payment Status). If its fully paid no need to show the a tag, else need to show it for very next element. I am a new one in angular.
<table>
<thead>
<tr>
<th>Month</th>
<th>Installement</th>
<th>PaymentAmount</th>
<th>PaymentDate</th>
<th>Payment Status</th>
<th>Pay</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="row in rowCollection|orderBy:type:reverse|filter:searchKeyword|itemsPerPage:maxsize">
<td>{{row.Month}}</td>
<td>{{row.MonthlyInstallement}}</td>
<td>{{row.PaymentAmount}}</td>
<td>{{row.PaymentDate}}</td>
<td>{{row.PaymentStatus}}</td>
<td ng-if="row.PaymentStatus == 'UNPAID'">
Pay Online
</td>
<td ng-if="row.PaymentStatus == 'FULLY_PAID'">
</td>
</tr>
</tbody>
</table>
function bindFinanceDetails() {
var finUrl = baseurl + 'api/FinancialStatement/GetCarFinanceInfo';
var req = {
method: 'post',
data: {
LoginID: LoginID,
ContractNumber: 11170200669,
CustomerId: 2355898046
},
url: finUrl,
headers: {
RequestedPlatform: "Web",
RequestedLanguage: cookiePreferredLanguage,
Logintoken: $cookieStore.get('LoginToken'),
LoginId: LoginID
}
};
$http(req).then(function(response) {
var getData = response.data.FinanceList;
$scope.rowCollection = getData;
}, function(error) {
toastr.error($filter('translate')('Error Occured'));
});
}
A quite hacky solution will be something like the following (just showing you the needed change in the unpaid td element):
<td ng-if="row.PaymentStatus === 'UNPAID'" ng-show="$index === data.payOnlineIndex"
ng-init="data.payOnlineIndex = (!data.payOnlineIndex || (data.payOnlineIndex > $index)) ? $index : data.payOnlineIndex">
Pay Online
</td>
This way ng-init will run for all unpaid elements, setting the smallest index to the payOnlineIndex variable. ng-show will make sure to only show that one element that has the smallest index.
I encapsulate payOnlineIndex with a data object to keep a stable reference to it. This also requires the following addition to the controller code:
$scope.data = { payOnlineIndex: null };
See a working jsFiddle example here: https://jsfiddle.net/t3vktv0r/
Another option is running your filter and orderBy in the controller, searching for the first occurrence of an "unpaid" row, and marking that element for the "pay online" feature with some flag you can test with ng-if in your view.
this is driving me mad and hope someone might be able to help.
I have this React.Component:
var Vehicle = React.createClass({
ondragend: function(e) {
e.preventDefault();
// Logic here
console.log('onDragOver');
},
ondragstart: function(e){
e.preventDefault();
console.log('ondragstart');
},
render: function() {
that = this
var loads = this.props.truck.map(function(load , i){
load.truckid = i
return (
<tr key={i} draggable="true" dragstart={that.ondragstart} dragend={that.ondragend}>
<td>
{load.load_number}
</td>
<td>
{load.stops[0].location_name}
</td>
<td>
{load.stops[1].location_name}
</td>
</tr>
)
})
return (
<div className="panel panel-primary" draggable="true">
<VehiclePanelHeading vehicleNbr={this.props.vehicleNbr}></VehiclePanelHeading>
<div className="panel-body" >
<table className="table">
<tbody>
{loads}
</tbody>
</table>
</div>
</div>
)
}
});
As you can see, I am trying to make the s draggable. Unfortunetly, this won't work, even if I use the Chrome dev tools to manually add this into the html in the browser.
I have tried removing my link to Bootstrap incase this is something to do with the CSS rules, and also tried to render just a html table with no dynamic values.
I can't see how the code in this fiddle:
jsFiddle
Works by setting the draggable=true in the render function, but mine won't.
Thanks in advance for any help.
Edit
Added the dropEnd/Start handlers but no change.
Curiously, if I add draggable=true to the div.panel container, this is draggable whilst the containing s remain not.
Update
If I create a quick .html page with this table:
<table className="table">
<thead>
<tr>
<td>Name</td>
<td>Tangyness</td>
</tr>
</thead>
<tbody>
<tr draggable="true">
<td>Apple</td>
<td>4</td>
</tr>
<tr draggable="true">
<td>Orange</td>
<td>7</td>
</tr>
</tbody>
</table>
Then the desired draggble = true works on the table rows. However, if I paste this into the React render function:
return (
<div className="panel panel-primary" >
<VehiclePanelHeading vehicleNbr={this.props.vehicleNbr}></VehiclePanelHeading>
<div className="panel-body" >
<table className="table">
<thead>
<tr>
<td>Name</td>
<td>Tangyness</td>
</tr>
</thead>
<tbody>
<tr draggable="true">
<td>Apple</td>
<td>4</td>
</tr>
<tr draggable="true">
<td>Orange</td>
<td>7</td>
</tr>
</tbody>
</table>
</div>
</div>
)
Then suddenly, the 'draggability' is lost.
It should work, but you probably want to implement onDragOver event(s) too. Otherwise it will look like it doesn't work because you can drag your component, but don't have any legal place to drop it. onDragOver lets you specify if an element accepts dropping and which elements it accepts.
As you can see in the fiddle you linked there are onDragOver events which look something like this
onDragOver: function(e) {
e.preventDefault();
// Logic here
}
Calling e.preventDefault(); tells the browser that dropping is possible here. You can put the onDragOver event on any of your parent elements, or on the tr itself. You can read more about drop targets here. If you remove the onDragOver event from the jsFiddle you linked the code in the fiddle stops functioning too.
If you implement onDragOver you will be able to implement an onDrop event on your table that handles dropped tr elements.
Here is your code with the events implemented:
var Vehicle = React.createClass({
onDragOver: function(e) {
e.preventDefault();
// Logic here
console.log('onDragOver');
},
onDragStart: function(e){
e.dataTransfer.setData('id', 'setTheId');
console.log('onDragStart');
},
onDrop: function(e) {
console.log('onDrop');
var id = event.dataTransfer.getData('id');
console.log('Dropped with id:', id);
},
render: function() {
that = this;
var loads = this.props.truck.map(function(load , i){
load.truckid = i
return (
<tr key={i} draggable="true" onDragOver={that.onDragOver} onDragStart={that.onDragStart}>
<td>
{load.load_number}
</td>
<td>
{load.stops[0].location_name}
</td>
<td>
{load.stops[1].location_name}
</td>
</tr>
)
})
return (
<div>
<div className="panel-body" >
<table className="table" onDrop={this.onDrop}>
<tbody>
{loads}
</tbody>
</table>
</div>
</div>
)
}
});
Here is a jsFiddle of this: http://jsfiddle.net/kb3gN/10761/
The reason that the item doesn't seem to drag is you have e.preventDefault(); inside onDragStart function, which prevents it from showing the default dragging movement. Just remove that line, so it would look like this and it should work:
var Vehicle = React.createClass({
...
onDragStart: function(e){
// REMOVED THIS LINE
//e.preventDefault();
console.log('ondragstart');
},
...
I have a table which is shown below. When multiple data comes, it is shown properly but if a single data come, data isn't shown in the table. I suspect absence of brackets in single data..
Multiple Data Sample:
[{"Id":1,"Name":"Tomato soup","Category":"Groceries","Price":1.39},{"Id":2,"Name":"Yo-yo","Category":"Toys","Price":3.75},{"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}]
Single Data sample
{"Id":1,"Name":"Tomato soup","Category":"Groceries","Price":1.39}
Table and scripts:
<script type="text/javascript">
$(document).ready(function () {
function ProductViewModel() {
var self = this;
self.productData = ko.observable();
self.productId = ko.observable();
self.getAllProducts = function () {
$.get('/api/products', {}, self.productData);
};
self.getProductById = function () {
$.get('/api/products/' + self.productId(), {}, self.productData);
};
}
ko.applyBindings(new ProductViewModel());
});
</script>
<input id="txtId" type="text" data-bind="value: productId" />
<button id="btnGetSpeProduct" data-bind="click: getProductById">Get Product By Id</button>
<button id="btnGetProducts" data-bind="click: getAllProducts">Get All Products</button><br />
<table data-bind="with: productData">
<thead>
<tr>
<th>
Name
</th>
<th>
Category
</th>
<th>
Price
</th>
</tr>
</thead>
<tbody data-bind="foreach: $data">
<tr>
<td data-bind="text: Name">
</td>
<td data-bind="text: Category">
</td>
<td data-bind="text: Price">
</td>
</tr>
</tbody>
</table>
The foreach binding can accept either an array or an object specifying various options. In this case, Knockout thinks the object you're giving it is the latter. It will work if you use the object syntax and specify your data using the data option.
<tbody data-bind="foreach: {data: $data}">
Sample: http://jsfiddle.net/mbest/Dta48/
Yes - it has everything to do with the "absence of brackets in single data".
The one with brackets means that it's an array; a list which can can iterate (foreach).
The one without brackets means that it's an object; something which can be stored inside an array, but can not be iterated using foreach.
So, you want it to act like an array so you can iterate over the result. First step, you'll need to use an observableArray instead of observable:
self.productData = ko.observableArray();
Next, you'll need to push the data you $.get to that array, instead of directly binding them.
$.get('/api/products', function(data) {
// Iterate over the data variable, and use
// self.productData.push(ITEM)
// to add it to the array
});
That should do it - good luck!
use observableArray instead of observable
self.productData = ko.observableArray();
I have the below html table where the header on seperate table and content on another table. I have to sort the table when i click the header that are in another table.
I found so many javascript examples that are working only if the headers are in same table.Can any you guys give me with some examples related to my task?
<html>
<table >
<tr>
<th>Name</th>
<th>Salary</th>
</tr>
</table>
<table>
<tr>
<td>Fred</td>
<td>$12000.00</td>
</tr>
<tr>
<td>Kevin</td>
<td>$191200.00</td>
</tr>
</table>
</html>
If you add some classes to the columns so that the column cells and the associated header have the same class name, it's not too difficult to leverage those other existing JavaScript solutions.
As an example, I used this simple JQuery sorting function and created this JSFiddle demo.
I modified the HTML like this:
<html>
<table id="heading">
<tr>
<th class="name-col">Name</th>
<th class="salary-col">Salary</th>
</tr>
</table>
<table id="data">
<tr>
<td class="name-col">Fred</td>
<td class="salary-col">$12000.00</td>
</tr>
<tr>
<td class="name-col">Kevin</td>
<td class="salary-col">$191200.00</td>
</tr>
</table>
</html>
Notice that I game the header Name and all of the cells in that column the class name-col, and I did the same for the Salary header and cells with the class salary-col.
Then I used JQuery to add a click listener to the name-col header, which then triggered the sort function on the name-col cells:
$('th.name-col').click(function() {
$('td.name-col').sortElements(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
}, function(){ return this.parentNode; });
});
$('th.salary-col').click(function() {
$('td.salary-col').sortElements(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
}, function(){ return this.parentNode; });
});
In this example, sortElements is the function provided in the simple JQuery sorting function I linked above. I am not the author of it.
You will notice that this script will only sort once, however, since the direction of the comparator (>) is hard-coded. One quick-n-dirty way to implement logic to reverse this sort is like this:
var nameAsc = false;
var salaryAsc = false;
$('th.name-col').click(function() {
$('td.name-col').sortElements(function(a, b){
if (nameAsc) {
nameAsc = false;
return $(a).text() > $(b).text() ? 1 : -1;
} else {
nameAsc = true;
return $(a).text() < $(b).text() ? 1 : -1;
}
}, function(){ return this.parentNode; });
});
$('th.salary-col').click(function() {
$('td.salary-col').sortElements(function(a, b){
if(salaryAsc) {
salaryAsc = false;
return $(a).text() > $(b).text() ? 1 : -1;
} else {
salaryAsc = true;
return $(a).text() < $(b).text() ? 1 : -1;
}
}, function(){ return this.parentNode; });
});
Here the nameAsc and salaryAsc boolean variables are just a hackish way of allowing you to reverse the sort order. If it's ascending, it flips the boolean and the direction of the > in the comparator function. There's probably a more efficient way to do this, but I was just going for a quick-and-dirty example.
You're going to have a lot of problems with your two-table model, especially with sizing the columns. If you have longer data in the cells in the data table, your data columns will no longer line up with your header columns. I strongly suggest you use just a single table for both the header and the data.
use sorttable.js for sorting, it might give problem with column alignment while clicking on column head for sorting....
<script type="text/javascript" src="http://community.wikidot.com/local--files/howto:sortable-tables-js/sorttable.js"></script>
<style>
th, td{
padding: 3px;//important
}
</style>
<table class="sortable">
<tr><th>...</th></tr><tr><td>...</td</tr>
</table>