I am having an issue with jQuery's Datatable plugin... I have filled a table, and a specific column has cells looking like this:
12
I have prevented the onclick event and it triggers this code:
$( 'a[name="PO"]' ).click(function(){
event.preventDefault();
var POid = $( this ).attr('href');
var element = $( this );
$( '<div id="Dialog">\
<p class="error"></p>\
<p style="text-align:center;" class="main">Entrez le P.O. associé à la commande</p>\
<input type="text" class="POprompt"/>\
</div>').dialog({
resizable: false,
height: 'auto',
width:'400',
modal: true,
title: 'Ajout d\'un PO',
show: 'blind',
hide: 'drop',
buttons:{
"Sauvegarder":function() {
$('.error').css('color','FF0000');
var prompt = $('.POprompt').val();
if (!isNaN(parseInt(prompt)))
{
$.post('setPO.php',{'PO':prompt,'id':POid},function(data)
{
element.text( prompt );
$('.main').css('color','#0F0');
$('.POprompt').css('visible','false');
$('.main').text("L\'ajout a été effectué avec succès.")
$( this ).dialog( "close" );
$('.error').text("");
$('.error').css('color','#FFF');
});
}
else
{
var error = $('.error');
error.text("Veuillez entrer des chiffres seulement.");
error.addClass( "ui-state-highlight" );
setTimeout(function() {
error.removeClass( "ui-state-highlight", 1500 );
}, 1000 );
}
$('.error').css('color','FF0000');
},
"Annuler":function()
{
$( this ).dialog( "close" );
}
}
} );
});
But when I go on page 2 or 3, or when I sort results and click on that cell link but that the row was generated in another page than the first one, the javascript does not trigger.
Anyone has an idea? Thanks a lot in advance guys, and have a nice day.
I realize that this question has been answered, however, it's incomplete and with all due respect possibly wrong. The issue with the mutipage datatable is that the initial selector is rendered useless with the user clicks on ANY of the pages other than the default first page. This is because dataTable does some horrible things to the DOM in order to render the table. This has the side effect of disabling your click handler.
The good news is that there is a way to handle this other than listing ALL elements.
instead of...
$( 'a[name="PO"]' ).click(function(){
try this:
$( "#dataTable tbody" ).on('click', 'a[name="PO"]', function(){
Read this jquery page ( on() ) and look for the section on deferred selectors.
Because when the javascript insert element to document it doesn't have onclick. jQuery will not add onclick to them, automatically.
Solution: Call this script every time data loaded (when user changes page or sorts table).
I finally got everything to work fine by adding this:
"bLengthChange": true,
to my datatable declaration.
I also modified the <select> options, adding a "show all" option which loads all the rows by default, but only shows 5 rows on pageload since I set "iDisplayLength": 5.
Here is how to add a "show all" value to your length select input (sum):
$(document).ready(function(){
$('table').dataTable({
"bLengthChange":true,
"bFilter":true,
"iDisplayLength": 5,
"sDom":'<"H"lfr>t<"F"ip>',
"oLanguage":{
"sUrl": "dataTables.txt"
}
});
});
The text file contains all your translations (if you need them) and your custom SELECT:
{
"sProcessing": "Processing...",
"sLengthMenu": "Show <select><option value=-1>INFINITE</option></select> results"
}
Note: of course I added other options to my select AND datatable declaration, it is just easier to read this way. The value=-1 part is how to get javascript to load on ALL rows/cells.
Thanks to the guys who tried helping me out, both of your answers were useful to me!
Related
I'm trying add auto-reload a page where I have div in form of a table with only rows that include username.
Using https://github.com/stidges/jquery-searchable to search for username inside div here's the website http://tntdroid.xyz/global.php
If I auto-reload the container the search stops working.
Does anyone know if there's a way to make this work. or an alternative
$(function worker(){
$("#searchable-container").load('lib/global.php');
setTimeout(worker, 10*1000);
});
$(function () {
$( '#searchable-container' ).searchable({
searchField: '#container-search',
selector: '.list-group-item',
childSelector: '.col-md-4',
show: function( elem ) {
elem.slideDown(100);
},
hide: function( elem ) {
elem.slideUp( 100 );
}
})
});
After reloading the content, you need to re-create the searchable.
Do this by re-calling
$( '#searchable-container' ).searchable({
...
});
This is needed because the complete element - with all its listeners - gets erased and overwritten.
I am trying to add a picture and text to my JQuery Dialog box yet I am having problems, I'm new to JQuery but can't seem to find anything wrong with the code. Anyone have any ideas on what the problem is ?
$(function() {
$( ".dialog" ).click(function(){
$('#dialog').append('<img src="Image here"/><br/>').append($(this).html());
$('#dialog').html("The Football Game ") + $(this).html() + " Is now playing")dialog({
resizable:true,
modal:true,
height: 350,
width: 500,
buttons: {
"Ok": function()
{
$(this).dialog('close');
},
"Cancel": function()
{
$(this).dialog('close');
}
}
});
});
});
Using your very example, slightly rewritten.
HTML markup to trigger dialog:
<div id="dialog" title="Basic dialog">
<p>Here's some content</p>
</div>
<!-- a HTML element with the class "dialog" to trigger the event -->
<input type="button" class="dialog" value="Trigger Dialog"/>
Your jQuery example modified:
$(document).ready(function(){
$('.dialog').click(function(){ //use a better selector to trigger this event..
var fetchHTML = $('#dialog').html(); //fetch the current HTML of your element with the ID "dialog" and save it within a variable
$('#dialog').html('<img alt="" src="someimage.png"/>'+ fetchHTML); // add your image to the element and then the HTML that was there before. The method htm() will overwrite everything that was there before
$('#dialog').dialog({ //use the jquery-ui dialog method with selected parameters
resizable : true,
modal : true,
height : 350,
width : 500,
buttons: {
"Ok": function(){
$(this).dialog('close');
},
"Cancel": function(){
$(this).dialog('close');
}
}
});
});
});
And remember to make sure that you have successfully included:
jQuery
jQuery-ui
jQuery-ui CSS stylesheet (or at least the appropriate classes that you need).
Google hosts them all for you https://developers.google.com/speed/libraries/devguide. Easy as pie to just copy and paste them within your document
Whenever developing web applications I use FireFox and have installed extensions such as FireBug, WebDeveloper and YSlow. They're of great help :) Just saying...
One
The main issue I see is in the line below:
$('#dialog').html("The Football Game ") + $(this).html() + " Is now playing")dialog({
There is an extra ) which is closing the html() and you are missing a . before calling dialog().
$('#dialog').html("The Football Game " + $(this).html() + " Is now playing").dialog({
Two
Also, you are calling html() after append(), essentially overwriting the appended content. Try using append() after html() (or combine all the content into the html() call):
$('#dialog')
.html('<img src="http://dummyimage.com/600x400/000/fff"/><br/>')
.append("The Football Game "+ $(this).html() + " Is now playing")
.dialog({ ...
Working Example
Proper abstraction aside, how can I grab the 'title' option of a jQuery dialog amongst multiple scripts?
For example, below I have 2 scripts where the first returns a var as a string, where the other does not return the variable as a string:
<script>
$(function() {
$( ".scheduleDiv" ).dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
Cancel: function() {
$( this ).dialog( "close" );
}
});
$( ".device-modal" )
.click(function() {
$( ".scheduleDiv" ).dialog({"title": $(this).attr('title')});
alert($( ".scheduleDiv" ).dialog('option', 'title'));
var single = $(this).dialog('option', 'title'); //works as expected
$( ".scheduleDiv" ).dialog( "open" );
return false;
});
});
</script>
<script>
$(document).ready(function() {
$('.locks').hide();
$('.device_groups').hide();
var single = $(this).dialog('option', 'title'); //is undefined...
if (single == "Add Single Lock") {
$('.locks').show();
//$('.locks select').removeAttr('disabled');
}
else {
$('.device_groups').show();
//$('.device_groups select').removeAttr('disabled');
}
});
</script>
So, how can I set 'single' to return the title as a string in the second script?
Many Thanks
Your context of this is likely not correct. When you handle the $(document).ready() event, this is the document. You need to manually grab your dialog window, and then get the title:
$('.scheduleDiv').dialog('option', 'title');
The code you are using to get the title is firing ondocumentready, but your initialization doesn't actually set a title. You are not setting the title until you click the 'deviceModal'. At that point, the code to log the title will not get re-fired, as the document only loads once.
I have a table that, when any row is clicked, launches a jQueryUI modal dialog box to allow users to edit that record. I use the following script which seems to work, successfully loading the relevant record's details in using AJAX:
$("#datatbl tr").bind('click', function() {
var url = 'item_edit.asp?id='+$(this).attr("data-myid");
var dialog = $('<div style="display:hidden" title="Record details:"></div>').appendTo('body');
// load remote content
dialog.load(
url,
{},
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
height: 440,
width: 550,
autoOpen: false,
modal: true,
buttons: {
"Update this record": function() {
$('#editform').submit();
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
dialog.dialog('open');
}
);
//prevent the browser to follow the link
return false;
});
It works ok the first time I click on a record, but if I click cancel and try to edit another record, the dialog box does appear (with the correct record details) however, no scripts within the dialog box work - eg: there's a jqueryUI datepicker input and some validation.
There are no javascript errors and, from my limited understanding of FireBug, I can't spot anything going wrong so I would appreciate some advice how to proceed, thanks!
EDIT: Argh! Sometimes, it takes something like typing it out here to spot the obvious. I just realised that the DIV created for the dialog box doesn't get destroyed when the box closes. I've added a line to do this and it now works. Thanks for listening. :)
For future reference, I added an ID to the DIV created in 'var dialog' and removed it in the Cancel function:
Cancel: function() {
$( this ).dialog( "close" );
$('#dialogbox').remove();
}
I'd still appreciate if anybody suggests a better way to handle this behaviour.
I fixed it: the DIV created for the dialog box doesn't get destroyed when the box closes.
I added an ID to the DIV created in 'var dialog' and removed the DIV in the Cancel function:
Cancel: function() {
$( this ).dialog( "close" );
$('#dialogbox').remove();
}
You can create the dialog at one time only, not on every load of its content, just set the autoOpen to false.
<div id="dialog">
<div id="content" style="display:hidden" title="Record details:"></div>
</div>
$('#dialog').dialog({
height: 440,
width: 550,
autoOpen: false,
modal: true,
buttons: {
"Update this record": function() {
$('#editform').submit();
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
$("#datatbl tr").bind('click', function() {
var url = 'item_edit.asp?id='+$(this).attr("data-myid");
// load remote content
$('#content').load(url);
$('#dialog').dialog('open');
return false;
}};
I have a JQuery UI accordion that contains different parts of the user workflow. I would like to disable accordion "tabs" that the user hasn't reached yet. (So if the user hasn't signed in yet, he can't yet publish content, etc.) Then, as the user completes the necessary steps, more tabs will become enabled.
Is there a way to do this? This doesn't work, even as a way to prevent any tabs from changing:
$("#accordion").accordion({
changestart: function(event, ui) {
return false;
}
});
You should add/remove the class "ui-state-disabled" to each header element (i.e. "<h3>") you want to disable/enable. Then use:
$( "#accordion" ).on( "accordionbeforeactivate", function (){
return ! arguments[1].newHeader.hasClass( "ui-state-disabled" );
})
To add/remove a class dyanamically, use:
$( "selector" ).addClass( "ui-state-disabled" );
$( "selector" ).removeClass( "ui-state-disabled" );
You can add a meaningul "id" attribute to each header element to simplify the "selector" part. For example, "step-1", "step-2", "step-n" for each step the user should traverse along the workflow.
You can try the following if you are positive about the position the tab to be disable has:
// Disable the first tab
$( "#accordion > h3:first-child" ).addClass( "ui-state-disabled" );
// Make sure the fourth tab is enabled
$( $( "#accordion > h3" )[3] ).removeClass( "ui-state-disabled" );
Also note that using "ui-state-disabled" is actually meaningful because it will render the header grayed (or whatever your theme makes disabled things look like).
Another note, if the tab you are dynamically disabling is currently active, it won't do anything special (i.e. it won't collapse or activate another tab). You can add extra logic to activate a default tab or do anything else.
This seems like it should be easier. But here's a solution:
The first thing we need to keep track of is which panels can be legally opened:
// Keep an array of the indexes that the user can open.
// [0,1] would allow ONLY the first and second panels
// to be opened
var available_indexes = [0,1];
Then, when you call your accordion, do it like this
$('#accordion').accordion({
header: 'h3',
change: function(event, ui) {
var newIndex = $(ui.newHeader).index('h3');
if (jQuery.inArray(newIndex, available_indexes) == -1) {
var oldIndex = $(ui.oldHeader).index('h3');
$(this).accordion( "activate" , oldIndex );
alert('That panel is not yet available');
}
}
});
So then, if you want to allow the user to access the third panel, you would do:
available_indexes.push(2);
$("#service_options_available h3").click(
function(e) {
if($(this).hasClass("empty")) {
e.stopImmediatePropagation();
return false;
}
}
);
$("#service_options_available").accordion({
autoHeight: false,
collapsible: true,
active: false,
header: 'h3',
changestart: function(event, ui) {
if($(ui.newHeader).attr("id") != null) {
alert($(ui.newHeader).attr("id"));
}
}
});
This has worked for me:
$("#accordionTabToDisable").click(function(){
$("#acordion" ).accordion( "option", "active",0); //maybe this line could be optional
return false;
});
The tab can be easily disable as below:
<p:tab title="First Tab Title" **disabled=”true”**>
To enable it you can use javascript to enable it again.
Diego Augusto Molina nailed it. ui-state-disabled class is the way to go: http://api.jqueryui.com/theming/css-framework/
Consider this piece of code that allows user go back, but not go to next accordion tab. We do it only programmatically, after proper validation:
function disableAccordionNextTabs () {
var $accordion = $(".accordion");
var active = $accordion.accordion('option', 'active');
var $headers = $accordion.find($accordion.accordion('option', 'header'));
$headers.addClass('ui-state-disabled');
for (var i = active; i >= 0; i--) {
$headers.eq(i).removeClass('ui-state-disabled');
}
}
None of the workarounds really worked for me. Would've been alot nicer if it was supported out of the box ofcourse, but here's the workaround i used. I bound the event to a custom event and added my own click event which can do whatever logic and trigger the customClick event if the navigation is allowed.
JS:
$('#accordion').accordion({
event: 'customClick'
});
$('#accordion > .ui-accordion-header').click(function() {
if(confirm ("Is this allowed?")){
$(this).trigger('customClick');
}
});
Or check out the working jsfiddle here: http://jsfiddle.net/hWTcw/
A pretty easy solution is grabbing the header (<h3>) by content:
$("h3:contains('panel name')").toggleClass('ui-state-disabled');
That way you can enable/disable with the same code or hide the panel all together with:
$("h3:contains('panel name')").toggle();