Quantcast
Channel: Recent Discussions — DataTables forums

Follow up to "Datatables defaults on datatable fields in Editor"

$
0
0

As I marked the question as answered, I will follow up here...

Following this up, seems like layout is where I have my issues..
My default settings are

                top: [
                    'buttons',
                    'paging',
                    { search: { placeholder: 'Sökord' } }
                ],
                topStart: null,
                topEnd: null,
                bottomStart: 'info',
                bottomEnd: 'pageLength'

This gets overridden by

                top: hasButtons
                    ? ['search', 'buttons', 'info']
                    : ['search', 'info'],
                bottom: ['paging'],
                bottomStart: null,
                bottomEnd: null,
                topStart: null,
                topEnd: null

It does not seem to be possible to override this in the datatable field type options.
I tried with

                            top: [
                                'buttons'
                            ]

but to no avail.
KR,
Björn H


Pagination start post variable always 0

$
0
0

Hello,

I'm working on a project upgrading our website- jquery/datatables/codeigniter. With the previous versions, I had no problem with this datatable. But now, for some reason the pagination isn't working. The datatable loads successfully the first time, but neither the drop-down to choose the number of results shown, nor the clickable page numbers work. Each time the function getRecordsInfo returns the same thing (results from 0 to 10).

Unfortunately the page is behind a login, but I can provide code as necessary. This is the header HTML, we are using dataTables 2.0.8

<script src="https://dev.vmc.w3.uvm.edu/xana/CI4/js/jquery-3.7.1.min.js" type="text/javascript"></script>
<script src="https://dev.vmc.w3.uvm.edu/xana/CI4/js/jquery-ui-1.13.2.js" type="text/javascript"></script>
<script src="https://dev.vmc.w3.uvm.edu/xana/CI4/js/bootstrap-4.1.3/bootstrap.min.js" type="text/javascript"></script>
<script src="https://dev.vmc.w3.uvm.edu/xana/CI4/js/vendor/mustache/0.5.0-dev/mustache.js" type="text/javascript"></script>
<script type="text/javascript" src="https://dev.vmc.w3.uvm.edu/xana/CI4/js/dataTables-2.0.8/datatables.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://dev.vmc.w3.uvm.edu/xana/CI4/css/bootstrap-4.1.3/bootstrap.min.css"/>
<link href="https://dev.vmc.w3.uvm.edu/xana/CI4/js/jquery-ui-1.11.2.custom/jquery-ui.min.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="https://dev.vmc.w3.uvm.edu/xana/CI4/js/dataTables-2.0.8/datatables.min.css"/>

The javascript initializing the table:

                      datat = $('#data-table').DataTable({
                           "processing": true,
                           "serverSide": true,
                            "ajax": {
                                "url": "<?php echo site_url('manage/versions/getRecordsInfo');?>",
                                "type": "POST",
                                "data": data
                            }, 
                            "drawCallback": function (settings) { 
                                    // Here the response
                                    var response = settings.json;
                                    console.log(response);
                                },                                    
                            "searching": false,
                            "ordering": false,
                            "columns": JSON.parse(result.cols), //result.cols,
                            "stateSave": true,
                            "scrollY": '50vh',
                            "scrollCollapse": true,
                            "scrollX": true
                        });

The beginning of getRecordsInfo looks like this. When I echo 'start' it is always 0, even if I am clicking on the 2nd or 3rd page. Any idea why that would be the case?

            $postData = $this->request->getPost();             
            $draw = (int)$postData['draw'];
            $start = $postData['start'];
            $length = $postData['length'];
            $datasetid = $postData['datasetid'];
            $versionid = $postData['versionid'];
            echo $start 

Link to test case: unavailable
Debugger code (debug.datatables.net): uploaded as debug code ejodaw
Error messages shown: no error messages shown
Description of problem: Pagination not working, start is always 0 (length is always 10 also)

Pagination jump scrolling and accessibility

$
0
0

I’ve been working with DT2 & BS5.3 and have an issue with pagination jump scrolling when used at the bottom of a layout, which I didn’t previously have in older versions. Clicking on new pages used to keep the pagination block at the bottom regardless of the page length, but now longer pages jump up and then scroll down to where it needs to be. So, the end result is the same, apart from some jumping around.

