How to link table and pagination of Element UI? - pagination

I work on Vue.js and use the Element UI library.
I have an el-table containing a lot of data, and an el-pagination just below, but I don't manage to connect them.
For now, when I click on a different page of the pagination, the selected number of the pagination element changes but it doesn't update the data inside the table.
The data attributes in the table and in the pagination are set to the same variable ("tableData") but that doesn't work.
How can I connect these two elements ?
Here is my .vue code:
<el-table :data="tableData" stripe class="margin-top-5" style="width: 100%">
<el-table-column
align="center"
label="Favori"
sortable
min-width="75">
<template slot-scope="scope">
<i class="el-icon-star-off"></i>
</template>
</el-table-column>
<el-table-column
align="center"
prop="legal_name"
:label="$gettext('Raison sociale')"
sortable
min-width="120">
</el-table-column>
<el-table-column
align="center"
prop="address"
:label="$gettext('Adresse')"
sortable
min-width="180">
</el-table-column>
<el-table-column
align="center"
prop="city"
:label="$gettext('Ville')"
sortable
min-width="100">
</el-table-column>
<el-table-column
align="center"
prop="zip_code"
sortable
:label="$gettext('Code postal')"
min-width="110">
</el-table-column>
<el-table-column
align="center"
prop="country"
:label="$gettext('Pays')"
sortable>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
<el-row type="flex" justify="end" class="margin-top-5 margin-bottom-5 row-pagination">
<el-button v-translate size="small" class="show-all">Afficher tout</el-button>
<el-pagination
background
layout="->, prev, pager, next"
:total="1000"
:data="tableData">
</el-pagination>
</el-row>
In my .js associated file I have:
data() {
return {
tableData: [],
};
and :
created() {
api.getAddresses().then(addresses => {
this.tableData = addresses;
});
}
Thank you in advance for your help!

#Pearly Spencer,
You should have a local computed array which will hold the displayed data, something like:
In the html:
change tableData to displayData:
:data="displayData"
In the script:
computed: {
displayData() {
if (!this.tableData || this.tableData.length === 0) return [];
<!--- Your filter logic goes here --->
},
}
In other words, you should implement the displayData manually upon each change / click via handleCurrentChange
methods: {
handleCurrentChange(val) {
}
}
Good Luck!

Use this in your table :pagination.sync="pagination"
pagination: {
rowsPerPage: 5
}
<v-data-table
:headers="headers"
:items="tableValue"
:search="search"
class="elevation-1"
:pagination.sync="pagination"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.name }}</td>
<td>{{ props.item.Source }}</td>
<td>{{ props.item.Destination }}</td>
<td>{{ props.item.TripTime }}</td>
<td>{{ props.item.Status }}</td>
</template>
</v-data-table>
<div class="text-xs-center pt-2">
<v-pagination v-model="pagination.page" :length="pages">
</v-pagination>

Related

Multiple CustomJSHovers mapped to one field Bokeh

