DataTable jquery selectors not firing - javascript

I have following code to handle clicks on row or individual cells.
$(document).ready(function() {
var JSON_URL = '{% url "technician_activity" %}';
var oTable = $('#technician_activity').dataTable( {
"processing": true,
"serverSide": true,
"ajax": JSON_URL ,
"jQueryUI": true
} );
alert("Without this alert selectors don't work? oTable = " + oTable);
oTable.$('tr').click( function () {
var data = oTable.fnGetData( this );
alert("Column " + data);
});
oTable.$('td').click( function () {
var data = oTable.fnGetData( this );
alert("Cell " + data);
});
});
One thing that puzzels me is without the first alert statement
alert("Without this alert selectors don't work? oTable = " + oTable);
selectors for tr and td don't work this is very puzzling to me -- what is the difference that this alert() is making?

I am now using code as suggested here - http://www.datatables.net/examples/server_side/select_rows.html
But it still remains question as to why the in code I initially posted, with first alert() statement things work but they don't work when that alert statement is absent....
Just for curiosity sake would like to understand whats going on there in case someone has ideas.

Related

javascript works in console but not on page even after adding $(document).ready(function ()

I just can't get this to work. It works fine in the console of Google Chrome. I added $(document).ready(function (). Still no luck. Any help is greatly appreciated. update: I'm trying to get the value of the first cell when the row is selected on a dynamically created html table
Script
<script type="text/javascript">
$.ajax({
url: '#Url.Action("VisitList")',
method: 'post',
dataType: "json",
contentType: 'application/json;charset=utf-8',
data: "{id: 112601}",
success: function (data) {
//alert("success");
$('#divData').removeClass('hidden');
$('#tblBody').empty();
$.each(data, function (index, value) {
var row = $('<tr><td>' + value.JobID + '</td><td>'
+ value.VisitID + '</td><td>'
+ value.VisitDate + '</td><td>'
+ value.VisitInfo + '</td><td>'
+ value.Engineer + '</td></tr>');
$('#tblData').append(row);
});
},
error: function (xhr) {
alert(xhr.responseText);
}
});
$(document).ready(function () {
$("#tblBody tr").click(function (rowElement) {
//alert("hello");
var value = $(this).find('td:first').html();
alert(value);
})
});
</script>
As you are adding rows dynamically, you need to use jQuery.on
$("#tblBody").on("click", "tr", function (rowElement) {
var value = $(this).find('td:first').html();
alert(value);
});
You probably forgot to add a jQuery to the head of your HTML. See the example:
$(document).ready(function(){
alert("Hello World!");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
What is the error?
Try putting this at the start of that Script:
console.log($().jquery);
It should print out the jQuery version so you know jQ is available at that point.
Also, the document might be ready but could it be that you add elements to it later dynamically?
$("#tblBody tr")
Maybe target for this is missing? Not loaded or you targeted poorly?
In any case, if above does not fix the problem, do include error, relevant HTML structure and any additional code that might change HTML in the question to make it a complete one.
PRO TIP: Questions that have plunker or similar available are solved way faster and do attract more people.
You could use .on click event on document something like this:
$(document).on('click', '#tblBody tr', function () {
var value = $(this).find('td:first').text();
alert(value);
});
If you add any data dynamically at that time you should use jquery .on() method.Like this:
$("#tblBody").on("click", "tr", function (rowElement) {
var value = $(this).find('td:first').html();
alert(value);
});

"i" value in JavaScript for loop is not being recognized in a jquery function

I'm using jQuery and ajax to open a bootstrap modal window. My code works perfectly when not in a loop, and my content is displayed appropriately in the modal window. But I have five modals on the page, and naturally I'd like to use a for loop so I don't repeat my code five times.
It seems like a no-brainer to write a for loop to execute the code five times, but somehow, there is a problem, and when I put the code into a for loop, the modal content will not show in the opened window.
Here is code that works how I need it, so the modal content from my modal1.php file shows in a modal popup window. Notice that the i variable is used three times; once in the jQuery selector, and twice in the $.ajax(...) area:
var i = 1;
$('#modal' + i).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
This code below uses the variable i the exact same way as the code above. However, with the code below, the modal1.php content does not show (nor do any of the other files named 'modal[i].php'). Instead, only a blank dark background appears when they are opened.
for (i = 1; i < 6; i++) {
$('#modal' + i).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
}
So I don't understand why the $.ajax() area of the code won't recognize the i variable in the for condition, but it will recognize it in the initial jQuery selector $('#modal' + i), which I've tested and found to be true. Is there a way I can write this loop so that the ajax area will recognize the i variable? Or is there a mistake in my code that I'm overlooking?
Incidentally, I've noticed that similar questions have been asked, but they have been downvoted for not being clearly written. I've read them all, and they don't answer the question that I have today.
The problem here is that you are (unintentionally) referencing a variable (i) via a closure.
Since scope is dictated by function in JavaScript, wrap your on usage with another (immediately invoked) function so a unique i is saved:
for (i = 1; i < 6; i++) {
(function() {
var iModalNumber = i;
$('#modal' + iModalNumber).on('show.bs.modal', function(e) {
var id = e.relatedTarget.dataset.id;
$.ajax({
type:'post',
url:'modals/modal' + iModalNumber + '.php',
data:{id:id},
success:function(data){
$('#modal' + iModalNumber).html(data);
}
});
});
}());
}
The reason that these questions get down-voted so much is because issues/misunderstanding of closures is so common. It is admittedly a difficult concept to grasp, and your question was well written.
More information: How do JavaScript closures work?
You could probably do this without using loop but using jQuery .each() and adding value attributes to your html elements. Warning... untested code ahead.
jQuery('.modal').each(function(){ // use a class instead of an id
$(this).on('show.bs.modal', function(e) { //use $(this) to target
var i = $(this).val(); // get the value id
var id = e.relatedTarget.dataset.id; // do your code
$.ajax({
type:'post',
url:'modals/modal' + i + '.php',
data:{id:id},
success:function(data){
$('#modal' + i).html(data);
}
});
});
});

how to enable and disable paging from jquery dataTables on button click

Following is the code found in data table website in order to remove the paging.
$(document).ready(function() {
$('#example').DataTable( {
"paging": false
} );
} );
My question is how to enable and disable paging on button click.
as when i call DataTable function second time to same table. It shows error that data table is already initiated and im calling it second time.
simply recreate the dataTable using destroy: true and paging:
I wanted to show only the first 10 rows of the table, but still be able to sort the whole table. But I also wanted the ability to click a link and show the whole table.
Here's what I did: (my table is "ka_ad")
First, turn on paging
table_ad = $('#ka_ad').DataTable({
paging: true,
});
Second (optional: I didn't want to display the datatable pagination links and element, so I hid them with css
#ka_ad_length{display: none;}
#ka_ad_paginate{display: none;}
Lastly, toggle the bPaginate setting (I have a button with an ID of "test"):
$('#test').click( function () {
//console.log(mytable.settings()[0]['oFeatures']['bPaginate'] );
if(table_ad.settings()[0]['oFeatures']['bPaginate'] == false)
{
table_ad.settings()[0]['oFeatures']['bPaginate'] = true;
$('#test').html('Show All Rows');
}
else
{
table_ad.settings()[0]['oFeatures']['bPaginate'] = false;
$('#test').html('Show Fewer Rows');
}
table_ad.draw();
});
Try like this.
var oTable;
$(document).ready(function() {
oTable = $('#example').DataTable( {
"paging": false
} );
$('.btn').click( function () {
oTable.paging= false;
oTable.fnDraw();
});
} );
try this:(but i don't guarantee, because, i haven't tested)
var oTable = $('#example').dataTable();
// get settings object after table is initialized
var oSettings = oTable.fnSettings();
oSettings.paging = false;
$(".button").click(function(){
oSettings.paging = !oSettings.paging;
});
https://www.datatables.net/forums/discussion/16373/enable-disable-features-after-initializing-the-table

Accessing the wysihtml5 editor object to use it inside "events"?

I found this in the documentation of bootstrap-wysihtml5:
The underlying wysihtml5 object
You can access the wysihtml5 editor object like this:
var wysihtml5Editor = $('#some-textarea').wysihtml5().data("wysihtml5").editor;
wysihtml5Editor.composer.commands.exec("bold");
So I tried this:
<script type="text/javascript">
var myCustomTemplates = {
link : function(locale) {
return "<li>" +
"<div class='bootstrap-wysihtml5-insert-link-modal modal hide fade'>" +
"<div class='modal-header'>" +
"<a class='close' data-dismiss='modal'>×</a>" +
"<h3>" + locale.link.insert + "</h3>" +
"</div>" +
"<div class='modal-body'>" +
"<input value='http://' class='bootstrap-wysihtml5-insert-link-url input-xlarge'>" +
"</div>" +
"<div class='modal-footer'>" +
"<a href='#' class='btn' data-dismiss='modal'>" + locale.link.cancel + "</a>" +
"<a href='#' class='btn btn-primary' data-dismiss='modal'>" + locale.link.insert + "</a>" +
"</div>" +
"</div>" +
"<a class='btn' data-wysihtml5-command='createLink' title='" + locale.link.insert + "'><i class='icon-link'></i></a>" +
"</li>";
},
"font-styles": function(locale, options) {
return "<li>" +
"<a class='logo'>Logo</a>" +
"</li>" +
"<li>" +
"<a class='btn btn-paragraph' data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='p'>" + locale.font_styles.p + "</a>" +
"</li>" +
"<li>" +
"<a class='btn btn-paragraph' data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='p'>" + locale.font_styles.p + "</a>" +
"</li>";
}
}
$('#wysihtml5-textarea').wysihtml5('deepExtend', {
"font-styles": true, //Font styling, e.g. h1, h2, etc. Default true
"emphasis": true, //Italics, bold, etc. Default true
"lists": true, //(Un)ordered lists, e.g. Bullets, Numbers. Default true
"html": true, //Button which allows you to edit the generated HTML. Default false
"image": false, //Button to insert an image. Default true,
"link": false,
"format-code": false, // enable syntax highlighting
customTemplates: myCustomTemplates,
"events": {
"focus": function() {
//var wysihtml5Editor = $('#wysihtml5-textarea').wysihtml5().data("wysihtml5").editor;
//wysihtml5Editor.composer.commands.exec("insertHTML", "<a href=...>");
}
},
parserRules: {
tags: {
p: {}
}
},
"stylesheets": ["<%= root_url %>wysiwyg-color.css", "<%= root_url %>github.css"], // CSS stylesheets to load
});
</script>
But it seems like it is breaking the code:
GET http://localhost:3000/posts/lib/css/wysiwyg-color.css 404 (Not Found)
And wysihtml5Editor.composer.commands.exec is not working either.
(The file loads just fine if I don't include the content inside "focus": function() {)
What the right way of doing this?
EDIT
Here's a minimally working code, to use as a starting point:
// I use this to keep this code out of the global scope.
// This takes this form: (function($){...})(jQuery);
// and allows me to use $ without worry about it interfering
// with other libraries and frameworks that share it's use.
(function priv($) {
// This is another scope thing; I can set the reference
// later on, but it will be in the parent scope, so I
// can cache these and then access them from within a
// window.onload handler, for instance, that I create
// further down.
var $editor,
opts;
// A more elegant, clean way of doing what was in the docs.
opts = {
// Note, it's not necessary to use quotes on labels in
// object notation, UNLESS there's something not allowed.
// This and format-code have comments ONLY because they
// have that infernal dash in there. No others in this
// list do, however.
'font-styles': false,
'format-code': false,
emphasis: true,
lists: true,
html: false,
image: false,
link: false,
events: {
// Passing a reference to a function I've declared
// later. I could not have this before the actual
// functions, though, if I use var onload = function...
// since "hoisting" does not occur. So, be careful
// emulating this too liberally if you don't under
// why it works.
load: onload,
focus: onfocus,
blur: onblur
}
};
// I'm using the `window.onload` method to setup my editor
// AFTER the page has loaded and the DOM is ready.
$(window).on('load', function load() {
// See, I set this up here, and can access it in the
// onload, onfocus, and onblur handlers without
// requerying. It's called caching a reference.
$editor = $('#wysihtml5-textarea');
$editor.wysihtml5(opts);
});
function onload() {
console.log('load');
}
function onfocus() {
console.log('focus');
}
function onblur() {
console.log('blur');
}
})(jQuery);​
http://jsfiddle.net/userdude/nWebx/5/
I put the wysihtml5 editor demo in a properly running fiddle and then modified it to run your referenced code:
$(window).on('load', function load(){
/*$('.textarea').wysihtml5();
$(prettyPrint);*/
$('#wysihtml5-textarea').wysihtml5('deepExtend', {
"font-styles": true, //Font styling, e.g. h1, h2, etc. Default true
"emphasis": true, //Italics, bold, etc. Default true
"lists": true, //(Un)ordered lists, e.g. Bullets, Numbers. Default true
"html": true, //Button which allows you to edit the generated HTML. Default false
"image": false, //Button to insert an image. Default true,
"link": false,
"format-code": false, // enable syntax highlighting
customTemplates: myCustomTemplates,
"events": {
"focus": function() {
var wysihtml5Editor = $('#wysihtml5-textarea').wysihtml5().data("wysihtml5").editor;
wysihtml5Editor.composer.commands.exec("insertHTML", "<a href=...>");
}
},
parserRules: {
tags: {
p: {}
}
},
"stylesheets": ["<%= root_url %>wysiwyg-color.css", "<%= root_url %>github.css"], // CSS stylesheets to load
});
})
http://jsfiddle.net/userdude/nWebx/2/
With this as-is, I receive this error in Chrome Console:
Uncaught ReferenceError: myCustomTemplates is not defined
So I comment that line out, and it runs. Try it:
http://jsfiddle.net/userdude/nWebx/1/
Now, I am running the editor code within a window.onload event using jQuery's $.on() event handler method:
$(window).on('load', function load(){
$('#wysihtml5-textarea').wysihtml5('deepExtend', {
...
});
}) // <<< I'd try to always using `;` at the end of statements.
And I also get no errors with the focus handler, although I need to check that it's event running to beginning with. So, what is in myCustomTemplates?
Try something like this:
var wysihtml5Editor = $('#some-textarea').wysihtml5().data("wysihtml5").editor;
wysihtml5Editor.composer.commands.exec("bold");
var focusHanlder = function(){
console.log(wysihtml5Editor);
wysihtml5Editor.composer.commands.exec("insertHTML", "<a href=...>");
}
var secondFocusHandler = function(){
console.log(this);
this.composer.commands.exec("insertHTML", "<a href=...>");
}.bind(wysihtml5Editor);
where focusHandler uses the exterior variable wysihtml5Editor and secondFocusHanlder uses that variable as this inside the call. Now pass one of those variable to the focus event.
Here is a little example of using the events on wysihtml5Editor: https://github.com/xing/wysihtml5/wiki/Events

DataTables jquery identifying row ID

I am using DataTables and capturing am img click on either edit or delete icon's. My problem is, I need to capture the row ID as well.. I tried putting the row ID in the href tag but npt able to extract it..
The current code is
$('#datatable tbody tr a.delete img').live( 'click', function (e) {
var rowID = $('a').attr('href');
alert(rowID);
if (!fancyConfirm(rowID, "Are you sure you want to delete this record?", function(ret) { alert(rowID) }))
e.preventDefault();
});
You can see the actual page at http://www(#)fisheragservice(#)com/tm/users(#)html
Please replace the (#)'s with .'s because the page contans actual email addresses I rather not have a spma bot find..
Can't you just attach the click event on the link instead of the img inside it and then use this?
$('#datatable tbody tr a.delete').live( 'click', function (e) {
var rowID = $(this).attr('href');
alert(rowID);
if (!fancyConfirm(rowID, "Are you sure you want to delete this record?", function(ret) { alert(rowID) }))
e.preventDefault();
});
Example link
You care selecting all the anchors using $('a') to get the rowID. That will not work. Instead use the parent().attr() function in the click handler. i.e.:
$('#datatable tbody tr a.delete img').live( 'click', function (e) {
var rowID = $(this).parent().attr('href');
alert(rowID);
if (!fancyConfirm(rowID, "Are you sure you want to delete this record?", function(ret) { alert(rowID) }))
e.preventDefault();
});
I am unsure if you are looking for the actual table row, or if the row
has some meaningful information like a database key.
if you indeed looking at a row id, consider the example below, which
uses the fnRender attribute.
var oTable = $('#inventory_list').dataTable ({
'bServerSide' : true,
'bAutoWidth' : false,
'bJQueryUI' : false,
'sPaginationType': 'full_numbers',
'sAjaxSource' : '/inventory/listall',
'aoColumns' :
[
{
'bSearchable': false,
"bSortable": false,
"fnRender" : function ( oObj )
{
var colval = '<div class="editcol"><a href="/inventory/edit/' +
oObj.aData[0] + '">' +
'<img src="/img/edit.png" alt="edit"><a/>' +
'<a href="/inventory/delete/' + oObj.aData[0] + '">' +
'<img src="/img/delete.png" alt="delete"><a/>' +
'</div>';
return colval;
}
},
null,
null,
null,
null,
null,
null,
null,
null,
null
]
});
The first column (out of 10) contains the edit/delete icons.
The listall call to the server return the inventory id in the first
cell, which is referenced by oObj.aData[0], ans used to build the URL.

Categories