That led me to wonder what the correct method should be for accessibility but I can’t find a consensus. I successfully forced the next page to start to the top which to me makes more sense to me but not sure that is the correct way. I think the focus should be targeted in the top left th but I suppose some checking is then needed to make sure there aren’t any hidden columns. There are so many combinations I can think of so wondered if there are any examples of best practice?

Not seeing the 'childRow.dt' event triggered.

$
0
0

Link to test case: https://live.datatables.net/dehonimi
Description of problem: Following the example provided on "https://datatables.net/reference/event/childRow" for handling the 'childRow.dt' event doesn't show any output.

The event doesn't trigger the handler regardless if it's applied before or after table initialization. Listening on either 'childRow' or 'childRow.dt' makes no difference and neither does using a static data set or AJAX for table data. I've also tried adding and removing a row manually afterwards with DtTable.row.add() and DtTable.row().remove().

Am I doing something wrong or is this event deprecated or perhaps just not working in the latest version of DataTables?

DataTable shows incorrect or duplicated data after updating rows in responsive mode

Column Control and fixed Header bug?

$
0
0

https://live.datatables.net/besoqowu/1/edit?html,js,output

No error messages:

Hi! Loving datatables and the new ColumnControl extension! Whilst working on a table in a ASP.Net solution, I have however ran into a bit of an issue between ColumnControl and Fixed header that is present within the JS Bin, when filtering on the FreeForm Search on columns , those being on Position, Whenever it filters and changes size, it loses focus on the input boxes , is this intended or is there anyway to go around that? Thank you in advance!

Example of how to use fetch() with DataTables React component

$
0
0

The DataTables React component is very nice.

I like how changing the data prop triggers a re-render. I utilized this behavior to implement a simple server-side fetch() that asynchronously populates the initial DataTable.

The following React component, called FetchDataTable, fetches the table data from a server using the browser API fetch. It is much easier to use than ajax for smaller tables.

FetchDataTable.jsx:

//
// FetchDataTable.jsx -- Wrapper for DataTables React component with fetch()
//

import { useState, useEffect, createContext } from 'react';

function useFetch(fetchUrl, fetchOptions) {
    const [tableData, setTableData] = useState([]/*empty table*/);
    const [isLoading, setIsLoading] = useState(true);
    const [errorMsg, setErrorMsg] = useState(null);

    useEffect(() => {

        const fetchData = async () => {

        try {
            setIsLoading(true);

            // fetch() default options
            const opts = Object.assign({
                method: 'GET', // or 'POST'
                cache: 'no-store',
                //credentials: 'same-origin', // default
                headers: { // if POST
                    'Content-Type': 'application/json; charset=utf-8',
                    //'Content-Type': 'application/x-www-form-url-encoded; charset=utf-8',
                },
                //body: JSON.stringify(data), // if POST
                redirect: 'error',
            }, fetchOptions);

            const response = await fetch(fetchUrl, opts);

            if (!response.ok) { // Got non-200 range response (404, etc)
                throw new Error(`Server request failed: Error ${response.status}`);
            }

            let text = await response.text();

            const json = JSON.parse(text); // Throws SyntaxError if bad JSON

            if (json.error) {
                throw new Error(json.error);
            }

            const data = json.data;

            if (Array.isArray(data)) {
                setTableData(data);
            } else {
                throw new Error('Server did not return data[]');
            }
        } catch(err) {
          setErrorMsg(err.message);
        } finally {
          setIsLoading(false);
        }
      };

      fetchData(); // Start the async data fetch

      return () => {
           // Do useEffect cleanup here
      };

    }, []/*once*/); // end useEffect()

    const props = {
        tableData,
        setTableData,
        errorMsg,
        isLoading
    };

    return props;
}

/*
Expected JSON response:
{
  data: [
        { "UserId": 123, "FirstName":"Bob", "LastName":"Smith", "Role": "Manager" },
        { "UserId": 456, "FirstName":"Roger", "LastName":"Kline", "Role": "Tech Support" },
        { "UserId": 789, "FirstName":"Julie", "LastName":"Adams", "Role": "Sales" }
  ]
}

If an error occurs, the expected JSON response is

{ error: "Error message" }
*/

