Ok so I have this datatable with around 90 fields being populated from a dbContext (Visual Studio MVC4). I added the .makeEditable() to enjoy inline editing...
Most of my fields are of a type string (but a user CAN input a date if he opts to....even though its a text type field, the date will be input as simple text..)
The problem I have is that even though I'm successfully being able to get the class of the edit form to become "datepicker", the calender isn't popping up and on other simple non-datatable pages, it runs just fine.
I want to be able to set certain column cells to have inline datepicking ability..
I want my table to look like this thing http://jquery-datatables-editable.googlecode.com/svn/trunk/inline-edit-extra.html
I tried mimic-ing the code there but with no success....its always a textbox for editing instead of a calender view..
UPDATE: I noticed that if I change the "type:" field in
$.fn.editable.defaults = {
name: 'value',
id: 'id',
type: 'datepicker',
width: 'auto',
height: 'auto',
event: 'click.editable',
onblur: 'cancel',
loadtype: 'GET',
loadtext: 'Loading...',
placeholder: 'Double-Click to edit',
loaddata: {},
submitdata: {},
ajaxoptions: {}
};
My entire table gets a datepicker on editing mode...
Apparently the intializing code to give certain columns datepicker options doesn't work as it should ....or at least I guess so
**UPDATE END****
This is my datatable initialization code:
<script language="javascript" type="text/javascript">
$(function() {
$(".datepicker").datepicker({ dateFormat: 'dd-MM-yy' });
});
$(document).ready(function ()
{
$('#myDataTable thead tr#filterrow th').each(function () {
var title = $('#myDataTable thead th').eq($(this).index()).text();
$(this).html('<input type="text" onclick="stopPropagation(event);" placeholder="Search ' + title + '""style="direction: ltr; text-align:left;" />');
});
$("#myDataTable thead input").on('keyup change', function () {
table
.column($(this).parent().index() + ':visible')
.search(this.value)
.draw();
});
var table = $('#myDataTable').DataTable({
//"scrollY": "200",
"scroller": "true",
"deferRender": "true",
"orderCellsTop": "true",
"columnDefs": [
{ "visible": false, "targets": 1 },
{ "type": "datepicker", "aTargets": [6,7,8,9,10] },
{ 'sClass':"datepicker", "aTargets": [6, 7, 8, 9, 10] }
],
"order": [[1, 'asc']],
"displayLength": 25,
"drawCallback": function (settings)
{
$(".datepicker").datepicker({ dateFormat: 'dd-MM-yy' });
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(1, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
'<tr class="group"><td colspan="88">' + group + '</td></tr>'
);
last = group;
}
});
},
"fndrawCallback": function (settings) {
$(".datepicker").datepicker({ dateFormat: 'dd-MM-yy' });
}
});
// Apply the search
table.columns().every(function () {
var that = this;
$('input', this.header()).on('keyup change', function () {
that
.search(this.value)
.draw();
});
});
// Order by the grouping
$('#myDataTable tbody').on('click', 'tr.group', function () {
var currentOrder = table.order()[0];
if (currentOrder[0] === 1 && currentOrder[1] === 'asc') {
table.order([1, 'desc']).draw();
}
else {
table.order([1, 'asc']).draw();
}
});
//$('#myDataTable thead').append($('#myDataTable thead tr:eq(0)')[0]);
$('#myDataTable').dataTable().makeEditable({
"aoColumnDefs": [
{ "type": "hasDatepicker", "aTargets": 4 },
{ "sClass": "hasDatepicker", "aTargets": 4 }
]
});
});
function stopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
} else {
evt.cancelBubble = true;
}
}
this is the datepicker.js
// add :focus selector
jQuery.expr[':'].focus = function (elem) {
return elem === document.activeElement && (elem.type || elem.href);
};
$.editable.addInputType(' datepicker', {
/* create input element */
element: function (settings, original) {
var form = $(this),
input = $('class ="datepicker" <input />');
// input.attr('class', 'datepicker');
input.attr('autocomplete', 'off');
form.append(input);
return input;
},
/* attach jquery.ui.datepicker to the input element */
plugin: function (settings, original) {
var form = this,
input = form.find("input");
// Don't cancel inline editing onblur to allow clicking datepicker
settings.onblur = 'nothing';
datepicker = {
onSelect: function () {
// clicking specific day in the calendar should
// submit the form and close the input field
form.submit();
},
onClose: function () {
setTimeout(function () {
if (!input.is(':focus')) {
// input has NO focus after 150ms which means
// calendar was closed due to click outside of it
// so let's close the input field without saving
original.reset(form);
} else {
// input still HAS focus after 150ms which means
// calendar was closed due to Enter in the input field
// so lets submit the form and close the input field
form.submit();
}
// the delay is necessary; calendar must be already
// closed for the above :focus checking to work properly;
// without a delay the form is submitted in all scenarios, which is wrong
}, 150);
}
};
if (settings.datepicker) {
jQuery.extend(datepicker, settings.datepicker);
}
input.datepicker(datepicker);
}
});
So after a lot of trial and error.....
I manually input the type of each of my 90 columns, and it manually worked....columnDefs with targeting a list of columns is probably bugged as in jeditable.datepicker it doesn't parse a list of columns passedin the settings....
Hope this helps a lost soul later on...
Related
I am new on javascript and I am trying to combine 2 javascript blocks but I am falling apart?
FIRST BLOCK
<script>
$(document).ready(function() {
// Setup - add a text input to each footer cell
$('table.table tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="'+title+' ARA" />' );
} );
// DataTable
var table = $('table.table').DataTable();
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
</script>
SECOND BLOCK
$('table.table').DataTable({
"order": [
[0, "desc"]
],
paging: true,
"oLanguage": {
"sUrl": "js/dil/LANGUAGE.json",
}
} );
I want to add "oLanguage" and "order" lines to first javascript. What should I do?
Just copy-paste array from DataTables to first part:
$(document).ready(function() {
// Setup - add a text input to each footer cell
$('table.table tfoot th').each(function () {
$(this).html('<input type="text" placeholder="'+$(this).text()+' ARA" />');
});
// DataTable
var table = $('table.table').DataTable({
order: [
[0, "desc"]
],
paging: true,
oLanguage: {
sUrl: "js/dil/LANGUAGE.json",
}
});
// Apply the search
table.columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
});
});
});
Note DataTables used to have it's variables in hUngarianNotation and later on moved to camlCase, so it's most likely your oLanguage is not recognized by new API
jquery autocomplete for a textbox should not allow data other than the autocomplete list.,but the problem is i need to allow only data from the list autocomplete list but not any other data, even if the user enter any another data we i need to show a message that please select from the autocomplete list.
The link show below is also allowing any data other than the autocomplete suggestions:
$("#field").autocomplete({
source: countries_starting_with_A,
minLength: 1,
select: function(event, ui) {
// feed hidden id field
$("#field_id").val(ui.item.id);
// update number of returned rows
$('#results_count').html('');
},
open: function(event, ui) {
// update number of returned rows
var len = $('.ui-autocomplete > li').length;
$('#results_count').html('(#' + len + ')');
},
close: function(event, ui) {
// update number of returned rows
$('#results_count').html('');
},
// mustMatch implementation
change: function (event, ui) {
if (ui.item === null) {
$(this).val('');
$('#field_id').val('');
}
}
});
http://jsfiddle.net/handtrix/32Bck/
There are lots of ways to do this. Here is one suggestion:
Working Example: http://jsfiddle.net/Twisty/32Bck/560/
HTML
<div class="ui-widget" style="position: relative;">
<input type="text" placeholder="type something ..." id="suggest" />
</div>
CSS
body {
padding: 30px;
}
input.ui-state-alert {
border: 1px inset #F00;
}
JavaScript
var makeSelect = false;
$(document).ready(function() {
function requiredValid(target) {
target = $(target);
// Return Focus
target.focus();
// Add alert class
target.addClass("ui-state-alert");
$("<div>", {
class: "required-alert-text",
style: "color: #F00; font-size: 10px; display: inline-block; position: absolute;"
}).html("Must select from list.").insertAfter(target).position({
my: "bottom",
at: "top+5",
of: target
});
}
$("#suggest").autocomplete({
delay: 100,
source: function(request, response) {
// Suggest URL
var suggestURL = "http://suggestqueries.google.com/complete/search?client=chrome&q=" + request.term;
// JSONP Request
$.ajax({
method: 'GET',
dataType: 'jsonp',
jsonpCallback: 'jsonCallback',
url: suggestURL
})
.success(function(data) {
response(data[1]);
});
},
select: function(e, ui) {
makeSelect = true;
},
close: function(e, ui) {
if (makeSelect) {
makeSelect = false;
$(".ui-state-alert").removeClass("ui-state-alert");
$(".required-alert-text").remove();
} else {
requiredValid(this);
}
}
});
$(".ui-state-alert").on("blur", function() {
$(this).focus();
})
});
This will not cover all cases. Basically, we want to know if the user made a selection from the list. I created makeSelect and assigned it as false. We assume upfront that the user has not done this.
When the user selects a list option, select callback is triggered and updates out variable. This also triggers close callback as it is now closing the list. If the user has made a selection, we move one and reset for the next time. If not, we apply some techniques to alert the user and keep focus until they make a selection.
How can I get my tooltip being displayed when using pagination within the datatable plugin?
I am using the plugin protip in connection with datatables to display tooltips, when text inside a column is too long. The tooltips plugin already works with the following snippet:
//Datatable Setup
jQuery(document).ready(function($) {
var table = $('#irp-table.raab').DataTable({
"columnDefs": [
{ visible: false, targets: 2 },
{ className: 'mdl-data-table__cell--non-numeric', targets: [0, 1]}
],
"order": [[ 0, 'asc' ]],
"displayLength": 25,
"drawCallback": function ( settings ) {
var api = this.api();
var rows = api.rows( {page:'current'} ).nodes();
var last=null;
api.column(2, {page:'current'} ).data().each( function ( group, i ) {
if ( last !== group ) {
$(rows).eq( i ).before(
'<tr class="group"><td colspan="3">'+group+'</td></tr>'
);
last = group;
}
} );
}
} );
//Initialize ToolTip
jQuery(document).ready(function($) {
$.protip();
});
//ToolTip hover behaviour
jQuery(document).ready(function($) {
$('td').bind('mouseenter', function () {
var $this = $(this);
if (this.offsetWidth < this.scrollWidth) {
var text = $this.text();
$this.attr("data-pt-title", text);
$this.protipShow()
}
}).mouseenter();
});
However it just works on the first site for the case I am using pagination on my datatable and navigate to another site.
SOLUTION
You need to use drawCallback to initialize tooltips every time DataTables redraws the table. This is needed because TR and TD elements for pages other than first are not present in DOM at the time first page is displayed.
Also the call to mouseenter() is not needed.
For example:
"drawCallback": function ( settings ) {
var api = this.api();
// ... skipped ...
$.protip();
$('td', api.table().container()).on('mouseenter', function () {
var $this = $(this);
if (this.offsetWidth < this.scrollWidth) {
var text = $this.text();
$this.attr("data-pt-title", text);
$this.protipShow();
}
});
}
LINKS
See jQuery DataTables: Custom control does not work on second page and after for more examples and details.
I would like to use a pagination style for DataTable's that is mobile friendly, I'd just like a button to load more rows when clicked which will append rows under the current visible rows.
I know this isn't available as a default option in DataTables but I believe it shouldn't be to difficult to create. Has anyone created this pagination method or seen it in use on a DataTable's table?
If not how can I modify the code of my table at https://jsfiddle.net/6k0bshb6/16/ to use this pagination style to make my table mobile friendly.
// This function is for displaying data from HTML "data-child-value" tag in the Child Row.
function format(value) {
return '<div>Hidden Value: ' + value + '</div>';
}
// Initialization of dataTable and settings.
$(document).ready(function () {
var dataTable = $('#example').DataTable({
bLengthChange: false,
"pageLength": 5,
"pagingType": "simple",
"order": [[ 7, "asc" ]],
"columnDefs": [
{
"targets": [ 5 ],
"visible": false,
"searchable": true
},
{
"targets": [ 6 ],
"visible": false,
"searchable": true
},
{
"targets": [ 7 ],
"visible": false,
"searchable": true
}
],
// Dropdown filter function for dataTable from hidden column number 5 for filtering gifts.
initComplete: function () {
this.api().columns(5).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.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>')
});
});
}
});
// This function is for handling Child Rows.
$('#example').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = dataTable.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(tr.data('child-value'))).show();
tr.addClass('shown');
}
});
// Checkbox filter function below is for filtering hidden column 6 to show Free Handsets only.
$('#checkbox-filter').on('change', function() {
dataTable.draw();
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = '£0.00';
var position = data[6]; // use data for the position column
if($('#checkbox-filter').is(":checked")) {
if (target === position) {
return true;
}
return false;
}
return true;
}
);
});
UPDATE: I have found some information on how to do this on the DataTables website although I don't fully understand how to integrate it into my table.
https://datatables.net/forums/discussion/3920/twitter-facebook-style-pagination
What you could possibly do (I've not tried it, but I can't think of why it wouldn't work...) is to set the scroll loading gap (the number of pixels before the bottom of the scroll for when the new data is loaded) to a negative number ( http://datatables.net/usage/options#iScrollLoadGap ) and then add a little button at the bottom of the table (might need to use fnDrawCallback for that) which when clicked will load the next data set (fnPageChange('next') should do that).
Anyone know how I can make this work with my table? Could someone show me how to do this on jsfiddle?
UPDATE 2: Response from datatables admin https://datatables.net/forums/discussion/35148/load-more-style-twitter-style-pagination-custom#latest
The iScrollLoadGap option you mention isn't available in 1.10 -
infinite scrolling was removed in 1.10 and that option with it.
However the basic principle still remains - you can either have a
button the user needs to press to load more rows (either increase the
page size or use rows.add() to add more rows) or use a scroll
detection to do the same thing.
Allan
Solved..
<button id="button" type="button">Page +5</button>
//Alternative pagination
$('#button').on( 'click', function () {
var VisibleRows = $('#example>tbody>tr:visible').length;
var i = VisibleRows + 5;
dataTable.page.len( i ).draw();
} );
you could use something like:
$(window).on("swipeleft", $("#example_next").click());
$(window).on("swiperight", $("#example_previous").click());
it will only work on mobile and uses your existing functionality...
I'm trying to allow users to delete multiple records, they click a link "delete" and a dialog shows saying are you sure? On clicking OK it should delete.
It works for the first time I do it, but for any other delete buttons I click it doesn't work. I'm setting a hidden field to store some information then getting that information in the dialog.
I have identified the problem see comment in code, but not sure why its a problem.
This is for the delete buttons:
$(".delete-item").click(function () {
$(this).css('font-weight', 'bold');
var delId = $(this).attr("id");
$("#hidden-itemid").val(delId);
$("#dialog-delete-sure").dialog("open");
});
heres the dialog:
$("#dialog-delete-sure").dialog({
autoOpen: false,
resizable: false,
height: 140,
modal: true,
buttons: {
Ok: function () {
var hiddenId = $("#hidden-itemid").val();//*** This comes back undefined the second time***//
var itemId = $("#hidden-itemid").val().split('-')[1];
var iType = $("#hidden-itemid").val().split('-')[0];
$.post('/User/Delete/', { id: itemId, itemType: iType }, function (json) {
if (json.success) {
$("#" + iType + "-row-" + itemId).hide('slow', function () { $("#hidden-itemid").remove(); });
$("#dialog-success-delete").dialog("open");
} else {
if (json.error == "unknown") {
$("#dialog-unknown-error").dialog("open");
}
if (json.error == "unauthenticated") {
$("#dialog-unauthenticated").dialog("open");
}
}
});
$("#hidden-itemid").css('font-weight', 'normal');
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
a typical delete button looks like this:
<a id="event-63" class="delete-item">Delete</a>
any ideas?
You are running
$("#hidden-itemid").remove();
on json.success so you remove the element from the DOM .. next time it does not exists and thus you get an error..