Hello everyone,

I'm currently developing a webpage that when user input the data needed in Advance Filtering and click on the button'Search Result',the table will show the data needed,but the problem is i get the error of Uncaught TypeError: Cannot read property 'fnDraw' of undefined when the user choose the input.

Can any kinds buddy help to assist me in my problem?

Thank you.

$(function(){
    var oTable,
            sumTable,
            tableWidth = $(".hunter-table").width();

    // Summary Table from summary page
     $(".SummaryTable").length > 0 && $(".SummaryTable").each(function() {

        if (!$(this).hasClass("dataTable-custom")) {
            var e = {
                sPaginationType : "full_numbers",

{if $pageType == "summary"}

<!-- advanced filter --> <section id="msp_filter"> <!-- button --> <div> <a id='msp_open_btn' class='btn btn-red is-open'>Advance Filtering <i class='icon-chevron-down'></i></a> </div> <!-- filter detail --> <div id='msp_filter_content'> <div class='msp_filter_box'> <table class="msp_filter_table"> <thead> <tr> <th></th> </th></th> </tr> </thead> <tbody> <tr> <td colspan='2'> <h5 class='filter_title'>Date & Time</h5> </td> </tr> <tr> <td>Month</td> <td> <select id="f_month" class='custom_select'> <option value=''>All</option>
                {$moption}
              </select> <select id="f_month_2" class='custom_select'> <option value=''>No Filter</option>
                {$moption}
              </select> </td> </tr> <tr> <td> >= Date</td> <td> <input id='f_date' type='date' value='' class='custom_datepick'> </td> </tr> <tr> <td colspan='2'> <h5 class='filter_title'>Product Status</h5> </td> </tr> <tr> <td>Category</td> <td> <select id="f_product" class='custom_select'> <!--<option value='no'>All</option>--> <option value='I'>PVC</option> <option value='F'>FABRIC</option> </select> </td> </tr> <tr> <td>Completion</td> <td> <select id="f_comp" class='custom_select'> <option value='no'>All</option> <option value='1'>Completed</option> <option value='0'>Not Completed</option> </select> </td> </tr> </tbody> </table> </div> <div class='msp_filter_box'> <h5 class='filter_title'>Custom Search</h5> <div class='m-20'> <input id='f_text_search' type='text' class='custom_text' placeholder='eg. Jobsheet, Articleno'> <i class='icon-search'></i> </div> <a class='btn btn-green mt-10' id="f_form_search">Search Result</a> <a class='btn btn-blue mt-10' id="f_table_refresh">Refresh Table</a> <a class='btn btn-red mt-10' id="f_form_reset">Reset Filter</a> </div> </div><!-- filter detail --> </section><!-- advanced filter -->
{/if }

<!--Big Wrapper--> <div class="hunter-body"> <!-- Table Insult --> <div class="hunter-table"> <!--Title--> <div class="hunter-table-title"></div><!--End Title--> <!-- dummy slider --> <div class="hentai-main"> <div class="hentai-scroll"> <div class="dummy-scroll"> </div> </div> </div><!-- dummy slider --> <!-- A lot of Table --> <div class="hunter-main-table"> <!-- slideshow idea container --> <div class="wip-container"> <div class="wip-slider"> <!--get schedule latest date, prepare for datatable filter--> <input type="hidden" id="wipDate" value="{$pageDate}"/> <input type="hidden" id="todayDate" value="{$todaydate}"/> <table class="SummaryTable table table-nomargin dataTable-display table-borderd usertable"> <thead> <tr>
                                {if $pageType == "summary"}
                                <th style="text-align: center; width : 1px !important;">No</th> <th style="text-align: center;width:80px !important;">Customer</th> <th style="text-align: center;width:60px !important; ">Jobsheet No.</th> <th style="text-align: center;width:200px; !important">Product Description</th> <th style="text-align: center;width:60px; !important">Article No / Old Article</th> <th style="text-align: center;width:20px !important;">Size / Color</th> <th style="text-align: center;width:10px !important;">Order Quantity</th> <th style="text-align: center;width:20px !important;">Ship Date</th> <th style="text-align: center;width:20px !important;">Material Status</th> <th style="text-align: center;width:20px !important;">Cutting Status</th> <th style="text-align: center;width:20px !important;">PVC Printing Status</th> <!--<th class="plf-none" style="text-align: center;width:40px !important;">Fab Printing Status</th>--> <th style="text-align: center;width:20px !important;">Fab Printing Status</th> <th style="text-align: center;width:20px !important;">PVC Printing QC Status</th> <th style="text-align: center;width:20px !important;">Sealing Status</th> <th style="text-align: center;width:20px !important;">Air Test Status</th> <th style="text-align: center;width:20px !important;">Sewing Status</th> <th style="text-align: center;width:20px !important;">Final Inspection</th> <th style="text-align: center;width:20px !important;">Packing Status</th> <th style="text-align: center;width:20px !important;">Warehouse</th>

              sDom : '<"voon"fl>rt<"joon"ip>',
                oLanguage : {
                    sSearch     : "<span class='vccc'>Date Filter :</span><select id='wipFilter'></select><span>Quick Search :</span> ",
                    sInfo       : "Showing <span>_START_</span> to <span>_END_</span> of <span>_TOTAL_</span> entries",
                    sLengthMenu : "_MENU_ <span>entries per page</span>"
                },
          fnServerParams : function(data) {
            data.push(
              { name : 'month'  , value : $f_month.val()    },
              { name : 'month2' , value : $f_month_2.val()  },          
              { name : 'date'   , value : $f_date.val() || 'no' },
              { name : 'product', value : $f_product.val()  },
              { name : 'comp'   , value : $f_comp.val()     },
              { name : 'search' , value : $f_t_search.val() || 'no' }
            );
          },
          fnDrawCallback : function() {

          }
            };

            // cache in window object
            oTable = $(this).dataTable( { bRetrieve : true } );

            if ($(this).hasClass("dataTable-display")) {
                e.iDisplayLength = 10;
                e.bDeferRender = !0;
            }

            ggTable = $(this).dataTable(e);

            $(".dataTables_filter input").attr("placeholder", "Search here...");
            $(".dataTables_length select").wrap("<div class='input-mini'></div>").chosen({
                disable_search_threshold : 9999999
            });
        }
    }); // end summary table

    // caching DOM and bind event
    $(".hunter-table").each(function(){
        var $this        = $(this),
                $container   = $this.find("div.wip-container"),
                $dummyMain   = $this.find("div.hentai-main"),
                $dummyScroll = $dummyMain.find("div.hentai-scroll"),
                $dummy       = $dummyScroll.find("div.dummy-scroll"),
                $voon        = $container.find("div.wip-slider").find("div.voon"),
                $wipFilter   = $voon.find("select#wipFilter"),
                $joon        = $container.find("div.wip-slider div.joon"),
                $table       = $container.find("div.wip-slider table"),
                $span        = $table.find("span.tabletitle"),
                $datestr     = $container.find("input#wipDate"),
                $dateoption  = $datestr.val(),
                $todaydate   = $container.find("input#todayDate"),
                poch         = $todaydate.val();

        // asyn scroll bar with the original one
        $dummyScroll.css("width",tableWidth + "px");
        $dummy.css("width",( $table.width() + 10) +"px");

        // scroll event
        $container.on("scroll",function(){
            var pixel = $(this).scrollLeft();
            $voon.css("margin-left", pixel + "px");
            $joon.css("margin-left", pixel + "px");
            // update dummy scroll bar
            $dummyScroll.scrollLeft(pixel);
        });

        // when scrolling dummy, update the original one
        $dummyScroll.on("scroll",function(){
            var pixel = $(this).scrollLeft();
            $container.scrollLeft(pixel);
        });

        // when window Resize, update the dummy scroll width
        $(window).resize(function(){
            var width = $(".hunter-table").width();
            $dummyScroll.css("width",width + "px");
        });

        $(window).on("scroll",function(){
            var container = $container.offset().top;
            if($(this).scrollTop() > container ) {
                $dummyMain.addClass("revFixed");
            } else {
                $dummyMain.removeClass("revFixed");
            }
        });

        // filter by date
        $wipFilter.append($dateoption)
                  .change(function(){
                                var val = $(this).val();
                                if(val === 'all') {
                                    ggTable.fnFilter("",7);
                                } else {
                                    ggTable.fnFilter(val,7);
                                }
                            });
        // auto filter after page landing
    // this statement must go before the previous one
        $wipFilter.children("option[value^='" + poch +"']").prop("selected","selected").change();
    }); // end cache dom
});