////////////////////////////////////////////////////////////////////////////
//
// Wrapper for <DataTable data={tableData}>
//
//

// Context to pass the fetched data down to the DataTable component
export const FetchDataTableContext = createContext({});

export function FetchDataTable({fetchUrl, fetchOptions, children}) {

    // Note the use of braces {}, not []
    const {tableData, setTableData, errorMsg, isLoading} = useFetch(fetchUrl, fetchOptions);

    if (isLoading) {
        return (
            <h1>Loading data...</h1>
        );
    }

    if (errorMsg) {
        return (
            <p style={{ color: "red" }}>Error: {errorMsg}</p>
        );
    }

    const contextData = { tableData, setTableData };

    return(
        <FetchDataTableContext value={contextData}>
          {children}
        </FetchDataTableContext>
    );
}

The following is a simple React app that uses the FetchDataTable component to populate a DataTable.

The example uses Bootstrap 5.

App.jsx:

// Example App

import { createRoot } from 'react-dom/client';
import { useRef, useState, useEffect, useContext } from 'react';

import * as bootstrap from 'bootstrap';
import DataTable from 'datatables.net-react';
import DT from 'datatables.net-bs5';

import 'bootstrap/dist/css/bootstrap.css';

import { FetchDataTable, FetchDataTableContext } from './FetchDataTable';

DT.use(bootstrap);
DataTable.use(DT);

function MyDataTable()
{
    const dtTable = useRef(); // Create a DT ref (Normally only plain DOM elements are allowed here, but DataTable is a special case)

    //Provides context.tableData, context.setTableTable()
    const context = useContext(FetchDataTableContext);

    const options = {

        lengthMenu: [2, 10, 25, 50, 100],

        // Put other options here

        columns: [
            { data: 'UserId' },
            { data: 'FirstName' },
            { data: 'LastName' },
            { data: 'Role' },
        ],
    };

    return (
        <DataTable id="users" ref={dtTable}
              data={context.tableData}
              options={options}
              className="display table table-striped table-bordered">
            <thead>
                <th>UserId</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Role</th>
            </thead>
            <tbody>
            </tbody>
        </DataTable>
    );
}

/////////////////////////////////////////////////////////////////////////////
//
function App() {

    const fetchUrl = 'https://my-site-name/my-api'
    const fetchOptions = { 'method': 'GET' };

    return (
      <div className="container">
        <FetchDataTable fetchUrl={fetchUrl} fetchOptions={fetchOptions}>
          <MyDataTable />
        </FetchDataTable>
      </div>
    );
}

/////////////////////////////////////////////////////////////////////////////

export const root = createRoot(document.getElementById("root"));

root.render(
    <App />
);

DataTable shows duplicated data when responsive

$
0
0

Link to test case: https://stackblitz.com/~/github.com/mizterdy07/vue3-test-datatable?file=src/App.vue&view=editor

Description of problem:
First, I opened the web page and resized the screen to 550px. At this width, four columns were hidden. Then, I clicked the Expand button to view the hidden columns (see the picture below).

After that, I clicked the Change Data button, which updates the values in the Description column to “11112222”. When I resized the screen back to the normal width of 1070px, the four previously hidden columns reappeared — but their data was duplicated (see the picture below).


Date search on ColumnControl

$
0
0

Hi everyone. My name is Filippo and I'm writing from Italy, this is my first post.

I've noticed that if I search for a date using the date picker in the "Start Date" column of this page, it doesn't find it. However, if I edit the text field, the search works. Does anyone has encountered the same problem?

Reference to buttons.name in config

$
0
0

Is it possibe to use the buttons.name setting to activate a set of buttons in a layout definition? (like 'buttons:main' or similar)
I would like to define multiple sets of buttons in the default settings and be able to refer to them in the config locally, but maybe this needs to be done through API calls after config?
KR, Bjørn H

grid layout - show custom div behind a feature element

$
0
0

