I have the following code where I edit the field of a row in a table, but I want it to be more Dynamic, that is, when editing a field it jumps to the next field where I will edit. I have a success function where I should jump to the next field to edit what the Item would be, but I do not know why it does not work.
$('#table').editable({
container: 'body',
selector: 'td.task',
title: 'task',
type: "POST",
showbuttons: false,
type: 'text',
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
},
success: function(response) {
//WITH THIS CODE I COULD JUMP BUT THE LIST GIVE A ERROR AND CREATE A NEW TR WITH TD
$(this).parent().find(".Item").click();
}
});
var ITEM = [];
$.each({
"Item1": "Item1",
"Item2": "Item2",
"Item3": "Item3",
"Item4": "Item4"
}, function(k, v) {
ITEM.push({
value: k,
text: v
});
});
$('#table').editable({
container: 'body',
selector: 'td.Item',
title: 'Item',
type: "POST",
showbuttons: false,
source: ITEM,
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
}
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<table id="table" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Task</th>
<th>Item</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td data-name="task" class="task" data-type="text">001</td>
<td data-name="Item" class="Item" data-type="select">Item2</td>
</tr>
<tr>
<td>2</td>
<td data-name="task" class="task" data-type="text">002</td>
<td data-name="Item" class="Item" data-type="select">Item1</td>
</tr>
</tbody>
</table>
I have seen an example on the next page. link you must press the checkbox auto-open next field at the moment of editing this jump to the next field to edit. I would like something like that, I hope I have explained myself well.
UPDATE: I add a line of code in my success function but the select give a error Error when loading list and in the table create a new <tr> with <td>
I just changed $(this).parent().find(".Item").editable('toggle'); to $(this).parent().find(".Item").click();
$('#table').editable({
container: 'body',
selector: 'td.task',
title: 'task',
type: "POST",
showbuttons: false,
type: 'text',
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
},
success: function(response) {
//WITH THIS CODE I COULD JUMP BUT THE LIST GIVE A ERROR AND CREATE A NEW TR WITH TD
$(this).parent().find(".Item").click();
}
});
var ITEM = [];
$.each({
"Item1": "Item1",
"Item2": "Item2",
"Item3": "Item3",
"Item4": "Item4"
}, function(k, v) {
ITEM.push({
value: k,
text: v
});
});
$('#table').editable({
container: 'body',
selector: 'td.Item',
title: 'Item',
type: "POST",
showbuttons: false,
source: ITEM,
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
}
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<table id="table" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Task</th>
<th>Item</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td data-name="task" class="task" data-type="text">001</td>
<td data-name="Item" class="Item" data-type="select">Item2</td>
</tr>
<tr>
<td>2</td>
<td data-name="task" class="task" data-type="text">002</td>
<td data-name="Item" class="Item" data-type="select">Item1</td>
</tr>
</tbody>
</table>
I think that your error show up because there is no default value at first try changing item then change text in your snippet
$('#table').editable({
container: 'body',
selector: 'td.task',
title: 'task',
type: "POST",
showbuttons: false,
type: 'text',
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
},
success: function(response) {
//CODE TO JUMP TO THE SELECT
}
});
var ITEM = [];
$.each({
"Item1": "Item1",
"Item2": "Item2",
"Item3": "Item3",
"Item4": "Item4"
}, function(k, v) {
ITEM.push({
value: k,
text: v
});
});
$('#table').editable({
container: 'body',
selector: 'td.Item',
title: 'Item',
type: "POST",
showbuttons: false,
source: ITEM,
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
}
});
$('#table .task').on('hidden', function(e, reason){
if(reason === 'save' || reason === 'nochange') {
var $next = $(this).closest('tr').next().find('.task');
setTimeout(function() {
$next.editable('show');
}, 300);
}
});
$('#table .Item').on('hidden', function(e, reason){
if(reason === 'save' || reason === 'nochange') {
var $next = $(this).closest('tr').next().find('.Item');
setTimeout(function() {
$next.editable('show');
}, 300);
}
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<table id="table" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Task</th>
<th>Item</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td data-name="task" class="task" data-type="text">001</td>
<td data-name="Item" class="Item" data-type="select">Item2</td>
</tr>
<tr>
<td>2</td>
<td data-name="task" class="task" data-type="text">002</td>
<td data-name="Item" class="Item" data-type="select">Item1</td>
</tr>
</tbody>
</table>
Please try again this. This will help you :)
$('#table').editable({
container: 'body',
selector: 'td.task',
title: 'task',
type: "POST",
showbuttons: false,
type: 'text',
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
},
success: function(response) {
//CODE TO JUMP TO THE SELECT
}
});
var ITEM = [];
$.each({
"Item1": "Item1",
"Item2": "Item2",
"Item3": "Item3",
"Item4": "Item4"
}, function(k, v) {
ITEM.push({
value: k,
text: v
});
});
$('#table').editable({
container: 'body',
selector: 'td.Item',
title: 'Item',
type: "POST",
showbuttons: false,
source: ITEM,
validate: function(value) {
if ($.trim(value) == '') {
return 'Empty!';
}
}
});
$('#table .task').on('hidden', function(e, reason) {
if (reason === 'save' || reason === 'nochange') {
$(this).parent().find(".Item").click();
}
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet" />
<table id="table" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Task</th>
<th>Item</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td data-name="task" class="task" data-type="text">001</td>
<td data-name="Item" class="Item" data-type="select">Item2</td>
</tr>
<tr>
<td>2</td>
<td data-name="task" class="task" data-type="text">002</td>
<td data-name="Item" class="Item" data-type="select">Item1</td>
</tr>
</tbody>
</table>
Thankfully, since you linked to the working example, I was able to examine the code. You can do this, by the way, by simply opening up the developer tools in your browser. I use Chrome, so for me that's just F12. In the source code, I found the following:
$('#user .editable').on('hidden', function(e, reason){
if(reason === 'save' || reason === 'nochange') {
var $next = $(this).closest('tr').next().find('.editable');
if($('#autoopen').is(':checked')) {
setTimeout(function() {
$next.editable('show');
}, 300);
} else {
$next.focus();
}
}
});
The code reads almost like English, so it is fairly easy to follow I think.
When the editor is closed, we first check for the reason why it closed.
The code then finds the next field and pops open the editor if the "auto-open next textfield" is checked. It's interesting to see here that this is done with a timeout instead of just calling $next.editable('show'); That might be important or just for show.
In your code, you'll want to be able to find some unifying selector for your items. Easiest way to do it, I think, is to just add an .editable to your original source and call it like they do in the demo.
So, for your HTML:
<table id="table" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Task</th>
<th>Item</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td data-name="task" class="editable task" data-type="text">001</td>
<td data-name="Item" class="editable Item" data-type="select">Item2</td>
</tr>
<tr>
<td>2</td>
<td data-name="task" class="editable task" data-type="text">002</td>
<td data-name="Item" class="editable Item" data-type="select">Item1</td>
</tr>
</tbody>
</table>
Notice the added class on the td tags. (EDIT: derp, didn't notice there was already a class attribute)
Then, you can emulate the demo js code, but be careful here because the $next variable cannot be selected in the same way. Your DOM layout is not the same since you have more than one editable cell in a row:
$('#table .editable').on('hidden', function(e, reason){
if(reason === 'save' || reason === 'nochange') {
var $next = $(this).nextAll().find('.editable');
if ($next.length > 0) {
$next = $next[0];
} else {
$next = $(this).closest('tr').next().find('.editable');
if ($next.length > 0) {
$next = $next[0];
} else {
return; // No editable fields remaining.
}
}
setTimeout(function() { $next.editable('show'); }, 300);
}
});
I should disclaim that I have not tested the above, but it should give you a good starting point to get going. The selection of the next field can probably be done a lot better than what I have, but I just don't have the testing environment to check this out properly.
EDIT: I've noticed that perhapse you only want to move on to the select field, but not necessarily from the select to the item in the next row. In that case, the code is a little bit simpler.
First off, there is no need for the editable class, so you can just use the html code you already have, but in the js, you need to address the selectors correctly:
$('#table .task').on('hidden', function(e, reason){
if(reason === 'save' || reason === 'nochange') {
var $next = $(this).nextAll().find('.Item');
setTimeout(function() { $next.editable('show'); }, 300);
}
});
And that should be it. When the editor on the select closes, the next field will not be selected automatically.
Related
I have 2 components.
Table Component
Row Component (Each row in the table)
The table component calls the row component inside the <tbody> tag for every row in the data.
But while rendering the rows are rendered first (outside the table tag) followed by the <table> tag.
See the example below.
Vue.component('single-table-row', {
props: {
row: {
type: Object
}
},
template: `
<tr>
<td>{{row.id}}</td>
<td>{{row.text}}</td>
</tr>
`
});
Vue.component('mytable', {
props: {
tabledata: {
type: Object
}
},
data: function () {
return {
headers: ['Id', 'Text']
}
},
computed: {
table_rows: function () {
return this.tabledata.data.rows;
}
}
});
var app3 = new Vue({
el: '#app-3',
data: {
mydata: {
data: {
rows: [
{
id: 1,
text: 'Sample 1'
},
{
id: 2,
text: 'Sample 2'
},
{
id: 3,
text: 'Sample 3'
}
]
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app-3">
<mytable v-bind:tabledata="mydata" inline-template>
<div id="table_parent">
<table>
<thead>
<tr>
<th v-for="header in headers">{{header}}</th>
</tr>
</thead>
<tbody>
<single-table-row :row=rows v-for="rows in table_rows" :key=rows.id>
</single-table-row>
</tbody>
</table>
</div>
</mytable>
</div>
The output is rendered as :
<div id="table_parent">
<tr>
<td>2</td>
<td>Sample 2</td>
</tr>
<tr>
<td>1</td>
<td>Sample 1</td>
</tr>
<tr>
<td>3</td>
<td>Sample 3</td>
</tr>
<table>
<thead>
<tr>
<th>Id</th>
<th>Text</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
Ideally it should have rendered the row component inside the <tbody> tag.
What am I missing here ?
You need to use <tr is="single-table-row" instead of <single-table-row.
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
This is because your template is directly in the HTML. The browser will parse it before Vue gets anywhere near it. Certain elements, such as tbody, have restrictions on what child elements they can have. Any elements that are not allowed will be torn out the table. By the time Vue gets involved they've already been moved.
Vue.component('single-table-row', {
props: {
row: {
type: Object
}
},
template: `
<tr>
<td>{{row.id}}</td>
<td>{{row.text}}</td>
</tr>
`
});
Vue.component('mytable', {
props: {
tabledata: {
type: Object
}
},
data: function () {
return {
headers: ['Id', 'Text']
}
},
computed: {
table_rows: function () {
return this.tabledata.data.rows;
}
}
});
var app3 = new Vue({
el: '#app-3',
data: {
mydata: {
data: {
rows: [
{
id: 1,
text: 'Sample 1'
},
{
id: 2,
text: 'Sample 2'
},
{
id: 3,
text: 'Sample 3'
}
]
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app-3">
<mytable v-bind:tabledata="mydata" inline-template>
<div id="table_parent">
<table>
<thead>
<tr>
<th v-for="header in headers">{{header}}</th>
</tr>
</thead>
<tbody>
<tr is="single-table-row" :row=rows v-for="rows in table_rows" :key=rows.id>
</tr>
</tbody>
</table>
</div>
</mytable>
</div>
I have table:
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks">
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.id}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.text}}<button v-if="showBatton">Test</button></td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.date_current}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"><button v-if="showBatton">Test</button></td>
</tr>
</tbody>
</table>
As intended, the button should appear on the line on which the mouse is hovering.
But now it appears on all visible lines.
Script:
data:{
showBatton:false,
},
showButtonFunction(){
// this.title="dsds2"
console.log("test")
this.showBatton=true;
},
hideButtonFunction(){
this.showBatton=false;
}
How to implement it?
You can do this with css only:
// CSS
tr button {
display: none;
}
tr:hover button {
display: inline-block;
}
// HTML
<tr v-for="row in tasks">
<td span>{{row.id}}</td>
<td span>{{row.text}}<button>Test</button></td>
<td span>{{row.date_current}}</td>
<td span><button>Test</button></td>
</tr>
You can do it Using VueJS Also Like:
<div id="app">
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks" #mouseover="showButtonFunction(row.id)" #mouseleave="hideButtonFunction" :key="row.id">
<td>{{row.id}}</td>
<td>{{row.text}}<button v-show="buttonIndex === row.id">Test</button></td>
<td>{{row.date_current}}</td>
<td><button v-show="buttonIndex === row.id">Test</button></td>
</tr>
</tbody>
</table>
</div>
JS Code:
var vue = new Vue({
el: '#app',
data:{
buttonIndex: false,
tasks: [
{
id: 1,
text: "Hello",
date_current: new Date()
},
{
id: 2,
text: "Hello2",
date_current: new Date()
},
{
id: 3,
text: "Hello3",
date_current: new Date()
}
]
},
methods:{
showButtonFunction(id){
// this.title="dsds2"
this.buttonIndex=id;
},
hideButtonFunction(){
this.buttonIndex=false;
}
}
})
Check this Link :)
I am using datatable in react. When i click on sorting (in tHead) it removes all data and says no data available in table
What i think here, is that tbody is being rendered before Datatable initialisation. Or something like that.
Here is my code in PasteBin
And here is some code of componentDidMount
componentDidMount(){
employessData = thisclass.props.data;
thisclass.setState({
stateReady: true
})
var self = this;
$('#mytableEmp').dataTable({
"columnDefs": [
{ "width": "20px", "targets": 0 }
],
"pagingType": "numbers",
"bAutoWidth": false,
"bDestroy": true,
"fnDrawCallback": function() {
self.forceUpdate();
}
});
$('#checkboxhead').removeAttr('area-sort').removeClass('sorting_asc');
$(".checkAllCBEmp").click(function () {
$('#mytableEmp tbody input[type="checkbox"]').prop('checked', this.checked);
});
$("#searchtabletb").on("keyup", function() {
var value = $(this).val();
value = value.toLowerCase();
console.log(value);
$("#mytableEmp tr").each(function(index) {
if (index != 0) {
var row = $(this);
var id = row.find("td").text();
id = id.toLowerCase();
if (id.indexOf(value) === -1) {
$(this).hide();
}
else {
$(this).show();
}
}
});
});
}
And here is code from render function.
render () {
return (
<table className="table table-stripped" id="mytableEmp">
<thead>
<tr className="table-head-row">
<th id="checkboxhead" className="firsttd">
<div className="round-cb">
<input type="checkbox" id="cb1_emp" className="checkAllCBEmp" />
<label htmlFor="cb1_emp"></label>
</div>
</th>
<th>Title</th>
<th>Type</th>
<th>Created on</th>
<th>From</th>
<th>To</th>
<th>Processed</th>
<th>Amount</th>
<th>Status</th>
<th id="detailarrowhead" className="lasttd"></th>
</tr>
</thead>
<tbody>
{
this.state.stateReady ?
employessData.map((heading, index) => {
return(<tr role="row" className="tablerow" key={index}>
<td className="firsttd">
<div className="round-cb">
<input type="checkbox" value="cb1" id={heading.userId} />
<label htmlFor={heading.userId}></label>
</div>
</td>
<td>
<div className="emp-avatar">
<img src={heading.profile_picture} />
</div>
<div className="emp-title-div">
<div className="emp-title">
<div>
{heading.name}
</div>
</div>
</div>
</td>
<td>c</td>
<td>Texto 2</td>
<td>Texto 2</td>
<td>Texto 2</td>
<td>Texto 2</td>
<td>Texto 2</td>
<td><span className="badge badge-red">Rejected</span></td>
<td className="lasttd"><Link to="/emp-profile" className="table-details-btn" onClick={() => {this.addlocalid(heading.userId)}}>View User</Link></td>
</tr>)
})
:
""
}
/tbody>
</table>
)
}
The scope of employessData is weird, so it thisclass.
You will want to do this instead in render:
let employessData = this.props.data;
this.state.stateReady ?
employessData.map(...);
and then understand if/why this.props.data that this component receives is empty (which is not visible here).
I have resolved this issue for the time being.
I have added delay of 3 seconds in following function
setTimeout(function(){
$('#mytableEmp').dataTable({
"columnDefs": [
{ "width": "20px", "targets": 0 }
],
"pagingType": "numbers",
"bAutoWidth": false,
"bDestroy": true,
"fnDrawCallback": function() {
self.forceUpdate();
}
});
}, 3000);
I use bootstrap-table and would like to use table-filter-control extension. In this example you can see how to use this extension. When I want to use this extension for more columns, it doesn't work. In my example filter works only for one column.
jsfiddle
html
<table ref="mainTable" class="table table-striped table-bordered table-hover"
cellSpacing="0" id="mainTable" data-show-toggle="true"
data-show-columns="true" data-search="true" data-pagination="true" data-filter-control="true">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="Customer Name" data-sortable="true" data-filter-control="select">Customer Name</th>
<th data-field="Location Type" data-sortable="true">Location Type</th>
<th data-field="Location" data-sortable="true" data-filter-control="select">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Cap Corp</td>
<td>Main</td>
<td>Norwalk CT 06851</td>
</tr>
<tr>
<td></td>
<td>Cap Corp</td>
<td>Other</td>
<td>Norwalk CT 06851</td>
</tr>
<tr>
<td></td>
<td>Tel</td>
<td>Main</td>
<td>Slough SL1 4DX</td>
</tr>
<tr>
<td></td>
<td>Tel</td>
<td>Other</td>
<td>London W1B 5HQ</td>
</tr>
</tbody>
</table>
data-filed should have not spaces, try to change
data-field="Customer Name"
to
data-field="CustomerName"
I updated your jsfiddle and filter-control works.
http://jsfiddle.net/5h595r6g/9/
However it would be great to implement filter options updating to available values, as I described in this post:
bootstrap table filter-control - how to unset unnecessary values from select options
I actually put select2 boxes in the headers, and then used the params feature to pass the code to the server. I made for a much nicer solution. My code isn't with me but if you are interested in it I can pass a sample along Monday.
Edited to add example.
Basic Table
<table id='90day' class='table table-striped' data-filter-control='true'>
<thead>
<tr>
<th></th>
<th><select id='findfield' class='form-control gosearch'><option></option></select></th>
<th><select id='findwellname' class='form-control gosearch'><option></option></select></th>
</tr>
</thead>
</table>
Initialize the select2
$('#90day').on('post-header.bs.table', function () {
$('#findfield').select2({
width: '100%',
placeholder: 'Field',
allowClear: true,
SingleSelection: true,
ajax: {
url: 'selectfield90day.php?active=y',
dataType: 'json',
//delay: 250,
data: function (params) {
$('#findfield').empty();
var d = new Date();
var n = d.getTime();
return {
q: params.term,
n: n
};
},
processResults: function (data) {
return { results: data };
}
}
});
$('#findwellname').select2({
width: '100%',
placeholder: 'Name',
allowClear: true,
ajax: {
url: 'selectwellname90day.php?active=y',
dataType: 'json',
delay: 250,
data: function (params) {
$('#findwellname').empty();
var d = new Date();
var n = d.getTime();
return {
q: params.term,
field: $('#findfield').text(),
pad: $('#findpad').text(),
n: n
};
},
processResults: function (data) {
return {
results: data
};
}
}
});
//refresh on any select2 change
$('.gosearch').on('select2:close', function(){
$('#90day').bootstrapTable('refresh');
});
});
Finally table initialization
$('#90day').bootstrapTable({
url: ...,
columns:[
...
],
queryParams: function(params){
params['field']=$('#findfield').text();
params['well_name']=$('#findwellname').text();
return params;
}
});
The code inside the DIV search_status works with sorting and pagination once the page has loaded, however if I call the exact same data from an ajax call to replace the content the sorting still works however the pagination breaks. Any ideas anyone as to why this would happen and how I could fix?
EDIT: Adding the below fixes the issue.
$("#tablesorter").tablesorterPager({ container: $("#pager"), positionFixed: false });
-
<script type="text/javascript" src="/js/jquery.metadata.js"></script>
<script type="text/javascript" src="/js/jquery.tablesorter.js"></script>
<script type="text/javascript" src="/js/jquery.tablesorter.pager.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#tablesorter").tablesorter({ debug: false, widgets: ['zebra', 'columnHighlight'] })
.tablesorterPager({ container: $("#pager"), positionFixed: false });
});
$(function() {
if ($("#search").val()!=''){
asearch();
}
function asearch() {
$.post("/_ajax/search_table",{
search: $("#search").val()
},
function(data){
$("#search_status").html(data);
$("#tablesorter").tablesorter({widgets: ['zebra']});
});
return false;
}
$("#button_search").click(function() {
asearch();
});
$('#search').bind('keydown',function(e){
if (e.keyCode==13 || e.which==13) asearch();
});
});
}
</script>
Search <input id="search" name="search" type="text"> <input id="button_search" type="button" value="Search">
<div id="search_status" style="text-align:left">
<table cellspacing="1" id="tablesorter" class="tablesorter">
<thead>
<tr align="center">
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tfoot>
<tr id="pager" align="center">
<td colspan="7">
<img src="/images/first.png" class="first" alt="First Page" height="16" width="16">
<img src="/images/prev.png" class="prev" alt="Previous Page" height="16" width="16">
<label class="pagedisplay"></label> <img src="/images/next.png" class="next" alt="Next Page" height="16" width="16">
<img src="/images/last.png" class="last" alt="Last Page" height="16" width="16">
<select class="pagesize">
<option selected="selected" value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
</select>
</td>
</tr>
</tfoot>
<tbody>
<tr align="center">
<td>2</td>
<td>John</td>
</tr>
<tr align="center">
<td>1</td>
<td>Doe</td>
</tr>
</tbody>
</table>
</div>
I had problems with the pager and the table sorter in general when loading the table with an ajax call. After trying a few different suggestions (none that worked completely) I found puting the JQuery tablesorter script in my partial view and not in the main view did the trick.
In the main view
$(document).ready(function () {
$(document).ajaxStart(function () {
$('#ajaxBusy').show();
$('#details').hide();
$('#pager').hide();
}).ajaxStop(function () {
$('#ajaxBusy').hide();
$('#details').show();
$('#pager').show();
});
....
});
function SearchCustomerStock(force) {
var searchText = $("#FindStock_ED").val();
var customerId = '#ViewBag.EncodedID';
if (force || searchText.length > 2) {
$('#ajaxBusy').show();
$('#details').hide();
var dataObject = { CustomerId: customerId, Like: searchText, Perspective: $('#Perspective').val(), PerspectiveId: $('#PerspectiveId').val() };
$.ajax({
type: "GET",
url: "/CustomerStock/GetStockLike",
data: dataObject,
contentType: "application/json; charset=utf-8",
//async: false,
success: function (data) {
//$('#ajaxBusy').hide();
//$('#details').show();
$('#details').html(data);
/*var sorting = [[0, 0]];
$("table.tablesorter")
.tablesorter(
{ widthFixed: true },
{ sortList: [[0, 0]] },
{ headers: { 7: { sorter: false } } })
.tablesorterPager({ container: $("#pager"), size: $(".pagesize option:selected").val() });*/
},
error: function (jqXHR, textStatus, errorThrown) {
$('#ajaxBusy').hide();
$('#details').show();
alert(jqXHR + ', ' + textStatus + ', ' + errorThrown);
},
cache: false
});
}
//$("#FindStock_ED").attr('disabled', false);
return false;
}
In the partial view
#model IEnumerable<SkyPortR.Models.CustomerStockViewModel>
<script type="text/javascript">
$("table.tablesorter")
.tablesorter(
{ widthFixed: true },
{ sortList: [[0, 0]] },
{ headers: { 7: { sorter: false } } })
.tablesorterPager({ container: $("#pager"), size: $(".pagesize option:selected").val() });
</script>
<table class="tablesorter">
<thead>
<tr>
<th>
Barcode
</th>
<th>
Alternate Code
</th>
<th>
Group
</th>
<th>
Description
</th>
<th>
Packsize
</th>
<th>
LastCost
</th>
<th>
Supplier
</th>
<th class="indexImages">
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>