4

I am using the [datatables.net][1] jQuery plugin with an <apex:datatable /> and I want to submit all records checked from the dataTable meaning i'm using

<apex:stylesheet value="{!$Resource.lib}/css/jquery.dataTables.css"> 
<apex:includeScript value="{!$Resource.lib}/js/jquery.dataTables.min.js"/> 

Here is the Code to initialize dataTable Jquery:

 jQuery(document).ready(function(){
    $('table[id$="itemsList"]').dataTable();

    // Check / uncheck all available rows at once.
        jQuery('#selectAll').click( function(){             
            if(jQuery(this).is(':checked')){
                jQuery('.chkProd').attr('checked', true);               
            }else{
                jQuery('.chkProd').attr('checked', false);
            }
           });
 });

in my VisualForce Page. And i have the follow environment, which has "10","50","100" options records to display:

<apex:dataTable value="{!listaInnerProduct}" var="item" id="itemsList" rowClasses="odd,even" rendered="{!IF(tempListaInnerProd.size == 0,true,false)}">
           <apex:column >  
             <apex:facet name="header">
                <input type="checkbox" id="selectAll" value="" title="Selecccionar todos los registros." />
             </apex:facet>   
             <apex:inputCheckbox styleClass="chkProd" value="{!item.isSelected}" />  
           </apex:column>              
           <apex:column >  
             <apex:facet name="header">Cantidad</apex:facet> 
             <apex:inputText value="{!item.cantidad}" style="width:30px;" onkeypress="return isNumberKey(event)"></apex:inputText>
           </apex:column>         
</apex:dataTable>

Controller Code:

public with sharing class AgregarProductosController {

 public List<InnerProduct> listaInnerProduct {get;set;}

 public AgregarProductosController(ApexPages.standardController stdCon){
  this.listaInnerProduct = obtenerProductosInternos();
 }

public List<InnerProduct> obtenerProductosInternos(){
 List<InnerProduct> listaInnerProduct = new List<InnerProduct>();
 InnerProduct inProd;
 for(Product2 prod : [Select Id,Name From Product2]){

  //code to create new Wrapp object for each product2

 }
}

public class InnerProduct{
    public Id productId {get;set;}
    public String name {get;set;}
    public Boolean isSelected {get;set;}
}

I have the following problem:

-If i do check on some Rows and then go to Next Page button, and then Click on my commandButton.. the previous values are not sending to the server. Only the current page.

My question is: How could i send an array of ObjectHTMLRowElement (which ones i got it from the dataTable()) from the visualforce page to the controller and parse it to sObject?

  • Can you show the code which you're using to perform the submit as well as the controller which receives the data? There is no javascript array being used in your example code. – Mark Pond Dec 6 '13 at 16:12
  • Added, i meant with js array[] to a reference for all records. The problem is when i SELECT doing click on checkbox in the current dataTable page and use the 'Pagination' the records are saved but when are submitted only submit the record on the currentPage. – mauriD Dec 6 '13 at 16:21
  • I think you need to show more code, where is "next page" functionality? – Sergej Utko Dec 6 '13 at 16:25
  • Jquery DataTable library provides "next Page" functionality, that actually works fine. The problem is when submit the records. Only submit the checked records in the current Page – mauriD Dec 6 '13 at 16:30
  • can you show the script which you're using to initialize the datatables.net plugin within the page? – Mark Pond Dec 6 '13 at 17:31
1

I suggest you get in touch with Allan, at data tables.net/support : he is extremely reactive and efficient, you will get the answer you your questions, he has solved many for me already.

| improve this answer | |
  • Thanks, it was very helpful that contact! Allan provides me some ways to resolve it. – mauriD Dec 10 '13 at 3:18
  • 1
    @mauriD how did you resolve the issue? I have the exact same scenario – jonathanwiesel Sep 10 '14 at 16:16
  • 2
    @jonathanwiesel i used this solution: I include this js class to the page <apex:includeScript value="{!$Resource.lib}/js/fnLengthChange.js"/>source js . The when you press Save button you have to call a js function like addAll() in onClick(); then inside it you have to call fnLengthChange function from the table: var table = $('table[id$="tblProd"]').dataTable(); table.fnLengthChange(5000); So this will expand the table before send the info to server and will take all the checked items. – mauriD Sep 10 '14 at 22:35
  • @mauriD I tried your solution but it doesn't seem to work for me when applying search filters, like selecting some rows, then filtering by search to show only 1 of the selected, then clicking submit, only the selected visible one gets submitted. Didn't try paginating though, don't have much data to test with. – jonathanwiesel Sep 11 '14 at 14:06
  • Jona provide your code please; Are you using inner class item to have the selected items? you added in onclick submit function the fnLengthChange method? Every time you submit you have to call this function with the total of your items. I mean if the controller handle 1400 items try to set fnchangeLength(1400) on the javascript function which is called from your submit button. It must to work. Let me see – mauriD Sep 11 '14 at 14:15
0

@mauforcedev What was the resolution to your datatables issue? I am in a similar predicament.

Thanks!

| improve this answer | |
  • The resolution was include fnLengthChange functionality and call the function to set the items to proccess in the onclick save button. So by this way you can process all checked items between all pages that you were navigated. – mauriD Sep 10 '14 at 22:39
0

This was answered by mauriD in the comments above, but I will try to summarize it with a real example, so others will get a clear view of the solution. I provide the most essential code here without formatting, css styles etc.

VISUAL FORCE PAGE

External scripts on the page:

<apex:page controller="CustomController" showHeader="false" sidebar="false" standardStylesheets="false" docType="html-5.0">
<!-- jQuery -->
<apex:includescript value="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" />
<!-- jQuery Data Table-->
<apex:includescript value="//cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js" />
<apex:stylesheet value="//cdn.datatables.net/1.10.4/css/jquery.dataTables.min.css" /> 

Datatable initialization:

<apex:outputPanel id="contactTable">
    <!-- jQuery Data Table Start -->
    <script>
        $ = jQuery.noConflict();
        /* Initialise the table with the required column ordering data types */
        $(document).ready(function() {
            var mainTable = $('[id$="mainTable"]').dataTable(
                {
                    "order": [[ 1, "asc" ]],
                    "paging": true,
                    "pagingType": "full_numbers",
                    "pageLength":  10,
                    "stateSave": false,
                    "columnDefs": [ 
                        {"targets": 0, "orderable": false} 
                    ]
                }
            );
        } );
    </script>

    <table id="mainTable">
        <thead>
            <tr>
                <th><apex:inputCheckbox value="false" id="contactsMain" /></th>
                <th>NAME</th>
            </tr>
        </thead>

        <tbody>
            <apex:repeat value="{!leads}" var="lead" >
                <tr>
                    <td><apex:inputCheckbox value="{!lead.Can_Be_Contacted__c}"/></td>
                    <td><apex:outputText value="{!lead.name}"/></td>
                </tr>
            </apex:repeat>
        </tbody>
    </table>
    <!-- jQuery Data Table End -->
</apex:outputPanel>

<apex:pageMessages id="messagesSection"/>

Submit to the controller:

When a user clicks the "Continue" button, a js function will be invoked that do two important things: (1) displays all table rows on one page and (2) invokes an action function that makes an AJAX request to the controller passing all parameters. Notice that upon completion of AJAX call the following elements will be rerendered: contactTable and messagesSection. That makes sure that the page will display correct data (updated by the controller) and DataTable will be reinitialized again so the pagination will be restored.

<script>
    function prepareTable()
    {
        try
        {
            var contactTable = $('[id$="contacttable"]').DataTable();
            // redraw the table to show all rows on one page
            contactTable.page.len( -1 ).draw();
            // call actionFunction
            handleSubmit();
            return true;
        }
        catch (err)
        {
            console.log(err.message);
            return false;    
        }
    }
</script>
<button type="button" onclick="prepareTable()">Continue</button>
<apex:actionFunction name="handleSubmit" action="{!handleSubmit}" reRender="contactTable, messagesSection"/>

</apex:page>

CONTROLLER

public with sharing class CustomController
{
    public List<Lead> leads { get; set; }

    public CustomController()
    {
        this.leads = [SELECT Id, Name, Can_Be_Contacted__c FROM Lead];
    }

    public PageReference handleSubmit
    {
        update leads;
        return null;
    }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.