How can I insert a custom div directly after the layout element paging?
Currently, it is displayed as a separate cell in the grid.

https://live.datatables.net/mijifezi/1/edit?html,css,output

<div class="dt-layout-row">
  <div class="dt-layout-cell dt-layout-full"></div>
  <div class="dt-length"></div>
  <div class="custom-div">hallo</div>
  <div class="dt-search"></div>
</div>

current

what i want

djangorestframework-datatables and searchPanes

rowReorder has started adding extra rows

$
0
0

Link to test case: https://www.wd4g.com/WCGateway/rowReorder_Debug.wc
Debugger code (debug.datatables.net): n\a
Error messages shown: no error message
Description of problem:
rowReordering was working fine until recently, now each time we do a rowReorder (or just drag the row to the top of the dt) we get a new rows inserted above the actually data rows (but below the column headers), this new row contains the datatables_length elements, and the datatable_filter elements. Also, we get a new rows below the data rows, (but above the table footer), this row contains the datatable_info and datatable_pagnation elements. This happen for each rowReOrder, so it duplicates each time.

I have tried removing all recent global changes to do with datatables, but the issue remains.

So, I'm struggling to find the cause of this issue.
If someone could please take a look and offer any advice that would be really appreciated.

Thanks, Chris

I'm trying to join the first name and surname from two different column and display it as full name.

$
0
0

Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:

Plugins columncontrol-bs5 and colreorder-bs5 not available through Composer

$
0
0

Hello,

As the title says, these packages are not available in the Packagist repository.
When doing the following commands:

composer require datatables.net/datatables.net-colreorder-bs5
composer require datatables.net/datatables.net-columncontrol-bs5

I receive the following messages:

Could not find package datatables.net/datatables.net-colreorder-bs5.
Could not find a matching version of package datatables.net/datatables.net-columncontrol-bs5. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (stable).  

These commands are given by Datatables download page when selecting the Composer installation.

I have installed other plugins through the same means (responsive-bs5, fixedheader-bs5, buttons-bs5 etc.) and there were no issues.

Is it possible to upload the missing plugins on packagist, please?

Thank you !


datatable download builder: jquery-ui missing textures?

$
0
0

I use jQuery UI with a theme that uses textures. There are two methods to include a jQuery UI style.

1) Method: jQuery UI ThemeRoller example
dataTables.jqueryui.css is loaded separately

2) Method: datatable download builder
Step 1. Choose styling => jQuery UI
datatables.css contains jQuery UI CSS styles

using Methode 1 ui-state-default

table.dataTable thead th.ui-state-default,
table.dataTable tfoot th.ui-state-default {
  border-left-width: 0;
}
table.dataTable thead th.ui-state-default:first-child,
table.dataTable tfoot th.ui-state-default:first-child {
  border-left-width: 1px;
}