// redraw otable 
  function ofs() {

     window.oTable.fnDraw();

  }

I have try to add

var dTable = group_table.find('div.dataTables_scrollBody table').dataTable({'bRetrieve': true});
dTable.fnDraw();

to function ofs() but nothing seem to work.

Please help me as I'm really lost now...

Dani AI

Generated

Short answer: the error means the DataTable reference you call fnDraw on is undefined. As hinted, this is almost always a scoping/instance problem rather than a DataTables bug.

Why it happens

  • ofs() is calling a variable on window (or a different scope) that was never set to the actual DataTable instance at runtime. If the table is created inside the ready callback (or inside a loop) with a local var, window.oTable will be undefined when ofs() runs. Mixed use of the legacy API (.dataTable() / fnDraw) and the 1.10+ API (.DataTable() / draw) can make this harder to debug.

Practical fixes

  • Make the instance reachable where you call redraw:
    • Move ofs() inside the same scope that declares the table, or
    • Explicitly attach the instance to a known place (but avoid implicit globals): window.myTable = $(selector).dataTable(...); (or better window.myTable = $(selector).DataTable(...);)
  • Prefer the 1.10+ API and a selector-based redraw so you do not rely on a single global variable.

Safe redraw helper (works with old and new APIs)

function safeRedraw(selector) {
  var $t = $(selector);
  if (!$t.length) return;
  if ($.fn.dataTable && $.fn.dataTable.isDataTable(selector)) {
    var api = $t.DataTable();
    if (api && typeof api.draw === 'function') api.draw(false);
    return;
  }
  var legacy = $t.dataTable && $t.dataTable();
  if (legacy && typeof legacy.fnDraw === 'function') legacy.fnDraw(false);
}

Troubleshooting checklist

  • In the console, log the instance you plan to redraw: console.log(window.oTable, $('.SummaryTable').DataTable && $('.SummaryTable').DataTable());
  • Check for multiple table initializations or wrong selector scope.
  • Replace implicit globals with var/let/const or pass the instance to the function that needs it.

Applying the safe helper or making ofs() use the same local instance will eliminate the uncaught fnDraw error.

Hi,
Have you examine this part?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.