Im using bootstrap datatables, and im having a search input and whatever I do it won't remove Search text and add placeholder. I've seen examples here on stack and google but that didnt helped.
I believe this is the js for the search input:
function _fnFeatureHtmlFilter ( settings )
{
var classes = settings.oClasses;
var tableId = settings.sTableId;
var language = settings.oLanguage;
var previousSearch = settings.oPreviousSearch;
var features = settings.aanFeatures;
var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
var str = language.sSearch;
str = str.match(/_INPUT_/) ?
str.replace('_INPUT_', input) :
str+input;
var filter = $('<div/>', {
'id': ! features.f ? tableId+'_filter' : null,
'class': classes.sFilter
} )
.append( $('<label/>' ).append( str ) );
var searchFn = function() {
/* Update all other filter input elements for the new display */
var n = features.f;
var val = !this.value ? "" : this.value; // mental IE8 fix :-(
/* Now do the filter */
if ( val != previousSearch.sSearch ) {
_fnFilterComplete( settings, {
"sSearch": val,
"bRegex": previousSearch.bRegex,
"bSmart": previousSearch.bSmart ,
"bCaseInsensitive": previousSearch.bCaseInsensitive
} );
// Need to redraw, without resorting
settings._iDisplayStart = 0;
_fnDraw( settings );
}
};
var jqFilter = $('input', filter)
.val( previousSearch.sSearch )
.attr( 'placeholder', language.sSearchPlaceholder )
.bind(
'keyup.DT search.DT input.DT paste.DT cut.DT',
_fnDataSource( settings ) === 'ssp' ?
_fnThrottle( searchFn, 400 ):
searchFn
)
.bind( 'keypress.DT', function(e) {
/* Prevent form submission */
if ( e.keyCode == 13 ) {
return false;
}
} )
.attr('aria-controls', tableId);
// Update the input elements whenever the table is filtered
$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
if ( settings === s ) {
// IE9 throws an 'unknown error' if document.activeElement is used
// inside an iframe or frame...
try {
if ( jqFilter[0] !== document.activeElement ) {
jqFilter.val( previousSearch.sSearch );
}
}
catch ( e ) {}
}
} );
return filter[0];
}
As you know it datatables doesn't show in HTML, so its js.
How it looks, look at the search input
How I want it to look
you can use following code
oLanguage: {
"sSearch": ""
},
for Placeholder put the following code
$('.dataTables_filter input').attr("placeholder", "search...");
Related
I am defining a Datatable this way:
var dat_one = $('#dat_one').DataTable({
select: {
style: 'single'
},
responsive: true,
});
I would like to access a specific line of my datatable. I want to color a line that contains a specific string. (Example: Line that contains 'Ashton Cox' as column 1 and 'San Francisco' as column 3
I tried to color a selected line with this code :
$(".selected").css('background-color', '#ccffcc');
But doesn't works if my line is not selected.
Try using rowCallback. There you can change row attributes with value checking.
$('#example').dataTable( {
"rowCallback": function( row, data ) {
if ( data.grade == "A" ) {
$('td:eq(4)', row).html( '<b>A</b>' );
}
}
} );
This is documentation. Note the function has many other parameters you can use.
rowCallback( row, data, displayNum, displayIndex, dataIndex )
Following documentation, this is an alternative to Aruna Perera:
// var table = $('#dat_one').DataTable() ;
dat_one.rows().eq(0).each( function ( index ) {
var row = table.row( index );
var data = row.data();
var column0value = data[0];
if(column0value == "Airi Satou"){
$(row.node()).css("background-color", "yellow")
}
// ... do something with data(), or row.node(), etc
} );
I had a successful execution before adding the form tag. But somehow the JavaScript is replaced. Is there a way to do without this form submission. I need to pass the data to PHP. Thank You in Advance..
This is the html I tried
<!DOCTYPE html>
<html>
<head>
<script src="riu003.js"></script>
</head>
<body>
<form name="myform" method="post" action="/riu/riu-01/riu001.php" enctype="multipart/form-data">
<div id="aaa">
</div>
<button style="width: 100%" class="bbb" onclick="addfielderbutt()">Add Fields</button>
<button style="width: 100%; height: 45px; background-color: dodgerblue" onclick="submity()" type="Submit" value="submit">SUBMIT</button>
</form>
</body>
</html>
And here is the JavaScript file.
function createElemented(element, attribute, inner) {
if (typeof(element) === "undefined") { return false; }
if (typeof(inner) === "undefined") { inner = ""; }
var el = document.createElement(element);
if (typeof(attribute) === 'object') {
for (var key in attribute) {
el.setAttribute(key, attribute[key]);
}
}
if (!Array.isArray(inner)) { inner = [inner]; }
for (var k = 0; k < inner.length; k++) {
if (inner[k].tagName) {
el.appendChild(inner[k]);
} else {
el.appendChild(document.createTextNode(inner[k]));
}
}
return el;
};
var noofclicks = 0;
function addfielderbutt() {
noofclicks = noofclicks + 1;
var uptexty = createElemented("TEXTAREA", { class: "upt_" + noofclicks, name: "positiveuse_" + noofclicks, type: "text" }, "Type the postive uses here...");
var nptexty = createElemented("TEXTAREA", { class: "unt_" + noofclicks, name: "negativeuse_" + noofclicks, type: "text" }, "Type the negative uses here...");
var dptexty = createElemented("TEXTAREA", { class: "dpt_" + noofclicks, name: "positivedisuse_" + noofclicks, type: "text" }, "Type the postive disuses here...");
var dntexty = createElemented("TEXTAREA", { class: "dnt_" + noofclicks, name: "negativedisuse_" + noofclicks, type: "text" }, "Type the negative disuses here...");
var breakkk = createElemented("BR");
document.getElementById("aaa").appendChild(uptexty);
document.getElementById("aaa").appendChild(nptexty);
document.getElementById("aaa").appendChild(dptexty);
document.getElementById("aaa").appendChild(dntexty);
document.getElementById("aaa").appendChild(breakkk);
}
function submity(){
document.cookie = "numberofclicks="+noofclicks;
}
The problem is probably because your submit button have type="submit". Since you mentioned it was working before adding the form tag, i'm guessing that submity() is the function that sends the data to PHP, but now that you added a form tag, it will not be executed. This is because a clicking a button with type="submit" inside a form tag not only sends the form data to the link in the action attribute, but also navigates to it.
I'm fairly sure I understand the issue with your original code - that being the inability to prevent the default action occurring when using the button. I modified the code a little and added the ajax function which would allow the sending of the form data without reloading the page. Essentially the same code but rewritten to use external event listeners rather than inline event handler calls. Hope i helps.
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
/*
this is to emulate whatever code you have in
the form action /riu/riu-01/riu001.php
*/
exit( json_encode( $_POST ) );
}
?>
<!DOCTYPE html>
<html>
<head>
<title>You have got to have a title...</title>
<style>
button{ width: 100%;height:45px;background-color: dodgerblue }
.bbb{}
fieldset{border:none;}
</style>
<script>
document.addEventListener('DOMContentLoaded',()=>{
/*
presumably this will be in riu003.js
------------------------------------
*/
let counter = 0; // the counter to be incremented.
let url=location.href; // change this to "/riu/riu-01/riu001.php"
const submity=function(e){
/*
explicitly prevent the default form submission
*/
e.preventDefault();
/* The payload is a FormData object */
let payload=new FormData( document.querySelector('form[name="myform"]') );
/*
The callback can do far more than this...
*/
let callback=function( r ){
alert( r )
}
/*
send the ajax request to the backend PHP script.
The actual url used will not be `location.href`
according to the original code...
*/
ajax.call( this, url, payload, callback );
};
/* a variation on the createElemented function */
const create=function(type,attributes,parent){
try{
let el = ( typeof( type )=='undefined' || type==null ) ? document.createElement( 'div' ) : document.createElement( type );
let _arr=['innerhtml','innertext','html','text'];
for( let x in attributes ) if( attributes.hasOwnProperty( x ) && !~_arr.indexOf( x ) ) el.setAttribute( x, attributes[ x ] );
if( attributes.hasOwnProperty('innerHTML') || attributes.hasOwnProperty('html') ) el.innerHTML=attributes.innerHTML || attributes.html;
if( attributes.hasOwnProperty('innerText') || attributes.hasOwnProperty('text') ) el.innerText=attributes.innerText || attributes.text;
if( parent!=null ) typeof( parent )=='object' ? parent.appendChild( el ) : document.getElementById( parent ).appendChild( el );
return el;
}catch( err ){
console.warn( err.message );
}
};
/* ultra basic ajax function to send a POST request */
const ajax=function(url,payload,callback){
let xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if( this.status==200 && this.readyState==4 )callback.call( this, this.response );
}
xhr.open('POST',url,true);
xhr.send(payload);
};
const addfielderbutt=function(e){
counter++;
/* explicitly prevent the default action being triggered */
e.preventDefault();
/* create a fieldset and append new children to it */
let fieldset=create( 'fieldset', {}, document.getElementById('aaa') );
/* add the children */
create( 'textarea',{ 'class':'upt_' + counter, name:'positiveuse_' + counter },fieldset );
create( 'textarea',{ 'class':'unt_' + counter, name:'negativeuse_' + counter },fieldset );
create( 'textarea',{ 'class':'dpt_' + counter, name:'positivedisuse_' + counter },fieldset );
create( 'textarea',{ 'class':'dnt_' + counter, name:'negativedisuse_' + counter },fieldset );
};
/*
Bind the event handlers to the buttons
*/
document.querySelector( 'button.bbb' ).addEventListener( 'click', addfielderbutt );
document.querySelector( 'button[ type="submit" ]' ).addEventListener( 'click', submity );
});
</script>
</head>
<body>
<form name='myform' method='post'>
<div id='aaa'>
<!-- generated content will appear here -->
</div>
<button class='bbb'>Add Fields</button>
<button type='Submit' value='submit'>SUBMIT</button>
</form>
</body>
</html>
I am using Jquery Datatable for my table and for filtering data I am following this example
DataTables > API > Multi-filter
This is working fine for regular columns. But I have some columns with drop downs as following.
For this column filtering is not working since it is considered the all entries of the drop down for filtering.
Can someone please suggest a way to put a filter for this king of column.
I am using DataTables version 1.10.7.
Thanks.
That was fun:
const table = $('#example').DataTable({
initComplete: function () {
this.api().columns().eq(0).each( function (index) {
const column = this.column(index);
const title = $(column.header()).text();
if(index === 2){
var select = $(`
<select class="form-control">
<option value="">Please choose</option>
</select>
`)
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
});
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
});
}else{
var input = $(`
<input class="form-control" type="text" placeholder="Search ${title}" />
`)
.appendTo( $(column.footer()).empty() )
.on( 'keyup change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column
.search( val )
.draw();
});
}
});
}
});
Working JSFiddle here.
After correction by Mr. Polywhirl (Thank you!) I revisited the problem and adapted a previous answer:
(function() {
$.fn.dataTable.ext.type.search.selected = (data) => !$(data).is("select")
? ''
: $(data).val();
$.fn.dataTable.ext.order['dom-select'] = function(settings, col) {
return this.api().column(col, {
order: 'index'
}).nodes().map(td => $('select', td).val());
}
})();
var table = $('#example').DataTable({
"columnDefs": [{
"orderDataType": "dom-select",
"type": "selected",
"targets": 2
}]
});
$("#example select").on("change", function() {
var $this = $(this),
val = $this.val(),
cellPosition = table.cell($this.parents("td")).index(),
rowDate = table.row(cellPosition.row).data();
$this.find("option").each((k, v) => ($(v).val() === val)
? $(v).attr("selected", "selected")
: $(v).removeAttr("selected"));
rowDate[cellPosition.column] = $this.prop("outerHTML");
table.row(cellPosition.row).data(rowDate);
table.cell(cellPosition).invalidate().draw();
});
Another working example here.
Hope that helps!
Found an answer from this question.
To write our own filtering function, we have to extend the $.fn.dataTable.ext.search function of Datatable.The function has 5 parameters and you need the fourth parameter (the original data source for the row). This fourth parameter is a JavaScript array, where the original HTML code of the given columns of the given rows can be found.
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex,original,counter ) {
var filterValue = $('#filterField').val();
var valueToFilter6 = original[6]; // this is the column with select box
if( valueToFilter6.indexOf('value="' + filterValue) != -1){
return true;
}
return false;
}
);
A complete working example fiddle can be found here.
I have Javascript code using JQuery to create quizzes containing free text, radio buttons (single choice) and check boxes (multiple choice) questions. The quizzes are made using a web interface, with Zurb - Foundation for the style, and are being serialized in JSON. While creating the radio buttons and the check boxes answers for an specific question, when an user checks either component (to mark it as the valid answer, for example), it's supposed to validate this, and come as "true" (represented by the number "1") in the JSON.
It's currently working for the text type question, as it is basically hard-coded. But it's not doing the trick for the other two.
Here's the main pieces of code (If more is needed I'll edit the question): Whole quiz
storeQuiz: function( event ) {
var self = event.data;
var store = [];
$(self.element).find( '.question-content' ).each( function(){
var question = $( this );
var entry = { options: [] };
if ( question.parent().attr( 'class' ).match( /template/ ) ) {
return true;
}
entry['content'] = question.find( '.input' ).val();
entry['type'] = question.parent().attr( 'class' ).match( /quiz-(\w+)/ )[1];
question.find( '.option' ).each( function() {
var option = $( this );
var data = {};
if ( entry.type === 'text' ) {
data['valid'] = true;
} else {
data['valid'] = !!option.find( '.option-validation input' ).attr( 'checked' );
}
data['content'] = option.find( '.option-content textarea' ).val();
entry.options.push( data );
})
store.push( entry );
});
self.storeUpdate( store );
},
Radios:
buildRadios: function( data ) {
var tmpl = this.radiosHandler( {data: this} );
var self = this;
tmpl.find( '.option' ).remove();
tmpl.find( '.input' ).val( data.content );
$.each( data.options, function() {
var plus = tmpl.find( '.add' );
var option = self.addAnswer.call( plus, {data: self} );
option.find( '.option-validation input' ).attr( 'checked', this.valid );
option.find( '.option-content textarea' ).val( this.content );
});
},
Check boxes:
buildCheckboxes: function( data ) {
var tmpl = this.checkboxesHandler( {data: this} );
var self = this;
tmpl.find( '.option' ).remove();
tmpl.find( '.input' ).val( data.content );
$.each( data.options, function() {
var plus = tmpl.find( '.add' );
var option = self.addAnswer.call( plus, {data: self} );
option.find( '.option-validation input' ).attr( 'checked', this.valid );
option.find( '.option-content textarea' ).val( this.content );
});
},
its smarter if you use
$('input[type="checkbox"]').is(':checked');
return value is boolean
Do not use attr() when looking for checked values because it is actually a property so .prop() should be used.
if($('input[type="checkbox"]').prop('checked') === true)
{
// checkbox is checked, uncheck it
$('input[type="checkbox"]').prop('checked', false);
}
else
{
// checkbox is unchecked, check it
$('input[type="checkbox"]').prop('checked', true);
}
If you want to get fancy:
$('input[type="checkbox"]').on('change', function(){
if($(this).prop('checked')){
alert('TRUE : checked');
}
else{
alert('FALSE : unchecked');
}
});
This is the reason that <input type="checkbox" checked> works without needing to do <input type="checkbox" checked="checked">
When you check a checkbox with your mouse then the DOM object's property is set to Boolean TRUE and unchecking switches it to Boolean FALSE
There is another easy way ..
if($('inputSelector')[0].checked == true) {
}
to set the checkbox use
$('inputSelector')[0].checked = true / false;
I solved my problem thanks to a friend with this fix:
data['valid'] = !!option.find( '.option-validation input' ).attr( 'checked' );
Changed to:
data['valid'] = option.find( '.option-validation input' ).is( ':checked' );
After successfully implementing datatables multi-filter to my system for one table, I'd like to implement it for all of my tables, which are organized by several tabs, like shown here.
To reach that, I think I have to set three individual variables:
var oTable0 = $('#tabs-0 table.display').dataTable({
var oTable1 = $('#tabs-1 table.display').dataTable({
var oTable2 = $('#tabs-2 table.display').dataTable({
For filtering, I should need something like:
$("tfoot input").keyup( function () {
/* Filter on the column (the index) of this element */
oTable0.fnFilter( this.value, $("tfoot input").index(this) );
oTable1.fnFilter( this.value, $("tfoot input").index(this) );
oTable2.fnFilter( this.value, $("tfoot input").index(this) );
});
For the table footers I also have to individualize the rows. Here an example for the first table:
<th>
<input type="text" name="search_tabs0_rfid" value="Search column" class="search_init0" />
</th>
<th>
<input type="text" name="search_tabs0_art" value="Search column" class="search_init0" />
</th>
...
For adapting the user friendlyness part I thought of:
$("tfoot input").each( function (i) {
asInitVals0[i] = this.value;
asInitVals1[i] = this.value;
asInitVals2[i] = this.value;
});
$("tfoot input").focus( function () {
if ( this.className == "search_init0" ){ this.className = ""; this.value = "";}
if ( this.className == "search_init1" ){ this.className = ""; this.value = "";}
if ( this.className == "search_init2" ){ this.className = ""; this.value = "";}
});
$("tfoot input").blur( function (i) {
if ( this.value == "" ){ this.className = "search_init0"; this.value = asInitVals0[$("tfoot input").index(this)];}
if ( this.value == "" ){ this.className = "search_init1"; this.value = asInitVals1[$("tfoot input").index(this)];}
if ( this.value == "" ){ this.className = "search_init2"; this.value = asInitVals2[$("tfoot input").index(this)];}
});
Now, the first Tab (#tabs-0) is working fine, but the rest is not.
Maybe the part
$("tfoot input")
Is a problem because this occurs in every one of the three individual tables.
So, how can I get these column searches bound to their specified table? Which part did I miss?
Cheers,
thowi
Whenever you want to isolate instances start from an ancestor element that isolates only the instance elements needed which I think could be tfoot in your case.
$("tfoot input").blur( function (i) {
/* traverse up the document tree to ancestor needed*/
var $parent=$(this).closest('tfoot');
/* index only the inputs in current parent tfoot*/
var index=$parent.find('input').index(this);
/* more code*/
});
If you needed to interact with the dataTables API...can look up to the table itself and do something like:
$parent.closest('table').datatables_API_method()