using Methode 2 ui-state-default
table.dataTable thead > tr > *.ui-state-default { background: #f6f6f6; }

I have noticed that textures used with method 2 are lost.

The configured texture influences various elements, such as table headings.

How do you get a DataTables table Search input field to autofill with a parameter passed in a URL?

$
0
0

I have a page which builds a page with a column like this:

<td><a href='/bin/users?phone={{ $customerPhone }}' target='_new'>{{ $customerLabel }}</a></td>

It correctly passes the phone argument to the users page as seen in the URL:

https://devel.mysite.com/bin/users?phone=303-000-0000

How do we make this autofill the DateTables Editor table Search input field so that it limits the results to the user with that phone number, 303-000-0000?

Searching a table which contain tinyint values?

$
0
0

Can I search table data rows which have tinyint values?
Scenario: A table contains people. A table column is for marital status. 0=not married, 1=married. Please note that the information is not in text format.
How can I search using datatable and fetch the married people or the opposite?
Any example?
Thank you

How do you incase the table, and bottom row, in a div? but leave out the top?

$
0
0

This might be a dumb question but i want to incase the table itself and the bottom row in a div, but leave out the top row?

is there an easy why to do that with layout?

something like this:

<div class="dt-search"> search</div>
<div class="card">
   <div class="dt-table"></div>
   <div class="dt-bottom-row"></div>
</div>

again sorry if its a stupid question

search highlighting using mark.js

$
0
0

I would like to implement search highlighting using mark.js with DataTables 2
https://datatables.net/blog/2017/search-highlighting-with-markjs#Adding-custom-mark.js-options

JS Bin test case
https://live.datatables.net/teripiyu/1/edit

I want to add custom mark.js options, such as wildcard search, but it only works when I trigger the search manually.

$("#example").mark("R*os", {
    wildcards: "enabled",
    caseSensitive: true
});

Using the same settings to initialize the DataTable, the search functionality in the search field is not working when typing.

var table = new DataTable('#example',
 { mark:
    {  wildcards: "enabled",
      caseSensitive: true
    }
 }                         
);

How to rotate cell text and adjust it's height?

$
0
0

I would like to rotate the text in certain cells by -90 degrees, as they are currently taking up too much space in width.

For testing purposes, I tried:

<span style="transform: rotate(-90deg);display: inline-block;">My Vertical Text</span>

It works well, except that the height of the cell is not adjusted and all the text ends up overlapping (see capture)

What is the correct way to do this? Thank you.

Column Control appears two times

$
0
0

Hello,

I'm not new to DataTables.

But recently in a small project I wanted to use Column Control plugin. Everything works perfectly except that those controls are appear two times per column.

Any hints how to debug ?

Maybe something is called twice ? But could not figure it out yet. It is simple php file (twig Templates) which loads 4 rows from the database.

new DataTable("#test-table",{
    paging: true,
    searching: false,
    columnControl: ['order', 'colVisDropdown',['searchList']],
    ordering: {
        indicators: false
    }
});


Issues with Column Control and Column Reorder in State object

$
0
0

Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:
I am using the latest libraries and noticing 2 issues both of which are tied to the state not being updated properly to reflect the current state of the table.

  1. When i have individual search boxes using the column control search funtionality, when I type search text into the search field in column[2] the search text shows in the column control search for column[0] in the state object. I had to implement a cutom mapping function to correctly map the search to the correct column in the State object.

  2. When reordering columns, the columncontrols in the state object do not get updated to the correct indexes that they should be. In the state object below it shows that columns 7 and 4 should be search lists not search inputs. columns 5 & 6 should be search inputs. but if you look at the colReorder and the columnControl they do not align with the correct indexes. This is causing issues for the workaround I implemented for issues 1 because the column control data does not align correctly to the indexes in the colReorder.

    "colReorder": [
    0,
    1,
    2,
    3,
    7,
    5,
    6,
    4,
    8,
    9,
    10,
    11
    ],
    "columnControl": {
    "2": {
    "searchInput": {
    "logic": "greater",
    "type": "date",
    "value": "2/1/2020"
    }
    },
    "3": {
    "searchList": []
    },
    "4": {
    "searchInput": {
    "logic": "contains",
    "type": "text",
    "value": "acc"
    }
    },
    "5": {
    "searchList": []
    },
    "6": {
    "searchInput": {
    "logic": "contains",
    "type": "text",
    "value": "rn"
    }
    },
    "7": {
    "searchList": []
    },
    "8": {
    "searchInput": {
    "logic": "less",
    "type": "date",
    "value": "2/1/2024"
    }
    },
    "10": {
    "searchList": []
    },
    "11": {
    "searchList": []
    }
    },

Date picker with jQuery UI

$
0
0

Hi, am I the only one experiencing an error with the date picker?

Example: https://editor.datatables.net/examples/dates/dates.html

When I select "DataTables" as the framework, everything works fine.
However, when I select "jQuery UI" as the framework, the direct selection of a month or year in the date picker no longer works. The selection box flashes briefly and then disappears immediately.

This issue occurs with the Firefox browser (143.0.3).
Chrome (140.0.7339.208) doesn’t seem to be affected.

Database showing error code 18 what should I do to removeit

$
0
0

Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:

Query - for Help and better solution

$
0
0

**https://live.datatables.net/ciyuride/21/edit**:

At the above 'test case'

Add a content before the current text

only if the first row contains a 'specific word'.(there use '36' and another is '$2,')

It is working for the first page only.

So the query is

1- How to loop through the entire table ?

2- Whether the Javascript works well on all browsers (old and modern) ?

3- Any better method to tiny up the said Javascript ?

4- Unable to change the table cell values from the default values to check that what will happen if the same mentioned values '36' is available on two different column.

Looking forward for a solution.

george

Inline editing and tag fields

$
0
0

Hi Allan,

I'll continue here (from https://datatables.net/forums/discussion/81422/date-picker-with-jquery-ui
).

