I'm using DataTables (datatables.net) and I would like my search box to be outside of the table (for example in my header div).
Is this possible ?
You can use the DataTables api to filter the table. So all you need is your own input field with a keyup event that triggers the filter function to DataTables. With css or jquery you can hide/remove the existing search input field. Or maybe DataTables has a setting to remove/not-include it.
Checkout the Datatables API documentation on this.
Example:
HTML
<input type="text" id="myInputTextField">
JS
oTable = $('#myTable').DataTable(); //pay attention to capital D, which is mandatory to retrieve "api" datatables' object, as #Lionel said
$('#myInputTextField').keyup(function(){
oTable.search($(this).val()).draw() ;
})
As per #lvkz comment :
if you are using datatable with uppercase d .DataTable() ( this will return a Datatable API object ) use this :
oTable.search($(this).val()).draw() ;
which is #netbrain answer.
if you are using datatable with lowercase d .dataTable() ( this will return a jquery object ) use this :
oTable.fnFilter($(this).val());
You can use the sDom option for this.
Default with search input in its own div:
sDom: '<"search-box"r>lftip'
If you use jQuery UI (bjQueryUI set to true):
sDom: '<"search-box"r><"H"lf>t<"F"ip>'
The above will put the search/filtering input element into it's own div with a class named search-box that is outside of the actual table.
Even though it uses its special shorthand syntax it can actually take any HTML you throw at it.
For recent and new version of DataTables, You should follow these steps:
1- searching option must be true.
2- Hide default search input:
.dataTables_filter {
display: none;
}
3- Add new search input:
<input type="text" id="search">
4- Request search:
$('#search').keyup(function() {
var table = $('.table-meetups').DataTable();
table.search($(this).val()).draw();
});
This one helped me for DataTables Version 1.10.4, because its new API
var oTable = $('#myTable').DataTable();
$('#myInputTextField').keyup(function(){
oTable.search( $(this).val() ).draw();
})
I had the same problem.
I tried all alternatives posted, but no work, I used a way that is not right but it worked perfectly.
Example search input
<input id="searchInput" type="text">
the jquery code
$('#listingData').dataTable({
responsive: true,
"bFilter": true // show search input
});
$("#listingData_filter").addClass("hidden"); // hidden search input
$("#searchInput").on("input", function (e) {
e.preventDefault();
$('#listingData').DataTable().search($(this).val()).draw();
});
More recent versions have a different syntax:
var table = $('#example').DataTable();
// #myInput is a <input type="text"> element
$('#myInput').on('keyup change', function () {
table.search(this.value).draw();
});
Note that this example uses the variable table assigned when datatables is first initialised. If you don't have this variable available, simply use:
var table = $('#example').dataTable().api();
// #myInput is a <input type="text"> element
$('#myInput').on('keyup change', function () {
table.search(this.value).draw();
});
Since: DataTables 1.10
– Source: https://datatables.net/reference/api/search()
I want to add one more thing to the #netbrain's answer relevant in case you use server-side processing (see serverSide option).
Query throttling performed by default by datatables (see searchDelay option) does not apply to the .search() API call. You can get it back by using $.fn.dataTable.util.throttle() in the following way:
var table = $('#myTable').DataTable();
var search = $.fn.dataTable.util.throttle(
function(val) {
table.search(val).draw();
},
400 // Search delay in ms
);
$('#mySearchBox').keyup(function() {
search(this.value);
});
This should be work for you:(DataTables 1.10.7)
oTable = $('#myTable').dataTable();
$('#myInputTextField').on('keyup change', function(){
oTable.api().search($(this).val()).draw();
})
or
oTable = $('#myTable').DataTable();
$('#myInputTextField').on('keyup change', function(){
oTable.search($(this).val()).draw();
})
You could move the div when the table is drawn using the fnDrawCallback function.
$("#myTable").dataTable({
"fnDrawCallback": function (oSettings) {
$(".dataTables_filter").each(function () {
$(this).appendTo($(this).parent().siblings(".panel-body"));
});
}
});
$('#example').DataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "../admin/ajax/loadtransajax.php",
"fnServerParams": function (aoData) {
// Initialize your variables here
// I have assign the textbox value for "text_min_val"
var min_val = $("#min").val(); //push to the aoData
aoData.push({name: "text_min_val", value:min_val});
},
"fnCreatedRow": function (nRow, aData, iDataIndex) {
$(nRow).attr('id', 'tr_' + aData[0]);
$(nRow).attr('name', 'tr_' + aData[0]);
$(nRow).attr('min', 'tr_' + aData[0]);
$(nRow).attr('max', 'tr_' + aData[0]);
}
});
In loadtransajax.php you may receive the get value:
if ($_GET['text_min_val']){
$sWhere = "WHERE (";
$sWhere .= " t_group_no LIKE '%" . mysql_real_escape_string($_GET['text_min_val']) . "%' ";
$sWhere .= ')';
}
If you are using JQuery dataTable so you need to just add "bFilter":true. This will display default search box outside table and its works dynamically..as per expected
$("#archivedAssignments").dataTable({
"sPaginationType": "full_numbers",
"bFilter":true,
"sPageFirst": false,
"sPageLast": false,
"oLanguage": {
"oPaginate": {
"sPrevious": "<< previous",
"sNext" : "Next >>",
"sFirst": "<<",
"sLast": ">>"
}
},
"bJQueryUI": false,
"bLengthChange": false,
"bInfo":false,
"bSortable":true
});
I am using https://datatables.net/ for my tables. I need localization in this tables witch will set like this:
$('#tableId').dataTable( {
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.11/i18n/Slovak.json"
},
...
but at search input is label which i do not want... Is there any way in init. set label hidden? or empty string? I was trying (after localization set)
...
language: {
"sSearch": ""
}
or
...
oLanguage: {
"sSearch": ""
}
but without result... Any ideas?
You cannot modify the language settings once they are set, without recreating the table. You could load the language JSON first, modify it and then initialise the datatable. Or you could simply strip out plain text from the filter / search filter <label> :
var table = $('#example').DataTable({
...
initComplete : function() {
$('.dataTables_filter label').contents().filter(function() {
return this.nodeType === 3 //TEXT_NODE¹
}).remove()
}
})
The loop is necessary due to the nature of the injected markup :
<div class="dataTables_filter">
<label>
Search
<input />
</label>
</div>
So we cant just use .text('') or similar.
¹ https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
EDITED:
renamed shouldComponentUpdate to onClick
I'm using Ruby on Rails with the gem react-rails. The idea is to use a "PATCH" method to update an ArrayAttribute but using just JavaScript. To be clear, I'm still a newbie building a project while learning.
The story is, when a user checks a checkbox, it marks their post as complete. Their Post's table has a column for is_complete: :boolean, :default => false. Im using Postgres for the database.
var Foo = React.createClass({
getInitialState: function() {
return {
is_complete: this.props.data.is_complete, # shows "Empty object"
# is_complete: this.props.data[0].is_complete ..... shows "false"
# I could not use that because data[0] and data[1] etc...
}
},
onClick: function(){
var newVal = this.state.is_complete;
this.setState({
is_complete: React.addons.update(this.state.is_complete, { '$set': [ newVal ] })
})
},
render: function() {
var supports = (s) => (
<input type="checkbox" onChange={this.onClick}
/> Mark complete
);
return (
<div>
{this.props.data.map(supports)}
</div>
);
}
});
Index.html.erb:
<%= react_component('Foo', { data: #userlist }) %>
controller:
#userlist = #user.supports.as_json(:only => [:is_complete] # shortened for emample
When the checkbox is checked I get Uncaught TypeError: Cannot read property of is_complete of undefined
I'm looping through all of that user's posts (supports) and outputting the result on one page with a checkbox to mark as complete. I could achieve something similar by adding the chechbox inside of the edit page but I don't want that.
After the edit, I'm not getting the result I want. I want when checked, Array[1] and [2]'s is_complete is set to true or false.
Somehow I need to loop the getInitialState(), is that possible? I see not documentation on that.
So all of my columns sort without issue, except for my Media column which displays quotas for file size limits (GB, TB, etc.) I suspect the Rails NumberHelper number_to_human_size isn't playing nicely with tablesorter. Anyone have an idea how to get it to sort, while utilizing the NumberHelper?
_table.html.haml
%table#myTable.tablesorter
%thead
%tr
%th Name
%th.right Per Month
%th.right Members
%th.right Additional
%th.right Media
%th.right Subscriptions
- if #plans.any?
%tbody
- #plans.each do |plan|
%tr
%td
= link_to admin_plan_path(plan) do
= plan.name
%td.right
= "$ #{plan.base_price_in_cents / 100}"
%td.right
= plan.included_users
%td.right
= "$ #{plan.price_in_cents / 100}"
%td.right
= number_to_human_size(plan.media_data_quota) || '∞'.html_safe
%td.right
= link_to organizations_admin_plan_path(plan) do
= plan.subscriptions.count
application.js
$(document).ready(function()
{
$("#myTable").tablesorter( {sortList: [[0,0], [1,0]]} );
}
);
To make file sizes sort properly, you'll need a parser to convert "GB" and "TB", etc, into sortable numbers.
There is a metric parser available on my fork of tablesorter - demo which converts both metric & binary values to make sorting work.
To use it, load the parser file, then add a sorter-metric and data-metric-name attribute:
<th class="sorter-metric" data-metric-name="b|byte">Media</th>
I haven't tested it, but if you are using the original tablesorter, this parser should still work. If that is the case, the sorter class name won't work, so you'll need to set the headers option:
headers: {
0 : { sorter: 'metric' }
}
I'm using the select2 jQuery plugin, on a rails form to do autocompleting on a multi-select field. Everything works fine if there are no validation errors on the page. If there is a validation error (not related to this element), then the javascript portion gets an empty element and fails on the JSON.parse call.
However inspecting with chrome-tools show that the Form Data has the correct information under services
services:[{"id":93,"text":"Old School"},{"id":94,"text":"Gels"}],93,94
Here is the view snippet
<%= f.label :services, "Services" %>
<input name="services" type='hidden' id='services' data-values='<%= #services %>' value='<%= #selected_services %>' style="width: 100%"/>
The Javascript looks like this.
var initSel = function (element, callback) {
console.log("intiSel data BRFORE json parse", $(element).val());
try {
var data = JSON.parse($(element).val());
callback(data);
console.log("intiSel data AFTER json parse", data);
} catch (e) {
console.error("Parsing error:", e);
}
}
$(function() {
$("#services").select2({
initSelection: initSel,
createSearchChoice: function(term, data) {
if ( $(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0) {return {id:term, text:term};}
},
multiple: true,
data: function (){
var data = $('#services').data('values');
return {results:data};
}
});
});
I had same problem, after validation error the select2 inputs fields were not able to load data.
I'm not sure that it will helps for your case but it can help other stack users with select2 error after validation.
In my case the error was coming from the controller. I was using a before_action filter to get the variables to prepare the options or the data for the select2 inputs fields.
I realize that I was missing some actions in my filter, so the variables were not generated anymore.
class MyController < ApplicationController
before_action :prepare_data, only: [:edit, :update, :new, :create] #now I had all my actions not only edit and new for instance.
private
def prepare_data
#my_var_for_data_select2 = User.all.collect.collect{|u| u.username}
end
end