My Bokeh version is 2.3.1. I'm able to use the CustomJSHover to specify some javascript to execute on hover, with the input being a field (from a column data source). However, I'm trying to map different CustomJSHover's to the same field, and specify them differently in the HTML. An example snippet of what I have is
customjs = CustomJSHover(code="""///do some javascript here on the value var.""")
hover_points = HoverTool(tooltips="""
<div $x{custom} id=$index style="font-size:12px; font-family:arial; color:white; background:black; padding:10px;">
<div>
<span style="font-weight:bold;">Name:</span>
<span>#input_x{custom}</span>
</div>
""",
formatters={
'#input_x' :customjs
},
point_policy='snap_to_data')
This works great, but I want to have multiple custom formaters on input_x. If I try something like this
c1 = CustomJSHover(code="console.log(1);")
c2 = CustomJSHover(code="console.log(2);")
hover_highlight_line = HoverTool(tooltips="""
<div style="font-size:12px; font-family:arial; color:white; background:black; padding:10px;">
<table>
<tr>
<th style="text-align: center;">1</th>
<th style="text-align: center;">2</th>
</tr>
<tr>
<td style="padding:5px;">#input_x{c2}</td>
<td style="padding:5px;">#input_x{c1}</td>
</tr>
</table>
</div>
""",
formatters= {
'#input_x':c1,
'#input_x':c2
},
I only get the console log for c2. Is this possible to achieve? Thanks.
After sleeping on it, I finally found out how to do this.
Within the bracket, you can map a prefix to a formatter. This is in the docs, but the doc's don't tell you how to use it. Within the CustomJSCode argument, you can access this prefix (or if you want just specify the name) with the format variable.
c1 = CustomJSHover(code="""
if(format == 'agg'){ return //do something with agg}
else if(format == 'mean'){return //do something to get the mean}
""")
hover_highlight_line = HoverTool(tooltips="""
<div style="font-size:12px; font-family:arial; color:white; background:black; padding:10px;">
<table>
<tr>
<th style="text-align: center;">1</th>
<th style="text-align: center;">2</th>
</tr>
<tr>
<td style="padding:5px;">#input_x{agg}</td>
<td style="padding:5px;">#input_x{mean}</td>
</tr>
</table>
</div>
""",
formatters= {
'#input_x':c1,
},
If there is a better way to do this, please post an answer. Thanks.

Form does not validate. csrf_token included

I have following issue with validate_on_submit() method in my Flask application.
Quick overview what I have:
My form class is created dynamically based on input:
class EditUsers(FlaskForm):
submit = SubmitField('Submit')
def form_builder(roles_list):
class EditUsersForm(EditUsers):
pass
for role in roles_list:
if isinstance(role, tuple) and len(role) == 5:
if not role[2] and role[3]:
setattr(EditUsersForm, f'{role[0]}_{role[4]}_bool', BooleanField(label=role[0]))
setattr(EditUsersForm, f'{role[0]}_{role[4]}_date', SelectField('Expiration Period', choices=choices))
else:
raise IncorrectType
IncorrectType is custom Exception i prepared and choices are created using datetime in same file (This is irrelevant so I am not including it in code).
My route in flask app (simplified):
#### EDIT: I pasted the wrong route, POST and GET Methods are included###
#edit_users.route('/users', methods=['GET', 'POST'])
def users():
... # Some code there
form = form_builder(roles_to_form)
print(form.is_submitted())
print(form.validate())
print(form.validate_on_submit())
return render_template('edit_user.html',
data_dict=data_dict, # in data_dict i pass form fields names and some other data
form=form,
)
My template:
<!-- Some usual stuff goes there css js etc -->
<div >
<form class="form form-horizontal" method="post" role="form" style="margin: auto; text-align: center; width: 40%;">
{{ form.csrf_token() }}
<table class="table" align="center">
<thead>
<th>Role</th>
<th>Expiration Date</th>
<th>Give Role?</th>
</thead>
{% for field in data_dict['id_list'] %}
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]] }}
</td>
<td align="left">{{ form[field[0]] }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="3" align="center">{{ form.submit() }}</td>
</tr>
</table>
</form>
</div>
What is my issue?
When I am hitting my Submit button, is_submitted() returns True but validate() does not, thus I cannot use typical if form.validated_on_submit() as it returns False even when I submit my form.
I dig a little and spot something unusual. I used protected members of form attributes, to check whatever validate() function sees as input:
for name in form._fields:
print(name)
inline = getattr(form.__class__, 'validate_%s' % name, None)
print(inline)
The output (don't mind names of fields):
submit
None
Engineer_2_bool
None
Engineer_2_date
None
Operator_3_bool
None
Operator_3_date
None
Supervisor_4_bool
None
Supervisor_4_date
None
Guest_5_bool
None
Guest_5_date
None
csrf_token
None
I don't know why my form does not have validate_{name} attributes.
I made a working example from your code, and I ended up with the problem you described.
If I reversed well your code, it seems that form[field[1]] is your BooleanField or SelectField. So to render it in a template your have to use form[field[1]]() (can use render_field as well).
So :
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]] }}
</td>
<td align="left">{{ form[field[0]] }}</td>
</tr>
corrected into :
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]]() }}
</td>
<td align="left">{{ form[field[0]]() }}</td>
</tr>
https://flask.palletsprojects.com/en/1.1.x/patterns/wtforms/#forms-in-templates
As you are using a FlaskForm, in your template you have to replace {{ form.csrf_token() }} by {{ form.csrf_token }}
https://flask-wtf.readthedocs.io/en/stable/csrf.html#html-forms
[EDIT Does not make any difference]
[Edited after w8eight's comment]
The route is not authorized for POST (and the form makes a POST request as seen in <form class="form form-horizontal" method="post" [...].
So you have to change : #edit_users.route('/users', methods=['GET']) to #edit_users.route('/users', methods=['GET','POST'])
The problem was with type of data passed to choices of SelectField. I passed list of tuples with datetime.datetime to it. When changed type to str everything works smoothly.

How to use search filter in Angular for nested JSON object?

I am bringing data from my mongoose to display on my HTML table. I am able to filter a JSON object normally but unable to filter nested JSON object?
I have used "npm i ng2-search-filter --save " to import filter pipe, but this only works for the first level. Doesn't do filter for the nested JSON object.
My JSON object is:
{
packageName:test,
packagePrice:200,
userid:{
userName:John,
userAge: 27
}
}
<input type="text" class="form-control" [(ngModel)]="searchtext"
placeholder="Search">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Package Name</th>
<th scope="col">Package Price</th>
<th scope="col">Customer Name</th>
<th scope="col">Customer Age</th>
</tr>
</thead>
<tbody *ngFor="let use of user | filter:searchtext">
<tr class="table-active">
<td> {{use.packageName}}</td>
<td>{{use.packagePrice}}</td>
<td>{{use.userid.userName}}</td>
<td>{{use.userid.userAge}}</td>
</tr>
</tbody>
</table>
When I enter packageName and packagPrice in a textbox for search filter it filters out and shows me correct result, but on userName and userAge its not working.
Please help.
Thank you.
I solved this with by just installing the latest version ng2 search filter.
Run below command:
npm i ng2-search-filter#0.5.1
You can use custom search pipe for this
I have create demo on Stackblitz
searchPipe.ts
transform(value: any, searchText?: any): any {
if(!value) return [];
if(!searchText) return value;
searchText = searchText.toLowerCase();
return value.filter( it => {
return it.packageName.toLowerCase().includes(searchText) || it.packagePrice.toString().includes(searchText) || (it.userid && it.userid.userAge.toString().includes(searchText) || it.userid.userName.toLowerCase().includes(searchText));
});
}
component.html
<tr class="table-active" *ngFor="let use of user | search:searchtext">
<td> {{use.packageName}}</td>
<td>{{use.packagePrice}}</td>
<td>{{use.userid.userName}}</td>
<td>{{use.userid.userAge}}</td>
</tr>
Try the below:-
function getResult(filterBy, objList) {
return objList.hightlights.filter(function(obj) {
return obj.queries.some(function(item){
return item.indexOf(filterBy) >= 0;
});
});
}

Laravel - Filter using Between Dates and a Dropdown

I am combining two tables to generate a report that will be exported to excel. It should be filtered using between dates and parameter in dropdownlist
I have created the model, query in the controller and also the view. I can export the report to excel, but don't know how to filter it in the controller and view. The two tables are:
users (User: id,name,username)
played_game (PlayedGame: id, user_id, game, created_at)
Controller
public function playersPerGame()//public function playersPerGame(Request $request)
{
$games = DB::table('played_game')
->select(DB::raw('count(*) as no_of_players, game'))
->groupBy('game')
->get();
return view('report.playersPerGame', compact('games'));
}
public function playersExport() {
$players = PlayedGame::select(
"game",
\DB::raw("SUM(count(*)) as `no_of_players`"))
//->groupBy("game")
->get();
// Initialize the array which will be passed into the Excel
// generator.
$playersArray = [];
// Define the Excel spreadsheet headers
$playersArray[] = ['Games', 'No. of Players'];
// Convert each member of the returned collection into an array,
// and append it to the payments array.
foreach ($players as $player) {
$playersArray[] = $player->toArray();
}
route
Route::get('/report/players-per-game', ['as' => 'playersPerGame', 'uses' => 'ReportController#playersPerGame']);
Route::get('/report/players-export', 'ReportController#playersExport')->name('players-export');
view
<div class="col-xs-4 left-padding">
<i class="fa fa-file-excel-o"></i> Excel
</div>
</div>
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<!--
<div class="box-header with-border">
<div class="box box-info">
-->
<table class="table table-bordered table-hover table-striped table-condensed" id="commenter_info_table">
<caption></caption>
<thead>
<tr>
<td>#</td>
<td>Player</td>
<td>No. of Games</td>
</tr>
</thead>
<tbody>
#foreach($players as $key => $player)
<tr>
<td>{{ ++$key }}</td>
<td>{{ $player->name }}</td>
<td>{{ $player->no_game }}</td>
</tr>
#endforeach
</tbody>
</table>
When I get to the view page:
I want to filter using between dates (played_game.created_at), dropdownlists (users.name and played_game.game) before exporting to excel

Trying to use laravel pagination breaks my controller/view

I'm trying to get Pagination working in Laravel. I've not used pagination before so am trying to use some examples from the docs and google results. I'm wondering if I need to turn 'pagination' on somewhere in config.
Here's my simple working controller:
public function get_index() {
$locations = Location::all();
return View::make('location.index')->with('locations', $locations)->render();
}
When I try and add pagination like this it breaks:
public function get_index() {
$locations = Location::paginate(5);
return View::make('location.index')->with('locations', $locations)->render();
}
..and I get the error:
Unhandled Exception
Message:
Error rendering view: [location.index]
Trying to get property of non-object
Here's my location.index view:
#layout('layouts.blank')
#section('content')
<div class="row">
<div class="twelve columns">
<div role="main" id="content">
<h3>Locations - All</h3>
#if($locations)
<table class="twelve">
<thead>
<tr>
<th style="text-align: left;">Address</th>
<th>Area</th>
<th>Region</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
#foreach($locations as $location)
<tbody>
<tr>
<td style="text-align: left;">{{ $location->company,', ',$location->add_name,', ',$location->add_city }}</td>
<td> – </td>
<td> – </td>
<td>{{ HTML::link('location/update/'.$location->id, '',array('class'=>"foundicon-edit updateicon")) }}</td>
<td>{{ HTML::link('location/delete/'.$location->id, '',array('class'=>"foundicon-remove warnicon")) }}</td>
</tr>
</tbody>
#endforeach
</table>
#else
Looks like we haven't added any locations, yet!
#endif
<p>{{ HTML::link('location/create', 'Create a location', array('class'=>"small radius button")) }}</p>
</div>
</div>
</div>
#endsection
I hadn't read deeply enough into the subject. It's now working and here's what I had to change in the view:
//from:
#foreach($locations as $location)
//to:
#foreach($locations->results as $location)
That returned just 5 results. Then to add links to the footer of my table I added this HTML/Blade:
<tfoot>
<tr>
<td colspan="5"> {{ $locations->links() }} </td>
</tr>
</tfoot>
Hope someone else benefits as I didn't find this terribly clear in the docs.

Resources