I have this table with ng-repeat. All I want is to display one the value only once inside the ng-repeat.
My ng-repeat in tr
<tr ng-repeat="xx in results " >
<tr>{{xx.id}}</tr>
<tr>{{xx.invoicenumber}}</tr>
</tr>
Here's my table
ID
INVOICE#
1
112
1
113
1
114
2
115
2
116
Desired Output
ID
INVOICE#
1
112
113
114
2
115
116
#SprakenDude , Can you also share us the details about how and what is the structure of data you are receiving?
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr>
<td>Id</td>
<td>Invoice Number</td>
</tr>
<tr ng-repeat="xx in results " >
<td>{{printXXId(xx.id)}}</td>
<td>{{xx.invoicenumber}}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.preid=-1;
$scope.printXXId=function(id){
return $scope.preid==id?'':$scope.preid=id;
}
$scope.results=[
{
id:1,
invoicenumber:112
},
{
id:1,
invoicenumber:113
},
{
id:1,
invoicenumber:114
},
{
id:2,
invoicenumber:115
},
{
id:2,
invoicenumber:116
},
]
});
</script>
</body>
</html>
Related
After fiddling with my table layout I give up, I am looking for up to date and elegant way to sort this table layout with such numbers.
I tried this popular solution.
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"formatted_numbers-pre": function ( a ) {
a = (a===" ") ? 0 : a.replace( /[^\d\-\.]/g, "" );
return parseFloat( a );
},
"formatted_numbers-asc": function ( a, b ) {
return a - b;
},
"formatted_numbers-desc": function ( a, b ) {
return b - a;
}
});
jQuery(document).ready(function() {
jQuery('#mieszkaniaList').DataTable({
responsive: true,
"columnDefs": [
{ "type": "formatted_numbers", "targets": '_all'},
],
"language": {
"decimal": ",",
"thousands": " ",
"lengthMenu": "Pokaż _MENU_ mieszkań na stronę",
"zeroRecords": "Niestety dla tego zakresu nie znaleźliśmy pasujących mieszkań ...",
"info": "Strona _PAGE_ z _PAGES_",
"infoEmpty": "Niestety brak mieszkań...",
"processing": "Przygotowujemy mieszkania...",
"search": "Szukaj",
"paginate": {
"first": "Pierwsza",
"last": "Ostatnia",
"next": "Następna",
"previous": "Poprzednia"
},
"infoFiltered": "(z _MAX_ mieszkań)"
}
});
});
Nr
Area
level
nr2
Price
Price per m2
01A
10 m2
1
1
502 200 PLN
7 200 PLN za m2
02A
20 m2
2
2
1 502 200 PLN
10 200 PLN za m2
03A
90 m2
3
3
2 502 200 PLN
15 200 PLN za m2
04A
120 m2
4
4
202 200 PLN
5 200 PLN za m2
Your approach looks close to me, but I can suggest some changes:
In your case you only need the -pre function - you do not need the -asc and -desc functions. In fact there is a note in the documentation which states that you cannot combine usage of -pre with the other two functions:
Note that in DataTables 1.10 a pre-formatter cannot be used with custom -asc and -desc methods - to use custom ordering functions you cannot apply a pre-formatter. This limitation will be addressed in the next major version of DataTables.
If you use -pre to convert your numbers-plus-text to numbers-only values, then sorting will use the numbers-only values automatically - and the data will automatically be handled as numeric, not text.
You need to handle the fact that some of your data contains strings with numbers ("m2"). A very simple way to handle these is to replace all occurrences of m2 with nothing, before performing the regex replacement.
Here is a runnable demo:
$(document).ready(function() {
$.fn.dataTable.ext.type.order['formatted_numbers-pre'] = function ( a ) {
a = a.replaceAll("m2", "");
a = (a===" ") ? 0 : a.replace( /[^\d\-\.]/g, "" );
console.log( a ); // for debugging only
return parseFloat( a );
};
var table = $('#example').DataTable( {
"columnDefs": [
{ "type": "formatted_numbers", "targets": '_all'},
]
} );
} );
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Nr</th>
<th>Area</th>
<th>Level</th>
<th>nr2</th>
<th>Price</th>
<th>Price per m2</th>
</tr>
</thead>
<tbody>
<tr>
<td>01A</td>
<td>10 m2</td>
<td>1</td>
<td>1</td>
<td>502 200 PLN</td>
<td>7 200 PLN za m2</td>
</tr>
<tr>
<td>02A</td>
<td>20 m2</td>
<td>2</td>
<td>2</td>
<td>1 502 200 PLN</td>
<td>10 200 PLN za m2</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
There is a logging statement in the above code, so you can see what data the -pre function is generating.
Here I wrote A code which fetches data from API http://fcctop100.herokuapp.com/api/fccusers/top/recent and displays Data in Form Of Table Which Looks Like Below In My Case As You Can See is Repeating For Every
But I want To Make It Look Like
Here Is What I Did So Far
var MainBox = React.createClass({
render:function(){
return(
<App/>
);
}
});
var App = React.createClass({
//setting up initial state
getInitialState:function(){
return{
data:[]
};
},
componentDidMount(){
this.getDataFromServer('http://fcctop100.herokuapp.com/api/fccusers/top/recent');
},
//showResult Method
showResult: function(response) {
this.setState({
data: response
});
},
//making ajax call to get data from server
getDataFromServer:function(URL){
$.ajax({
type:"GET",
dataType:"json",
url:URL,
success: function(response) {
this.showResult(response);
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render:function(){
return(
<div>
<Result result={this.state.data}/>
</div>
);
}
});
var Result = React.createClass({
render:function(){
var result = this.props.result.map(function(result,index){
return <ResultItem key={index} user={ result } />
});
return(
<div>
{result}
</div>
);
}
});
var ResultItem = React.createClass({
render:function(){
var camper = this.props.user;
return(
<div className="row">
<div className="col-md-12">
<table className="table table-bordered">
<thead>
<tr>
<th className="col-md-4">UserName</th>
<th >Points In Last 30 Days</th>
<th>Points All Time</th>
</tr>
</thead>
<tbody>
<tr >
<td>{camper.username}</td>
<td>{camper.recent}</td>
<td>{camper.alltime}</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
});
ReactDOM.render(
<MainBox />,
document.querySelector("#app")
);
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>React Tutorial</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<div id="app"></div>
<script src="demo.js" type="text/babel"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
</body>
</html>
The following should list all your items as a single row in your table, and only give you one table. One tip is to not use the index as the key for your map function. It's better to use some natural key or identifier in your result, some kind of id that will enable React better comparison of the components. A blog post describing this and some documentation.
var Result = React.createClass({
render:function(){
var result = this.props.result.map(function(result,index){
return <ResultItem key={index} user={ result } />
});
return(
<div className="row">
<div className="col-md-12">
<table className="table table-bordered">
<thead>
<tr>
<th className="col-md-4">UserName</th>
<th >Points In Last 30 Days</th>
<th>Points All Time</th>
</tr>
</thead>
<tbody>
{result}
</tbody>
</table>
</div>
</div>
);
}
});
var ResultItem = React.createClass({
render:function(){
var camper = this.props.user;
return(
<tr >
<td>{camper.username}</td>
<td>{camper.recent}</td>
<td>{camper.alltime}</td>
</tr>
);
}
});
In vue.js how can you filter a table using mutiple filters that target a specific column on the table.
For example if I have two search fields name and age how can I bind them to search the respective columns on the table below. So if user enters a name in the name input it should only search for a name on the name column. If the user enters an age as well then it should form an and condition and search for an age in the age column. Currently the filters simply search the entire table.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>The Vast World of Vue.js</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
</head>
<body id="demo" class="container">
<input v-model="name" class="form-control" placeholder="search by name"><br>
<input v-model="age" class="form-control" placeholder="search by age">
<table class="table table-striped">
<thead>
<tr>
<th >
Name
</th>
<th >
Age
</th>
</thead>
<tbody>
<tr v-for="item in people | filterBy name | filterBy age">
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</tr>
</tbody>
</table>
<script src="http://vuejs.org/js/vue.js"></script>
<script>
new Vue({
el: '#demo',
name: '',
age: '',
data: {
people: [
{ name: 'John', age: 50 },
{ name: 'Jane', age: 22 },
{ name: 'Paul', age: 34 },
{ name: 'Kate', age: 15 },
]
}
});
</script>
</body>
</html>
Vue 2
Since we don't have filters anymore, you'd need to use a computed property.
So you can do something like:
{
data: {
people: [{ name: }],
age: 28,
name: 'bi',
}
computed: {
filteredPeople () {
const { name, age, people } = this
return this.people
.filter(person => person.name.toLowerCase().indexOf(name.toLowerCase()) > -1)
.filter(person => person.age === age)
},
},
}
Then you'd loop through filteredPeople instead of people
<tr v-for="person in filteredPeople">...</tr>
Vue 1
If you take a look at the second example in API documentation for filterBy you'll see the ability to limit it to a field.
You'd want something like:
item in people | filterBy name in 'name' | filterBy age in 'age'
Hi Friends i am trying to use knockoutjs on one of my web pages in mvc
razor. From the following ViewModel i am achieving the "ADD MORE"
functionality.But My Problem is that how can we achieve the following
functionality:
(1) The second dropdown should be invisible when the dropdown for
"Type of Tobacco" is selected to "Choose..."
(2)When we choose some other value (other than "Choose") second
dropdown should be populated containing value 1 to 10....
(3) When we select "Others" instead of drop down a textbox should
appear
HERE IS MY ATTEMPT:
<script src="#Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script type="text/html" id="ddlSelection">
<div><select></select> yrs.</div>
<div><input type="text" data-bind=""></input></div>
</script>
<div id="container">
#*<div data-bind="template:{name:'smoker'}"></div>*#
<table cellpadding="3" cellspacing="4">
<tbody data-bind="foreach: seats">
<tr>
<td>
Type of Tobacco/Nicotine consumed :
</td>
<td>
<select data-bind="options: $root.availabledrugs, value: Drug, optionsText: 'DrugName'"></select>
</td>
<td><select></select></td>
</tr>
<tr>
<td>
Quantity : <input data-bind="value: Name" />
</td>
<td>
Frequency : <select data-bind="options: $root.availablefrequency, value: Frequency, optionsText: 'frequency'"></select>
</td>
<td data-bind="text: FormatPrice"></td>
</tr>
</tbody>
</table>
<button data-bind="click:AddConsumption">Add New One</button>
</div>
<script type="text/javascript">
function setconsumption(name, initdrug,initfrequency) {
var self = this;
self.Name = name;
self.Drug = ko.observable(initdrug);
self.Frequency = ko.observable(initfrequency);
self.FormatPrice = ko.computed(function () {
return self.Drug().Price ? "$" + self.Drug().Price.toFixed(2) : "none";
});
}
function ConsumptionViewModel() {
var self = this;
self.availabledrugs = [{ "DrugName": "Choose...", "Price": 0 },
{ "DrugName": "Cigarettes", "Price": 10 },
{ "DrugName": "Cigar", "Price": 20 },
{ "DrugName": "Others", "Price": 30}];
self.availablefrequency = [{ "frequency": "Choose..." }, { "frequency": "freq1" }, { "frequency": "freq2"}];
self.seats = ko.observableArray(
[new setconsumption("", self.availabledrugs[0], self.availablefrequency[0])]);
self.AddConsumption = function () {
self.seats.push(new setconsumption("", self.availabledrugs[0], self.availablefrequency[0]));
};
}
ko.applyBindings(new ConsumptionViewModel());
</script>
Its hard to guess for me that what you are trying to achieve. But i think you are looking for visible binding in knockout.
The visible binding causes the associated DOM element to become hidden or visible according to the value you pass to the binding.
And second think should be the optionsCaption comes under options binding.
If you use optionsCaption with options binding than ko will prepend an extra option in the select list, which will be selected by default and contains value undefined.
By using this both i have create a fiddle according to your requirement. Check this:
Demo fiddle
Hope this is what you are looking for!
I created a table with five columns dynamically. Two (the second and third column) of the five columns should be editable on the fly. Each time when user click on one the editable table cell, JavaScript should catch the user input and send the data to the server in json format. I have problem catch the user input and send to the server. Please help. This is my sample code -
<!DOCTYPE html>
<html>
<head>
<title>Editable table</title>
<style type="text/css" title="currentStyle">
#import "css/table.css";
</style>
<script type="text/javascript" language="javascript" src="js/jquery.js"></script>
</head>
<body id="dt_example">
<div id="container">
<div class="full_width big">
Data table<br />
</div>
<div class="editab">
<table border="1">
<thead>
<tr>
<th>Contract Number</th>
<th>Current Status</th>
<th>Sale Balance Amount</th>
<th>Interest Rate</th>
<th>Discount</th>
</tr>
</thead>
<tbody>
<tr>
<td>00123</td>
<td onClick="editTableCell(this)">A30</td>
<td onClick="editTableCell(this)">$1,500.00</td>
<td>3.99 %</td>
<td>140</td>
</tr>
<tr>
<td>00234</td>
<td onClick="editTableCell(this)">B20</td>
<td onClick="editTableCell(this)">$2,500.00</td>
<td>3.99 %</td>
<td>160</td>
</tr>
<tr>
<td>00345</td>
<td onClick="editTableCell(this)">C40</td>
<td onClick="editTableCell(this)">$3,500.00</td>
<td>3.99 %</td>
<td>180</td>
</tr>
<tr>
<td>00456</td>
<td onClick="editTableCell(this)">A20</td>
<td onClick="editTableCell(this)">$4,500.00</td>
<td>3.99 %</td>
<td>200</td>
</tr>
<tr>
<td>00567</td>
<td onClick="editTableCell(this)">B30</td>
<td onClick="editTableCell(this)">$5,500.00</td>
<td>3.99 %</td>
<td>225</td>
</tr>
<tr>
<td>00678</td>
<td onClick="editTableCell(this)">C10</td>
<td onClick="editTableCell(this)">$6,500.00</td>
<td>3.99 %</td>
<td>250</td>
</tr>
<tr>
<td>00789</td>
<td onClick="editTableCell(this)">A30</td>
<td onClick="editTableCell(this)">$7,500.00</td>
<td>3.99 %</td>
<td>300</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
var SelectState = false;
var SelectedElement = null;
var TextInput = null;
var CellText = null;
var txt = "test";
var idcount = 0;
function editTableCell( e ){
if ( SelectState == false ){
SelectedElement = e;
CellText = e.innerHTML;
e.innerHTML = "";
var objInput = document.createElement("input");
objInput.type = 'text';
objInput.value = CellText;
objInput.id = "txt" + idcount++;
objInput.onkeypress = editTextBox;
objInput.size = 15;
TextInput = objInput;
e.appendChild(objInput);
SelectState = true;
} else if (e != SelectedElement) {
SelectedElement.innerHTML = CellText;
SelectState = false;
}
}
function editTextBox( e ){
if (navigator.appName == "Microsoft Internet Explorer"){
e = window.event;
key = e.keyCode;
}
else if (navigator.appName == "Netscape"){
key = e.which;
}
if ( key == 13 ){
SelectedElement.innerHTML = TextInput.value;
SelectState = false;
}
else if ( key == 27 ){
SelectedElement.innerHTML = CellText;
SelectState = false;
}
}
/* var attrName = "":
var attrValue = "";
if ($('#test1')
{
attrName= "editField01";
attrValue = $(#test1).val();
}
if ($('#test2')
{
attrName= "editField02";
attrValue = $(#test2).val();
}
if ($('#test3')
{
attrName= "editField03";
attrValue = $(#test3).val();
}
var values = '{"' + attrName + '":' + attrValue + '}';
$.ajax({
url: serverUrl + "/abc/contract/" + poolId,
async: false,
type: "PUT",
data: JSON.stringify(values),
dataType: 'json',
processData: false,
contentType: 'application/json',
success: showResponse(json) {
// TODO: What info is returned in the data structure?
showResponse;
},
error: function(err) {
alert("Failed to update the attribute");
htmlErrorDialog(err.responseText);
}
});*/
function showResponse(json) {
if(json.success){
// handle successful response here
alert("user input from column sent successfully!");
} else {
// handle unsuccessful response here
alert("user input fail to send. Please try again");
}
}
</script>
</body>
</html>
You're not actually passing the json data to showResponse:
success: showResponse(json) {
// TODO: What info is returned in the data structure?
showResponse;
},
Pass it along as so, and make sure that json is an actual object and that you don't need to parse it first:
success: function(json) {
// check that json is an actual object via an alert
// alert(json);
showResponse(json);
},
EDIT: Okay after a lot of working around, I have a simple test case for making the fields editable. Please note it uses jquery, and comments are inline:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!-- Date: 2011-05-10 -->
</head>
<body>
<form>
<table border="1">
<thead>
<tr>
<th>Contract Number</th>
<th>Current Status</th>
<th>Sale Balance Amount</th>
<th>Interest Rate</th>
<th>Discount</th>
</tr>
</thead>
<tbody>
<tr>
<!-- The "identifier" class makes it so we have an id
to pass to our ajax script so we know what to change -->
<td class="identifier">00123</td>
<td class="editable">A30</td>
<td class="editable">$1,500.00</td>
<td>3.99 %</td>
<td>140</td>
</tr>
</tbody>
</table>
</form>
<script type="text/javascript">
// bind our event handler to all td elements with class editable
$('td.editable').bind('click', function() {
// Only create an editable input if one doesn't exist
if(!$(this).has('input').length) {
// Get the text from the cell containing the value
var value = $(this).html();
// Create a new input element with the value of the cell text
var input = $('<input/>', {
'type':'text',
'value':value,
// Give it an onchange handler so when the data is changed
// It will do the ajax call
change: function() {
var new_value = $(this).val();
// This finds the sibling td element with class identifier so we have
// an id to pass to the ajax call
var cell = $(this).parent();
// Get the position of the td cell...
var cell_index = $(this).parent().parent().children().index(cell);
// .. to find its corresponding header
var identifier = $('thead th:eq('+cell_index+')').html();
//ajax post with id and new value
$(this).replaceWith(new_value);
}
});
// Empty out the cell contents...
$(this).empty();
// ... and replace it with the input field that has the value populated
$(this).append(input);
}
});
</script>
</body>