When I use inline editing for tag fields and clicking on 'Add' expands the selection list. As soon as I select an entry from the list, the tag editor disappears without saving the new value.

I extended the tags-multiple example with added "keytable".

Here is the code:

var editor = new DataTable.Editor({
    ajax: '../../controllers/joinArray.php',
    fields: [
        {
            label: 'First name:',
            name: 'users.first_name'
        },
        {
            label: 'Last name:',
            name: 'users.last_name'
        },
        {
            label: 'Site:',
            name: 'users.site',
            type: 'select'
        },
        {
            label: 'Permissions:',
            name: 'permission[].id',
            type: 'tags',
            limit: 4
        }
    ],
    table: '#example'
});

$('#example').DataTable({
    ajax: {
        url: '../../controllers/joinArray.php',
        type: 'POST'
    },
    columns: [
        { data: 'users.first_name' },
        { data: 'users.last_name' },
        { data: 'sites.name' },
        { data: 'permission', render: '[, ].name', editField: 'permission[].id'}
    ],
    keys: {
        columns: [0,1,3],
        editor: editor
    },  
    layout: {
        topStart: {
            buttons: [
                { extend: 'create', editor: editor },
                { extend: 'edit', editor: editor },
                { extend: 'remove', editor: editor }
            ]
        }
    },
    select: true
});

best regards
Ilja

Editor Ajax URL Replacement not working for uploads

Has anyone incorporated the softdelete example into the parentchild datatables example?

$
0
0

I think this is due to the dynamic nature of the child datatables in the parentChild example.
Apologizes if this has been answered previously, but I did not find anything in the search.

The line in the below code that is the issue (I think) is ' var rows = DataTables_Table_0.rows({ selected: true }).indexes();' which does not work. I attempted using the ID from inspect since there is no obvious instantiation of the datatable in question (at least that I can see).

Any ideas?

Thanks in advance!

{
label: 'Users:',
name: 'users.site',
type: 'datatable',
editor: usersEditor,
submit: false,
optionsPair: {
value: 'users.id'
},
config: {
ajax: {
url: '../controllers/NEWuser/users.php',
type: 'post',
data: function (d) {
if (siteTable) {
var selected = siteTable.row({ selected: true });
if (selected.any()) {
d.site = selected.data().id;
}
}
}
},
buttons: [
{ extend: 'create', editor: usersEditor },
{ extend: 'edit', editor: usersEditor },
//{ extend: 'remove', editor: usersEditor }

        {
        extend: 'selected',
        text: 'Delete',
        action: function (e, dt, node, config) {


            var rows = DataTables_Table_0.rows({ selected: true }).indexes();

            usersEditor
                .hide(usersEditor.fields())
                .one('close', function () {
                    setTimeout(function () {
                        // Wait for animation
                        usersEditor.show(usersEditor.fields());
                    }, 500);
                })
                .edit(rows, {
                    title: 'Delete',
                    message:
                        rows.length === 1
                            ? 'Are you sure you wish to delete this row?'
                            : 'Are you sure you wish to delete these ' +
                              rows.length +
                              ' rows',
                    buttons: 'Delete'
                })
                .val(
                    'removed_date',
                    new Date().toISOString().split('T')[0]
                );
        }
    }                  

    ],
    columns: [
        {
            data: 'users.first_name',
            title: 'First name'
        },
        {
            data: 'users.last_name',
            title: 'Last name'
        },
        {
            data: 'users.phone',
            title: 'Phone'
        }
    ]
}

}


Row animation missing after ajax.reload()

$
0
0

