locked
jQuery Error - fnOpen is not a function and fnClose is not a function RRS feed

  • Question

  • User1912965948 posted

    Hi,

    I'm getting an error fnOpen is not a function

    var dataTable = $('#myTable').DataTable({
                    "bJQueryUI": "true",
                    "sScrollX": "100%",
                    "sPaginationType": "full_numbers"
                });
                $('#myTable tbody td img').click(function () {
                    debugger;
                    var nTr = this.parentNode.parentNode;
                    if (this.src.match('close')) {
                        this.src = '@Url.Content("~/Content/DataTables/images/details_open.png")';
                        dataTable.fnClose(nTr);
                    } else {
                        this.src = "@Url.Content("~/Content/DataTables/images/details_close.png")";
                        var customerId = $(this).attr("rel");
                        var url = "@Url.Action("Get_DetailsById", "Customer")";
                        $.get(url, { Id: customerId }, function (details) {
                            dataTable.fnOpen(nTr, details, 'Details');
                        });
                    }
                });

    Thanks in advance.

    Regards

    Friday, January 8, 2021 12:32 PM

All replies

  • User-1330468790 posted

    Hi fungus.00,

     

    The reason is just what the error tells: the function fnOpen is not existing.

    You could refer to https://legacy.datatables.net/ref and seach fnOpen function. You will see that it is available for DataTables v1.9 and earlier for only. 

    If you print the 'datatable' object in your codes, you could also find that it does not contain a function named 'fnOpen()'.

     

    Regarding your codes, you might want to implement a row-detail functionality.

    The legacy reference is here: https://legacy.datatables.net/examples/api/row_details.html

    However, if you are using the newest version, you should be looking at this documentation: 

    https://datatables.net/examples/server_side/row_details.html

     

    If you insist on using the legacy codes, you might also need to change the version of jQuery which should be earlier than 1.9 (excluded).

     

     

    Hope this helps.

    Best regards,

    Sean

    Monday, January 11, 2021 10:34 AM
  • User1912965948 posted

    Thank you very much for your detailed reply.

    Yes, I totally agree with you that there is a difference between DataTable and dataTable.
    You know exactly, this is a master detailed work.
    Let me tell you here that I am not a very good developer and my jQuery and javascript are not so good.
    you can say that I'm a new bee.
    I am using the DataTable because it has a table.reload() function and dataTable doesn't have it.

    In this case we fill the Master Table through ajax call and I also want to fill child row through ajax call you can see in the main post sending ajax call on click to fill child rows.

    I found a post. https://stackoverflow.com/questions/43962060/building-master-details-grids-using-jquery-datatable

    <script type="text/javascript">
    	
    	var dataTable;
    	
    	/* Formatting function for row details - modify as you need */
            function format (d) {
                // `d` is the original data object for the row
                return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
                    '<tr>'+
                        '<td>Office Type:</td>'+
                        '<td>'+ d.officeType +'</td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td>Web Url:</td>'+
                        '<td>'+ d.cityName +'</td>'+
                    '</tr>'+
                '</table>';
            }
    		
    		var customerId = 1; // need dynamic id here 
            function LoadAjaxInfo(data, callback) {
                debugger;
                $.ajax({
                    url: '@Url.Action("Get_CustomerDetails", "Customer")',
                    type: 'GET',
                    data: {Id: customerId},
                    success: function (response) {
                        callback(format(response));
                    },
                    error: function (err) {
                        alert('Error');
                    }
                    
                });
            }
    		
    		jQuery(document).ready(function(){
    			dataTable = jQuery('#masterTable').DataTable({
                    'ajax': {
                        url: '@Url.Action("CustomerMasterList", "Customer")',
                        type: 'GET',
                        dataType: 'JSON'
                    },
                    pageLength: 25,
                    sPaginationType: 'full_numbers',
                    columns: [
                        {
                            visible: true,
                            searchable: false,
                            orderable: false,
                            className: 'details-control',
                            data: null,
                            defaultContent: ''
    
                        },
                        {
                            orderable: false,
                            data: null,
                            render: function (data, type, full, meta) {
                                return data.customerName;
                            }
                        },
                        {
                            orderable: false,
                            data: null,
                            render: function (data, type, full, meta) {
                                return data.webUrl;
                            }
                        }
                    ]
                });
    			
    			 // Add event listener for opening and closing details
                $('#masterTable tbody').on('click', 'td.details-control', function () {
                    debugger;
                    var tr = $(this).closest('tr');
                    var row = dataTable.row( tr );
     
                    if ( row.child.isShown() ) {
                        // This row is already open - close it
                        row.child.hide();
                        tr.removeClass('shown');
                    }
                    else {
                      LoadAjaxInfo(row.data(), function(formattedContent){
                        // Open this row
                        row.child(formattedContent).show();
                        tr.addClass('shown');
                      });
                    }
                } );
    		});
    </script>

    I'm facing two problems in above code

    1. How to get row Id I mean cutomerId on click event?
    2. In the child row it gives me undefined error after ajax call so how to fix it?

    I'll be very thankful to you if you help me to solve it.

    Regards

    Friday, January 15, 2021 11:03 AM
  • User-1330468790 posted

    Hi fungus.00,

     

    How to get row Id I mean cutomerId on click event?

    As you can see that there is a parameter 'data' in the function 'LoadAjaxInfo()' which can be used to fetch the 'customerId'. The 'data' represents 'row.data()' where 'row' is the current row data object in DataTable.

      

    In the child row it gives me undefined error after ajax call so how to fix it?

    I guess the problem might be located in the server returned value. 

    Could you please show me how you return the value and what kind of format of it?

     

    From my side, I constructed a simplified demo to show how to make the codes working.

    Hope this demo could help you figure it out how to modify your codes.

     

    Index.cshtml

    <h2>Index</h2>
    
    <table id="masterTable">
        <thead>
            <tr>
                <th>customerId</th>
                <th>customerName</th>
                <th>cityName</th>
            </tr>
        </thead>
    </table>
    
    @section scripts{
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <link rel="stylesheet" href="https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css" />
        <script src="https://cdn.datatables.net/1.10.23/js/jquery.dataTables.min.js"></script>
        <script type="text/javascript">
    
    	var dataTable;
    
    	/* Formatting function for row details - modify as you need */
            function format (d) {
                // `d` is the original data object for the row
                return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
                    '<tr>'+
                        '<td>Office Type:</td>'+
                        '<td>'+ d.officeType +'</td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td>Web Url:</td>'+
                        '<td>'+ d.cityName +'</td>'+
                    '</tr>'+
                '</table>';
            }
    
            function LoadAjaxInfo(data, callback) {
                $.ajax({
                    url: '@Url.Action("Get_CustomerDetails", "Customer")',
                    type: 'GET',
                    data: { Id: data.customerId},
                    success: function (response) {
                        callback(format(response));
                    },
                    error: function (err) {
                        alert('Error');
                    }
    
                });
            }
    
    		$(document).ready(function(){
    			dataTable = $('#masterTable').DataTable({
                    'ajax': {
                        url: '@Url.Action("CustomerMasterList", "Customer")',
                        type: 'GET',
                        dataType: 'JSON'
                    },
                    pageLength: 25,
                    sPaginationType: 'full_numbers',
                    columns: [
                        {
                            data:"customerId",
                            visible: true,
                            searchable: false,
                            orderable: false,
                            className: 'details-control',
                            defaultContent: ''
    
                        },
                        {
                            data: "customerName",
                            orderable: false
                        },
                        {
                            data: "cityName",
                            orderable: false
                        }
                    ]
                });
    
    			 // Add event listener for opening and closing details
                $('#masterTable tbody').on('click', 'td.details-control', function () {
                    debugger;
                    var tr = $(this).closest('tr');
                    var row = dataTable.row(tr);
    
                    if ( row.child.isShown() ) {
                        // This row is already open - close it
                        row.child.hide();
                        tr.removeClass('shown');
                    }
                    else {
                      LoadAjaxInfo(row.data(), function(formattedContent){
                        // Open this row
                        row.child(formattedContent).show();
                        tr.addClass('shown');
                      });
                    }
                } );
    		});
        </script>
    
    }

    CustomerController:

    // GET: Customer
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult CustomerMasterList()
            {
                return Json(new { data=Customer.GetCustomers() },JsonRequestBehavior.AllowGet);
            }
    
            public ActionResult Get_CustomerDetails(int Id)
            {
                List<Customer> customers = Customer.GetCustomers();
                Customer customer = customers.AsEnumerable().FirstOrDefault(x => x.customerId == Id);
    
                return Json(customer, JsonRequestBehavior.AllowGet);
            }
    

    Customer.cs (model with simulation of data):

    public class Customer
        {
            public int customerId { get; set; }
            public string customerName { get; set; }
            public string webUrl { get; set; }
            public string officeType { get; set; }
            public string cityName { get; set; }
    
            public static List<Customer> GetCustomers()
            {
                return new List<Customer>
                {
                    new Customer
                    {
                         customerId = 1,
                         customerName = "Name1",
                         officeType = "officeType1",
                         cityName = "city1",
                         webUrl = "URL1"
                    },
                    new Customer
                    {
                         customerId = 2,
                         customerName = "Name2",
                         officeType = "officeType2",
                         cityName = "city2",
                         webUrl = "URL2"
                    },
                    new Customer
                    {
                         customerId = 3,
                         customerName = "Name3",
                         officeType = "officeType3",
                         cityName = "city3",
                         webUrl = "URL3"
                    },
                    new Customer
                    {
                         customerId = 4,
                         customerName = "Name4",
                         officeType = "officeType4",
                         cityName = "city4",
                         webUrl = "URL4"
                    }
                };
            }
        }

    Demo:

     

    Best regards,

    Sean

    Friday, January 22, 2021 9:15 AM