The pagination page numbers looks weird and lengthy. I want to display only some of the page numbers in frontend. my code It's working ok, but not good when there's large numbers of pages. so i'm using twbsPagination in function renderPagination. when i run my code i'm getting the error Uncaught TypeError: $(...).twbsPagination is not a function. twbsPagination source is script:src pagination.js. but when i run twbsPagination separate without any function it's working fine. how can i run twbsPagination with my code?
index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
<script src="homer/vendor/jquery/dist/jquery.min.js"></script>
<script src="desk/vendor/pagination/pagination.min.js"></script>
<script src="desk/components/approved2.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody id="approvedList">
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination"></ul>
</nav>
index.js
const localURL = "http://localhost:8000/"
// output Html
const Story = document.querySelector('#approvedList');
const pagination = document.querySelector('.pagination');
$(function () {
var page = 1,
records = 1,
totalRecords = 0,
search = '';
// Run on page load
fetchData();
setInterval(fetchData, 2000);
// data filtering
$("#search-input").keyup(function (e) {
let value = e.target.value
fetchData(search = value);
});
// Show Records limits
$("#records").click(function (e) {
let value = e.target.value
fetchData(records = value);
});
// Previous Page
$('[aria-label="Previous"]').click(function () {
if (page > 1) {
page--;
}
fetchData();
});
// Next page
$('[aria-label="Next"]').click(function () {
if (page * records < totalRecords) {
page++;
}
fetchData();
});
// data fetching from API
function fetchData() {
$.ajax({
url: "http://localhost:8000/api/approved/",
type: "GET",
data: {
page: page,
records: records,
search: search
},
success: function (res) {
totalRecords = res.count
Story.innerHTML = '';
res.results.map((object) => {
Story.innerHTML +=
`<tr>
<td> ` + object.id + `</td>
<td>${object.id}` + object.title + `</td>
</tr>`;
})
Pagination();
}
})
}
function Pagination() {
// let pagesNumbers = Math.ceil(totalRecords / records);
let pagesNumbers = Math.ceil(totalRecords / records);
$('#pagination').twbsPagination({
totalPages: pagesNumbers,
visiblePages: 5,
onPageClick: function (event, page) {
$('#page-content').text('Page ' + page);
}
});
}
})
You cannot add twice the jQuery library.
I don't know the pagination.min.js and approved2.js libraries but I know you can add the twbsPagination as follow:
<script src="https://cdnjs.cloudflare.com/ajax/libs/twbs-pagination/1.4.2/jquery.twbsPagination.min.js"></script>
Moreover, this line is wrong:
let pagesNumbers = Math.ceil(totalRecords / records);
pagesNumbers needs to be at least 1.
The snippet with your code:
const fakeData = {
data: [{
row: 1,
name: 'a'
}, {
row: 2,
name: 'b'
}, {
row: 3,
name: 'c'
}, {
row: 4,
name: 'd'
}, {
row: 5,
name: 'e'
}, {
row: 6,
name: 'f'
}, {
row: 7,
name: 'g'
}],
totalRecords: 7
};
// output Html
const Story = document.querySelector('#approvedList');
const pagination = document.querySelector('.pagination');
$(function () {
var page = 1,
records = 1,
totalRecords = 0,
search = '';
// Run on page load
fetchData();
// data fetching from API
function fetchData() {
totalCount = fakeData.totalCount;
Story.innerHTML = '';
fakeData.data.slice((page - 1) * records, page * records).map((object) => {
Story.innerHTML +=
`<tr >
<td>${object.row}</td>
<td>${object.name}</td>
</tr >
`;
})
renderPagination();
}
function renderPagination() {
let pagesNumbers = Math.ceil(totalRecords / records) || 1;
$('.pagination').twbsPagination({
totalPages: pagesNumbers,
visiblePages: 5,
onPageClick: function (event, page) {
$('#page-content').text('Page ' + page);
}
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twbs-pagination/1.4.2/jquery.twbsPagination.min.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody id="approvedList">
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination"></ul>
</nav>
Related
I have an AJAX function that returns this json array when the page loads.
{
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"oyWEgmEAMENvr8zTGd6gqCMyVPS2":{
"Highscore":800,
"username":"orange"
},
"acjqiNwlxqfZsSaRBYKoaVOqomh1":{
"Highscore":700,
"username":"white"
},
"IhnWPgRT1gVLrxLhD6ZvNn9migX2":{
"Highscore":"700",
"username":"RED"
},
"ZeGUezY38gcHX0NXaommRPR65cR2":{
"Highscore":600,
"username":"blue"
},
"A41jXf0wmQQqzUlAu6WAuaf04Nk2":{
"Highscore":600,
"username":"mary"
},
"Vm4jMNI83mSFdN4wYbfJ6C7ecEH3":{
"Highscore":500,
"username":"green"
},
"PtTdYXIWYAeMOrIPE8FBN66F9L32":{
"Highscore":400,
"username":"gray"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":300,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
}
what I want is to append only the high score and the username but not the uid into the table so it would populate the table once the page loads.
<table class="table table-borderless table-dark table-striped" id="records_table">
<tr>
<th style="text-align: center;">Rank</th>
<th style="text-align: center;">Username</th>
<th style="text-align: center;">Highscore</th>
</tr>
</table>
I tried each loop but I can't get it to work, any help is appreciated.
var obj ={
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":1200,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
}
var res = Object.keys(obj).map((data)=>{
var innerdata = obj[data];
var score = innerdata.Highscore;
var username = innerdata.username;
return [score,username]
})
var result = res.sort((a,b)=> b[0]-a[0])
var final = Object.keys(result).map((rank)=>{
var Rank =Number(rank)+1;
var score = result[rank][0];
var name = result[rank][1]
document.querySelector('table > tbody').innerHTML += `
<tr><td>${Rank}</td><td>${name}</td><td>${score}</td></tr>`;
})
It is simple. You just need to iterate over each object.
Like this:
const data = {
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"oyWEgmEAMENvr8zTGd6gqCMyVPS2":{
"Highscore":800,
"username":"orange"
},
"acjqiNwlxqfZsSaRBYKoaVOqomh1":{
"Highscore":700,
"username":"white"
},
"IhnWPgRT1gVLrxLhD6ZvNn9migX2":{
"Highscore":"700",
"username":"RED"
},
"ZeGUezY38gcHX0NXaommRPR65cR2":{
"Highscore":600,
"username":"blue"
},
"A41jXf0wmQQqzUlAu6WAuaf04Nk2":{
"Highscore":600,
"username":"mary"
},
"Vm4jMNI83mSFdN4wYbfJ6C7ecEH3":{
"Highscore":500,
"username":"green"
},
"PtTdYXIWYAeMOrIPE8FBN66F9L32":{
"Highscore":400,
"username":"gray"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":300,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
};
for (const key in data) {
const {Highscore, username, rank = "???"} = data[key];
document.querySelector('table > tbody').innerHTML += `
<tr><td>${rank}</td><td>${username}</td><td>${Highscore}</td></tr>`;
}
<table>
<thead>
<th style="text-align: center;">Rank</th>
<th style="text-align: center;">Username</th>
<th style="text-align: center;">Highscore</th>
</thead>
<tbody></tbody>
</table>
learning javascript by doing (beginner), here i have a table where is 'animals' and 'persons' want to know is there a way to reset table data back to 'Animal' after selecting data from select box ? i thought by calling the whole thing again inside onclick would do the trick but...
my code :
function myFunction() {
paivitys()
}
function paivitys(data, arvvoja) {
console.log(data);
//----
if (data.hasOwnProperty("animal")) {
document.getElementById("1name").innerHTML = data.animal;
} else {
document.getElementById("1name").innerHTML = data.person;
document.getElementById("1name1").innerHTML = 'person';
}
//----
if (data.hasOwnProperty("animal2")) {
document.getElementById("2name").innerHTML = data.animal2;
} else {
document.getElementById("2name").innerHTML = data.person2;
document.getElementById("2name1").innerHTML = 'person';
}
//-----
document.getElementById("id").innerHTML = data.id;
}
function paivitaselekt(data, arvvoja) {
for (var i = 0; i < data.length; i++) {
var select = document.getElementById("Select");
var option = document.createElement("option");
arvvoja.forEach((value) => {
option.textContent += data[i][value] + " ";
});
select.appendChild(option);
}
}
data = {
"animal": "tiger",
"animal2": "lion",
"id": "54321",
"dole": {
"Key": "fhd699f"
}
}
paivitys(data);
let kokoarray;
data = [{
"person": "kaka",
"person2": "julle",
"id": "9874",
},
{
"person": "Ronaldo",
"person2": "jussi",
"id": "65555",
}
]
kokoarray = data;
paivitaselekt(data, ["person", "id"]);
document.getElementById("Select").addEventListener("change", function(event) {
const valittutunnsite = event.target.value.split(" ")[1];
const valittutieto = kokoarray.filter((data) => data.id === valittutunnsite)[0];
paivitys(valittutieto);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous" />
<div class="container">
<table class="table ">
<thead>
<tr>
<th style="width: 25%;" id="1name1" class="table-primary">Animal</th>
<th style="width: 25%;" id="2name1" class="table-primary">Animal</th>
<th style="width: 25%;" class="table-primary">id</th>
</tr>
</thead>
<tbody>
<th id="1name"></th>
<th id="2name"></th>
<th id="id"></th>
</tbody>
</table>
<select id="Select" name="name"></select>
<button onclick="myFunction()">Reset</button>
</div>
Works this.
let animals
let animalCols = ['Animal', 'Animal 2']
let peopleCols = ['Person', 'Person 2']
function myFunction() {
paivitys(animals, animalCols)
}
function paivitys(data, arvvoja) {
console.log(data);
//----
if (data.hasOwnProperty("animal")) {
document.getElementById("1name").innerHTML = data.animal;
} else {
document.getElementById("1name").innerHTML = data.person;
}
//----
if (data.hasOwnProperty("animal2")) {
document.getElementById("2name").innerHTML = data.animal2;
} else {
document.getElementById("2name").innerHTML = data.person2;
}
document.getElementById("1name1").innerHTML = arvvoja[0];
document.getElementById("2name1").innerHTML = arvvoja[1];
//-----
document.getElementById("id").innerHTML = data.id;
}
function paivitaselekt(data, arvvoja) {
for (var i = 0; i < data.length; i++) {
var select = document.getElementById("Select");
var option = document.createElement("option");
arvvoja.forEach((value) => {
option.textContent += data[i][value] + " ";
});
select.appendChild(option);
}
}
animals = {
"animal": "tiger",
"animal2": "lion",
"id": "54321",
"dole": {
"Key": "fhd699f"
}
}
paivitys(animals, animalCols);
let kokoarray;
people = [{
"person": "kaka",
"person2": "julle",
"id": "9874",
},
{
"person": "Ronaldo",
"person2": "jussi",
"id": "65555",
}
]
kokoarray = people;
paivitaselekt(kokoarray, ["person", "id"]);
document.getElementById("Select").addEventListener("change", function(event) {
const valittutunnsite = event.target.value.split(" ")[1];
const valittutieto = kokoarray.filter((data) => data.id === valittutunnsite)[0];
paivitys(valittutieto, peopleCols);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous" />
<div class="container">
<table class="table ">
<thead>
<tr>
<th style="width: 25%;" id="1name1" class="table-primary">Animal</th>
<th style="width: 25%;" id="2name1" class="table-primary">Animal</th>
<th style="width: 25%;" class="table-primary">id</th>
</tr>
</thead>
<tbody>
<th id="1name"></th>
<th id="2name"></th>
<th id="id"></th>
</tbody>
</table>
<select id="Select" name="name"></select>
<button onclick="myFunction()">Reset</button>
</div>
I updated the code:
set columns
let animalCols = ['Animal', 'Animal 2']
let peopleCols = ['Person', 'Person 2']
udpate data
paivitys(animals, animalCols)
and
function paivitys(data, arvvoja) {
...
document.getElementById("1name1").innerHTML = arvvoja[0];
document.getElementById("2name1").innerHTML = arvvoja[1];
//...
}
Your reset button calls the function:
function myFunction() {
paivitys()
}
Which calls the paivitys function with no arguments.
function paivitys(data, arvvoja) {
The function takes data as its first argument, but you are not passing any variable to it.
This line is failing:
if (data.hasOwnProperty("animal")) {
Because data is undefined.
But as well as this, you are defining your data using animals, and then later changing the data to contain people. So the animals data is lost. You need to use a different variable to store people data.
I am using smart admin theme.
I am trying to implement data table but it's show the error
ement.DataTable is not function
my console shows the following error
ERROR TypeError: element.DataTable is not a function
table.ts file code is given below
ngOnInit() {
setTimeout(()=>{this.render()},500);
}
render() {
let element = $(this.el.nativeElement.children[0]);
let options = this.options || {};
let toolbar = "";
if (options.buttons) toolbar += "B";
if (this.paginationLength) toolbar += "l";
if (this.columnsHide) toolbar += "C";
if (typeof options.ajax === "string") {
let url = options.ajax;
options.ajax = {
url: "./../../assets/datatables.standard.json"
// complete: function (xhr) {
//
// }
};
}
options = $.extend(options, {
dom:
"<'dt-toolbar'<'col-xs-12 col-sm-6'f><'col-sm-6 col-xs-12 hidden-xs text-right'" +
toolbar +
">r>" +
"t" +
"<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
oLanguage: {
sSearch:
"<span class='input-group-addon'><i class='glyphicon glyphicon-search'></i></span> ",
sLengthMenu: "_MENU_"
},
autoWidth: false,
retrieve: true,
responsive: true,
initComplete: (settings, json) => {
element
.parent()
.find(".input-sm")
.removeClass("input-sm")
.addClass("input-md");
}
});
console.log("_dataTable");
console.log(element);
const _dataTable = element.DataTable(options);
if (this.filter) {
// Apply the filter
element.on("keyup change", "thead th input[type=text]", function() {
_dataTable
.column(
$(this)
.parent()
.index() + ":visible"
)
.search(this.value)
.draw();
});
}
if (!toolbar) {
element
.parent()
.find(".dt-toolbar")
.append(
'<div class="text-right"><img src="assets/img/logo.png" alt="SmartAdmin" style="width: 111px; margin-top: 3px; margin-right: 10px;"></div>'
);
}
if (this.detailsFormat) {
let format = this.detailsFormat;
element.on("click", "td.details-control", function() {
var tr = $(this).closest("tr");
var row = _dataTable.row(tr);
if (row.child.isShown()) {
row.child.hide();
tr.removeClass("shown");
} else {
row.child(format(row.data())).show();
tr.addClass("shown");
}
});
}
}
table.html file code is given below
<table class="dataTable responsive {{tableClass}}" width="{{width}}">
<ng-content></ng-content>
</table>
app.component.ts code is given below
public REST_ROOT = 'https://jsonplaceholder.typicode.com';
options = {
dom: "Bfrtip",
ajax: (data, callback, settings) => {
this.http.get(this.REST_ROOT + '/posts')
.pipe(
map((data: any)=>(data.data || data)),
catchError(this.handleError),
)
.subscribe((data) => {
console.log('data from rest endpoint', data);
callback({
aaData: data.slice(0, 100)
})
})
},
columns: [
{ data: "userId" },
{ data: "id" },
{ data: "title" },
{ data: "body" },
]
};
constructor(private http: HttpClient) { }
ngOnInit() {}
private handleError(error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
app.component.html code is given below
<div color="blueDark">
<header>
<span class="widget-icon"> <i class="fa fa-table"></i> </span>
<h2>Datatables Rest Demo</h2>
</header>
<div>
<div class="widget-body no-padding">
<app-table [options]="options" tableClass="table table-striped table-bordered table-hover">
<thead>
<tr>
<th [style.width]="'8%'" data-hide="mobile-p">User ID</th>
<th [style.width]="'8%'" data-hide="mobile-p">Post ID</th>
<th>Title</th>
<th data-class="expand">Body</th>
</tr>
</thead>
<tfoot>
<tr>
<th>User ID</th>
<th>Post ID</th>
<th>Title</th>
<th>Body</th>
</tr>
</tfoot>
</app-table>
</div>
</div>
</div>
Trying to make a load more button, when user click it add 10 more item into the page. But the button code is not running smoothly... I still see all items in the page, and also there is no error in the console too.. of course button is not working.
Additionally, trying to make it run with the filter function.. Thank you for any example, help.
data() {
return {
estates:[],
moreEstates: [],
moreEstFetched: false,
}
},
mounted() {
axios.get('/ajax').then((response) => {
this.estates = response.data
this.insertMarkers();
});
},
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
this.moreEstates = response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr v-for="estate in one">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
As #pyriand3r pointed out that the axios request is async you can do something like this with async/await without modifiyng too much the code.
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then(async (response) => {
this.moreEstates = await response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
// Also you cant splice a boolean only arrays.
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
See: Async/await in JavaScript
Made some changes to your code, read the comment to understand.
But this is the same as the last post you added.
data() {
return {
visible:true ,
estates:[],
moreEstates: [],
moreEstFetched: false,
size: 10,
selectedPage:0,
init: false,
}
},
updated: function () { // when loaded, trigger only once
if (!this.init) {
this.handleButton();
this.init = true;
}
},
mounted() {
// why is this here, you should only have handleButton to load the data
// axios.get('/ajax').then((response) => {
// this.estates =this.filterData(response.data)
// this.insertMarkers();
// this.showMore();
// });
},
methods: {
filterData: function (data) {
let filteredStates = data.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
showMore: function(){
if (Math.ceil( this.moreEstates.length / this.size) <= this.selectedPage +1 ){
this.selectedPage++;
// using slice is better where splice changes the orginal array
var nextEsts = this.moreEstFetched.slice((this.selectedPage * this.size), this.size);
this.estates.push(nextEsts);
}else this. visible= true; // hide show more
},
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
// filter the whole data at once
this.moreEstates = this.filterData(response.data);
this.moreEstFetched = true;
// not sure what this is, i moved it here
this.insertMarkers();
this.showMore();
});
}else this.showMore();
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr v-for="estate in estates">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button v-if="visible" class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
actually, I am not sure it is the best way but, tried much more simplest way to achieve it...
data() {
return {
moreEstates: 10,
}
},
<table class="table table-hover">
<tbody>
<tr v-if="moreIndex < one.length" v-for="moreIndex in moreEstates">
<td><img id="image" :src="one[moreIndex].image" alt=""></td>
<td>{{one[moreIndex].building_name}}</td>
<td>{{one[moreIndex].address}}</td>
<td>{{priceSep(one[moreIndex].price)}} 万円</td>
<td>{{one[moreIndex].rooms}}</td>
<td>{{xtendSep(one[moreIndex].extend)}} m²</td>
<td>{{one[moreIndex].m2_price}}</td>
<td><a :href="/pages/+one[moreIndex].id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="moreEstates += 10">次の10件を見る</button>
I am new to react and trying to build a table component that changes based on what is passed in for headers and rows.
I have been following the fb react tutorials and I have hit a road block I have looked on here and did some changes but nothing is working.
Here is my HTML page that gets the generated content.
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="IE=10; IE=9; IE=8; IE=7; IE=EDGE" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.4.1/css/bootstrap-datepicker3.css"/>
<link rel="stylesheet" type="text/css" href="/vendor/twbs/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/vendor/etdsolutions/sweetalert/sweetalert.css?<?= assetCacheQueryStr() ?>" />
<link rel="stylesheet" type="text/css" href="/lib/jquery-ui-1.11.4/jquery-ui.css">
<link rel="stylesheet" type="text/css" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.3/css/bootstrap-select.min.css">
<!-- Javascript -->
<script src="https://unpkg.com/react#15.3.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#15.3.2/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-core#5.8.38/browser.min.js"></script>
<script src="https://unpkg.com/jquery#3.1.0/dist/jquery.min.js"></script>
<script src="https://unpkg.com/remarkable#1.6.2/dist/remarkable.min.js"></script>
<script src="/vendor/etdsolutions/sweetalert/sweetalert.min.js?<?= assetCacheQueryStr()?>"></script>
<script src="/vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.3/js/bootstrap-select.min.js"></script>
<script src="/lib/sorttable.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.4.1/js/bootstrap-datepicker.min.js"></script>
<title>React</title>
</head>
<body>
<div id="loadboardContainer"></div>
<!-- Import the table react setup. -->
<script type="text/babel" src="test.js"></script>
</body>
</html>
Now I have the external react script in the test.js file which is this.
var Table = React.createClass({
getInitialState: function() {
return {
results: [],
columns: []
}
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function(result) {
result = JSON.parse(result);
this.setState({
results: result['resultRows'],
columns: $.makeArray(result['resultCols'])
});
}.bind(this));
},
componentWillUnmount: function(){
this.serverRequest.abort();
},
render: function() {
// Set array for rows.
var rows = [];
var header = [];
this.state.columns.map(function(cols) {
header.push(<TableColumns data={cols.cols} key={cols.id} />);
});
this.state.results.map(function(result) {
rows.push(<TableRow data={result.rows} key={result.id} />);
});
// Loop through head to get columns.
/*this.props.columns.forEach(function(cols) {
header.push(<TableColumns data={cols.cols} key={cols.id} />);
});
// Loop through the returned rows and display.
this.props.results.forEach(function(result) {
rows.push(<TableRow data={result.rows} key={result.id} />);
});*/
// Return the table.
return (
<table className="table table-condensed">
<thead>
{header}
</thead>
<tbody>
{rows}
</tbody>
</table>
);
}
});
// Set up columns
var TableColumns = React.createClass({
render: function() {
var colNodes = this.props.data.map(function(col, i){
return (
<th key={i}>{col}</th>
);
});
return (
<tr>
{colNodes}
</tr>
);
}
});
// Set up row
var TableRow = React.createClass({
render: function() {
var rowNodes = this.props.data.map(function(row, i){
return (
<td key={i}>{row}</td>
);
});
return (
<tr>
{rowNodes}
</tr>
);
}
});
var futureContainer = document.getElementById('loadboardContainer');
ReactDOM.render(<Table source="getTableValues.php" />, futureContainer);
As you can see I have the commented out part of what used to be the props calls to the table. Now that I am trying to get the information from another file it looks like on here I have to use state.
On the other file this is what I have. Its just an array of array to return data before I actually query the stuff.
<?php
// Start the session.
session_start();
// Set Variables.
$returned = array(); // Returns results
$returned['resultRows'][0] = array();
$returned['resultRows'][0]['id'] = 10221;
$returned['resultRows'][0]['rows'] = array("654221", "2016-03-26", "Customer 1", "98755/54622", "Carrier 1", "Driver 1", "2016-03-28", "TX - IN", "DRY", "1240", "", "", "This is a test note");
$returned['resultRows'][1] = array();
$returned['resultRows'][1]['id'] = 10223;
$returned['resultRows'][1]['rows'] = array("654221", "2016-03-26", "Customer 1", "98755/54622", "Carrier 2", "Driver 2", "2016-03-28", "TX - IN", "DRY", "1240", "", "", "This is a test note2");
$returned['resultCols']['id'] = 100;
$returned['resultCols']['cols'] = array("PO Number", "Load Date", "Customer(s)", "Customer PO", "Carrier", "Driver", "Delivery Date", "Lane", "Temp", "Weight", "Attention Date", "ND Date", "Notes");
echo json_encode($returned);
?>
I keep getting an error this.state.columns.map is not a function.
The same is true if I use this.props. So what am I doing wrong on this? I know how to make it work if I statically put in the data and insert that way on the since page but the call is not working.
You try to map a string at the beginning because of async $.get
replace this :
getInitialState: function() {
return {
results: '',
columns: ''
}
}
by this :
getInitialState: function() {
return {
results: [],
columns: []
}
}
EDIT TO MATCH PHP RETURN
var Table = React.createClass({
getInitialState: function() {
return {
results: [],
columns: []
}
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function(result) {
result = JSON.parse(result);
this.setState({
results: result['resultRows'],
columns: result['resultCols'].cols
});
}.bind(this));
},
componentWillUnmount: function(){
this.serverRequest.abort();
},
render: function() {
// Return the table.
return (
<table className="table table-condensed">
<thead>
<TableColumns data={this.state.columns} />
</thead>
<tbody>
{this.state.results.map(function(result) {
rows.push(<TableRow data={result.rows} key={result.id} />);
})}
</tbody>
</table>
);
}
});
// Set up columns
var TableColumns = React.createClass({
render: function() {
var colNodes = this.props.data.map(function(col, i){
return (
<th key={i}>{col}</th>
);
});
return (
<tr>
{colNodes}
</tr>
);
}
});
// Set up row
var TableRow = React.createClass({
render: function() {
var rowNodes = this.props.data.map(function(row, i){
return (
<td key={i}>{row}</td>
);
});
return (
<tr>
{rowNodes}
</tr>
);
}
});
var futureContainer = document.getElementById('loadboardContainer');
ReactDOM.render(<Table source="getTableValues.php" />, futureContainer);