I'm trying to implement a branded row animation (e.g., fade-in or highlight) after calling table.ajax.reload(null, false) in DataTables. The goal is to visually indicate updated rows after an AJAX refresh.

I've placed the animation logic inside drawCallback, and confirmed via console.log that the callback executes. However, the animation doesn't visibly trigger — even though the class is applied.

$(document).ready(function () {
    usersTable = $('#usersTable').DataTable({
        ajax: {
            url: '/Admin/GetUsersAjax',
            type: 'GET',
            dataSrc: function (json) {
                console.log("AJAX response received:", json);
                return json.data;
            },
            error: function (xhr) {
                console.error("DataTables AJAX error:", xhr.responseText);
                alert("Failed to load user data.");
            }
        },
        drawCallback: function (settings) {
            console.log("drawCallback triggered");

            $('#usersTable tbody tr').each(function () {
                const row = $(this);
                row.removeClass('row-animate');
                void row[0].offsetWidth; // force reflow
                row.addClass('row-animate');
                console.log("Animation class applied to row:", row.text());
            });
        },
        order: []
    });

    // Optional: clean up after animation
    $('#usersTable').on('animationend', 'tr.row-animate', function () {
        $(this).removeClass('row-animate');
        console.log("Animation class removed after animationend");
    });
});
function PopupForm(url) {
    console.log("PopupForm called with URL:", url);

    var formDiv = jQuery('#masterModal');

    jQuery.get(url, function (response) {
        console.log("PopupForm GET response received:", response);

        if (response.trim().length > 0) {
            jQuery('#modalBody').html(response);
            formDiv.modal('show');
            console.log("Modal shown with content.");
        } else {
            console.warn("Modal content is empty. Skipping modal popup.");
        }
    }).fail(function (xhr) {
        console.error("PopupForm GET failed:", xhr.responseText);
    });
}

function SubmitForm(form) {
    console.log("SubmitForm triggered for form:", form);

    jQuery.validator.unobtrusive.parse(form);
    console.log("Validation parsed.");

    if (jQuery(form).valid()) {
        console.log("Form is valid. Submitting via AJAX...");

        jQuery.ajax({
            type: 'POST',
            url: form.action,
            data: jQuery(form).serialize(),
            success: function (data) {
                console.log("AJAX POST success:", data);

                if (data.success) {
                    if (document.activeElement) {
                        document.activeElement.blur();
                        console.log("Active element blurred.");
                    }

                    $('#masterModal').modal('hide');
                    console.log("Modal hidden after success.");

                    usersTable.ajax.reload(function () {
                        console.log("DataTable reloaded.");

                        const nodes = $(usersTable.rows().nodes());
                        console.log("Table rows fetched:", nodes.length);

                        nodes.each(function () {
                            const rowData = usersTable.row(this).data();
                            console.log("Checking row:", rowData);

                            if (rowData && String(rowData.UserID) === String(data.newUserID)) {
                                console.log("Matching row found. Applying animation.");
                                $(this).addClass('new-row-animate');

                                setTimeout(() => {
                                    $(this).removeClass('new-row-animate');
                                    console.log("Animation class removed after timeout.");
                                }, 1500);
                            }
                        });
                    }, false);

                    jQuery.notify(data.message, {
                        globalPosition: 'top center',
                        className: 'success'
                    });
                } else {
                    console.warn("Server returned error state:", data.message);
                    $('#modalBody').html(data.html);

                    jQuery.notify(data.message, {
                        globalPosition: 'top center',
                        className: 'error'
                    });
                }
            },
            error: function (xhr) {
                console.error("AJAX POST failed:", xhr.responseText);

                jQuery.notify("Server error occurred", {
                    globalPosition: 'top center',
                    className: 'error'
                });
            }
        });
    } else {
        console.warn("Form validation failed.");
    }

    return false;
}
/* Animation for adding new row in table */
@keyframes rowFlash {
    0% {
        background-color: #c6f6d5;
    }

    50% {
        background-color: #90ee90;
    }

    100% {
        background-color: transparent;
    }
}

#usersTable tbody tr.new-row-animate {
    animation: rowFlash 1.2s ease-in-out;
}

Any help would be greatly appreciated!



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>