i have made this example work on my page http://datatables.net/examples/server_side/server_side.html, (using php5, jquery+ui and dataTables.net)
i would like to be able to add a Modify and Delete link on each row, how can i do that without sending two extra columns with the links from the server?
also how can i substitute the ids the rows have in the database and that are sent by the server with nice number starting from 1 till iTotalDisplayRecords...
thank you
found how
var controller_name = '<?php echo Zend_Controller_Front::getInstance()->getRequest()->getControllerName();?>';
"fnDrawCallback": function ( oSettings ) {
/* Need to redo the counters if filtered or sorted */
for ( var i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
{
var link = $(' Modifica Cancella');
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).html( i+1 );
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).append(link);
}
},
Related
I am using jquery plugin DataTables for building nice table
var table = $('#example').DataTable({
"data": source
});
I would like that make an each for all rows in table
Unfortunately this way may be out of date and does't work with new version (it launchs an error)
$(table.fnGetNodes()).each(function () {
});
And this way only works only for visibles rows (10 first rows because other rows are paginated)
table.each( function ( value, index ) {
console.log( 'Data in index: '+index+' is: '+value );
} );
Do you known how to loop to all rows please?
I finally found:
var data = table.rows().data();
data.each(function (value, index) {
console.log(`For index ${index}, data value is ${value}`);
});
Datatables have an iterator for each row rows().every() with this referring to the context of the current row being iterated.
tableName.rows().every(function(){
console.log(this.data());
});
If you are using the legacy DataTables then you can get all the rows even the paginated ones, as shown below...
table.fnGetNodes(); // table is the datatables object.
So we can loop through the rows by using .each() method provided by jQuery.
jQuery(table.fnGetNodes()).each(function () {
// You can use `jQuery(this).` to access each row, and process it further.
});
for example, this data has three fields UserID, UserName and isActive and we want to show only active users
The following code will return all the rows.
var data = $('#myDataTable').DataTable().rows().data();
We will print only active users
data.each(function (value, index) {
if (value.isActive)
{
console.log(value.UserID);
console.log(value.UserName);
}
});
Im trying to update the mini-cart (cart_fragments) after/on an ajax event. It works like this.
HTML Trigger:
<a id="woomps-button-\'.$nr.\'" class="woomps-button" '.$ajax_url.' data-button-nr="'.$nr.'">
jQuery request:
jQuery( document ).on('click', '.woomps-button', function() {
var nr= jQuery(this).data('button-nr');
jQuery.ajax({
url : subpost.ajax_url,
type : 'post',
data : {
action : 'woomps_update_nr',
security : subpost.security,
nr: nr
},
success : function( response ) {
window.alert(nr);
//MAYBE_code to refresh_fragments here
}
});
return false;
});
PHP responder:
function woomps_update_choosen_person () {
$p = $_POST['nr'];
if ($p == 1) {$x= "This must show in cart";}
WC()->session->set( 'woomps_limit_by_persons' , $x );
//MAYBE code to refresh_fragments here
}
And in the mini-cart.php template i have a calculation based on this field.
$items_left_start = WC()->session->get( 'woomps_limit_by_persons' )?: 3 ;
//Do something something here
So this works, except I need to refresh the cart like when an item is added to cart. My assumption is that is should be an ajax request from jQuery that i can put in the success block?
The class i (think) I want to fire is this WC_AJAX::get_refreshed_fragments(); But this is fired from an an add_action, so i tried this add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( 'WC_AJAX', 'get_refreshed_fragments' ) );. But it did not work either.
I also try to create an jQuery ajax call like it does in the add_to_cart button, but it neither worked.
//MAYBE_code to refresh_fragments here
var data = {};
jQuery.post(
wc_get_refreshed_fragments_params.wc_ajax_url.toString().
replace( '%%endpoint%%', 'get_refreshed_fragments' ), data,
function( response ){
})
}
I do not completely understand how this works, if anyone have some pointers or a snippet i would so much appriciate it. Been struggeling with this for some time now.
After much struggeling this topic on stack helped create the correct code to update mini cart fragments. It was both PHP and jQuery neeeded.
So basically you can call the WC_AJAX::get_refreshed_fragments() at the end of your PHP coode responder; if it comes from an AJAX call. It will not return to your PHP responder code so put it at the end. The PHP respons will end/sent back to jQuery inside the WC_AJAX::get_refreshed_fragments(); so you also need to create some jQuery that responds to this. This i got from the topic:
var fragments = response.fragments;
if ( fragments ) {
jQuery.each(fragments, function(key, value) {
jQuery(key).replaceWith(value);
});
}
(simplified) Scenario: a remote MySql DB and an HTML page with 2 buttons: SHOW and SELECT. The SHOW loads a single record and displays the fields in a form.
Everything is ok on this side.
The SELECT was made with a new approach for me:
I pass a parameter to a PHP function to query the DB and create an html file with the resuls.
This file is a series of <UL><LI><a id="1"...data..</LI></UL> to be inserted within a DIV.
One of the <LI> contains a link that, when clicked, calls the SHOW function. The record identification is made by mean of the ID associated to the anchor.
This procedure works fine; I get the new HTML segment (that I can check on the remote web server).
It is inserted (???) inside my DIV and the content is correctly displayed on screen, but... it does not exist.
Clicking on the links does not activate the SHOW procedure (actually, an Alert with the calling ID is never shown).
Looking to the html page source from Mozilla it still shows the previous content, without the new added (or replaced) code.
This is the reason for this post's title: I see something that really is not there.
Possibly, I should have AJAX to 'refresh' its visibility of the DOM, but and do not understand how.
This is the piece of JQuery script that I use to get the new content:
$("#select").click(function() {
$.ajax({
url: "new_record_list.php",
cache: false,
success:
function(recNumber)
{
$("#selected").val(recNumber); //ok
$("#recordList").load("list.txt"); //'list.txt is created by new_record_list.php
alert($("#recordList").html()); //this is OK
}
});
});
Everything is ok, but where is the meat?
Most likely the listener you created did not attach to the new dom nodes.
You can fix this by attaching a listener to a parent element that exists at page creation or even the document like so:
$(document).on('click', '.show', function() {
//click event
});
Replace ".show" with the jquery selector for the links
Since I'm unable to comment on your new post due to rep:
Remove the click event handler inside the loadRecord function.
The click event was already bound at the top of your script. What happens is that you click, activate the load record function which binds a new click handler, triggering the action on all the clicks following it.
The load record should look like this instead:
function loadRecord(){
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
};
Also, you should replace
$(document).on('click', '.compLink', function() {
loadRecord();
});
with
$(document).on('click', '.compLink', loadRecord);
And loadRecord will be passed the mouse event as an argument. $(this) will also refer to the link you clicked inside the loadrecord function.
Otherwise you need to pass the element clicked into that function.
One issue I can see straight away is the AJAX call, it should be along the lines of:
$( "#select" ).on( "click", function ()
{
$.ajax( {
url: "new_record_list.php?record=MY_RECORD_VALUE",
type: "GET",
success: function ( response )
{
$( "#selected" ).val( response );
$( "#recordList" ).html( function ()
{
$.ajax( {
url: "list.txt",
typ: "GET",
success: function ( response2 )
{
$( "#recordList" ).html( response2 );
}
} );
} );
alert( $( "#recordList" ).val() );
},
beforeSend: function()
{
$( "#recordlist" ).html( "Loading..." );
$( "#selected" ).val( "Loading..." );
}
} );
} );
This will give a better result from the $.ajax call that you have made.
The .load() method can be quite unreliable at times, hence why it is (IMO) better to make an ajax within an ajax, because that's what your doing with less control effectively.
Where you have done the function(recNumber) is kinda wrong I'm afraid, whats brought back from the AJAX call is the response, everything that would be shown should you be using it as an actual page, e.g. if you had:
<table>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
</table>
<input id="id_valued" value="2" />
Then this whole thing would be returned, not just the id_valued input field.
I followed the hints from Erin plus some other suggestion found on this forum and now the program ALMOST works.
Actually it does, but when a new set of records is loaded, to update the display (that is to call the loadRecord function) it is necessary to click twice on a link, the very first time only. All next clicks reacts immediately.
I try to post the entire script, for you experts to see what I hardly did:
<script type="text/javascript">
$(document).ready(function()
{
$(document).foundation();
var $scrollbar = $("#scrollbar1"); //other stuff
$scrollbar.tinyscrollbar();
//Erin suggestion + my understanding
$(document).on('click', '.compLink', function() {
loadRecord();
});
/* =========== ADD Rows ============================== */
/* action called by hitting the "selectRow" button.
/* query the DB and get a list of rows (5 fields each)
/* that are then inserted into the '#recordList' DIV.
/* Each rows has format:
/* <UL><LI><A id="xxx" class="compLink" ...>item xxx</A></LI><LI>....</LI></UL>
*/
$("#selectRow").on( "click",function()
{
$.ajax(
{
url: "new_record_list.php",
type: "GET",
success: function(recNumber) //if ok, we get the number of records
{
$("#selectedRecords").val(recNumber); //show how many records we got
$("#recordList").load("newRecords.txt"); //loads the remote text file into the DIV
}
});
});
/* ====================================================== */
/* =========== LOAD Record ============================== */
/* loads and displays an entire record from DB,
/* based on the ID of clicked link with class="compLink"
/* in '#recordList' DIV.
/* Example: <a id="1" class="compLink" ...>
*/
function loadRecord(){
$(".compLink").click(function(event)
{
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
});
};
/* ====================================================== */
return false;
});
</script>
I hope this is clear enough. Thanks
i am trying to add / remove rows dynamically in / from a table using JQuery and the DataTables plugin, at a specific index.
$('#jt').dataTable();
The rows i try to add is some additional info, which i get by clicking on a row (ajax). Each row has a unique id that i pass as an argument.
$('#jt').on('click','.togetinfo',function() {....
$.get(functions, { id: id }).done(function(data) {
....
For each result i add the content to a var and add it after the row i want.
$.each(jsonresult, function(i,item){
subentries = subentries + ....... /* the info */
});
$('#jt > tbody > tr').eq(id).after(subentries);
This works perfectly on the first page, but on the second page of the entries (paging) it does not insert the new data.
The fnAddData() of the "DataTables" API inserts the data on the end of the entire table.
Does anyone has an idea of how to make it work on all the pages?
The false was found in the indexes of each row after the first page.
Each index (on click) must be recalculated.
var rowIndex = oTable.fnGetPosition( $(this).closest('tr')[0] );
rowIndex = rowIndex - oSettings._iDisplayStart;
Here's the scenario: I'm building a Wordpress plugin to manage some survey research that I'm involved in. The project admin is able to upload a csv file from the WP admin interface. On the client side, when the file is uploaded it goes through each line of the file, extracts the necessary info about the users and then makes an AJAX call to add the participant to the project. I decided to parse the csv file on the client side and submit the ajax requests one by one so that I could update a progress bar as each returns. The javascript looks like this:
$( '#csv_upload_button' ).click( function() {
// declare the necessary variables
var f = $( '#csv_file_input' )[0].files[0],
fr = new FileReader,
rows, headers, dialog, count, remaining;
// when the file loads
fr.onload = function() {
// get the rows, the count, number remaining to process, and headers
rows = fr.result.split( "\n" );
remaining = count = rows.length - 1; // -1 to account for header row
headers = $.trim( rows[0] ).split( ',' );
// create the dialog box to show the progress bar
dialog = $( '<div></div>' )
.html(
'<p>Loading...</p>' +
'<p><progress id="csv_upload_progress" max="' + count +
'" min="0" value="0"></p>' )
.dialog( { modal: true; } );
// then for each row in the file
$( rows ).each( function( i, r ) {
// create an object to hold the data
var data = {}, row = $.trim( r ).split( ',' ), j;
if ( i > 0 ) { // data starts on the second row
// map the data into our object
for ( j = 0; j < headers.length; j++ ) {
data[ headers[ j ] ] = row[ j ];
}
// send it to the server
$.post(
ajaxurl,
{
action: 'import_panel_member',
data: data,
postid: $( '#post_ID' ).val()
},
function( result ) {
var prog = $( '#csv_upload_progress' );
prog.attr( 'value', prog.attr( 'value' ) + 1 );
if ( 0 == --remaining ) {
// stuff to do when everything has been loaded
}
}
);
}
});
};
// read the csv file
fr.readAsText( f );
});
The PHP looks something like this:
function import_panel_member() {
header( 'content-type: application/json' );
// get the variables sent from the client
$postid = $_POST[ 'postid' ];
$data = $_POST[ 'data' ];
/*
* ...do other things involving talking to a 3rd party server...
*/
// get the WP meta data variable to be updated
$participants = get_post_meta( $postid, '_project_participants', true );
// modify it
$participants[] = $data;
// update the database
update_post_meta( $postid, '_project_participants', $participants );
// return a message to the client
echo json_encode( (object) array( 'success' => 1, 'message' => 'added' ) );
exit;
}
The problem is that since these requests happen asynchronously, it appears that the _project_participants metadata field is only being updated by the last record to be processed. In other words, only the last person in the list shows up in the list of participants. Here are some things that I've tried:
Change $.post() to $.ajax() and set async: false
This works but it's much slower (due to synchronous calls) and for some reason it prevents my dialog box from showing up until after all the ajax calls have finished.
Upload the entire csv file to the server and deal with it there
Instead of parsing the csv on the client side. This works, too, but I don't think I can get intermediate feedback from the server that I can use to update the progress bar. This request can take quite a while, and I don't want users to "give up" on the request before it's complete. When doing it this way, sometimes the server never responds to the ajax call.
So perhaps I am greedy and just want my cake and to eat it, too. How can I take advantage of the speed of asynchronous requests, which give me the opportunity to give the user feedback with a progress bar, but not screw myself up with concurrency issues on the server?
I figured it out. The answer was a hybrid of the two methods. I can use a series of $.post() calls to do the stuff that works better in async mode, and then upload the whole csv to do the stuff that works better in sync mode. Never would have figured this out without typing out the whole explanation in SO!