Getting sum of salary when using date range filter
Getting sum of salary when using date range filter
First of all, I have this test case http://live.datatables.net/veqetisa/1/edit
and I don't need to display the table on load. I need to display the table when the user choose dates. I did this by using hide and show functions and it is working perfectly fine, but is this a good way for this? Or there is a better way? Second, I don't need to display the table unless BOTH dates are entered not one date only, also I did this that as shown above in the test case, Is there a better way of doing this? Third, the important thing, when the user enters both dates, I need to get the sum of salary and display it rather than showing the original table (which is the date and salary). How can I do this?
This question has accepted answers - jump to:
Answers
One problem is this:
Each time you change
#min
you are creating a new (additional) event handler for#max
. Now when you change max the event handler will run multiple times. Plus you have the reverse of this so you will end up with multiple event handlers running when selecting the dates. Remove the inner event handler.Instead of OR use an AND conditional, like this:
This example shows how to get the sum of a column. Use the
selector-modifier
of{ search:'applied' }
to sum the data of the matched rows. Similar to theTotal over this page
example.Kevin
@kthorngren Thanks Kevin! I fixed the min and max issue. Now regarding the sum, here is the test case that I did http://live.datatables.net/fifemisi/1/edit
I faced a lot of errors, and I don't really know how to fix them... I removed total over this page section because I need it on all pages... Also, footerCallback, does that means the sum will be displayed at the footer? I don't need to display it at the footer I just need to display it instead of the table (replace the whole table with the sum). Is this possible?
Using the
footerCallback
is one option. Its one of many callbacks that are called on every draw. The key is it gives you easy access to the footer. You don't have to place the result in the footer though. You can place it in any DOM element. Just to eliminate confusion, when you debug the code a year from now, it might be better to use a more generic callback like `-option drawCallback.You have the
footerCallback
code outside the Datatables initialization code. It needs to be placed in the init object, like the example.Kevin
@kthorngren My bad... I now placed the code inside datatables init code here is the test case http://live.datatables.net/lasapecu/1/edit
But I'm still getting errors... I copied the same code from the link https://datatables.net/examples/advanced_init/footer_callback.html
with some changes, but still I am facing errors...
You are getting this error:
This line is not correct:
I replaced it with the statement from the footercallback example.
Next you are getting this error:
Its from this line because you don't have
table
defined:Next you are getting this error:
It's due to having
You have 2 columns defined for the table but you have essentially defined 5 with the
colspan="4"
I added the
{search:'applied'}
. I believe this is what you are asking for.http://live.datatables.net/lasapecu/2/edit
Kevin
@kthorngren Yep! That's right! Now, I edited the code so it appears like this http://live.datatables.net/wijiqaqa/1/edit
which almost near to what I want... Now I need to display the "total" under "amount" in the table not in the footer... How this can be done?
I would add a
span
tag, with anid
attribute, to the cell you want to place the total then update thespan
with the total. Like this:http://live.datatables.net/wijiqaqa/2/edit
Two changes were made:
Not the use of toFixed() to show only two decimal places. Remove the toFixed to see the difference.
Kevin
@kthorngren Yeah, thanks it worked! Now after a lot of testing, I've found there is some validation issue in this code
if($('#min').val().length > 0 && $('#max').val().length > 0) {
this code means if both inputs are not empty. I must change this to, if both inputs has VALID dates not if the they are not empty. Because, if you type in the first input 01/02/2022 and in the second input 0/02/2022 it will still give me the total, which is not what I want... So, I need to check if both inputs has valid dates to calculate total else show nothing. What is the best way to do this?
Since you are using moment.js in the plugin maybe you can use moment.js' isValid() method. You can find examples in their docs.
Kevin
@kthorngren Thanks Kevin! Now I implemented the code in the last test case in my real project (almost the same code) it worked when I try to input 2 same dates, but when I try to input 2 different dates, it will always gives me the the first record (the first amount), meaning it only recognizes the first amount. Also, another issue, if I input same dates and then if I need to change either dates, it will still give me the first amount, it does not update...So, I found that it will always gives me the first amount or 0.00 So, I thought the issue is that the data that I brought is from the database, I am using PHP and MYSQL to bring the data, and I think this is the issue. So, I used ajax, and I successfully brought the data. I added this code to my previous code:
"ajax":{
"url": "ajax/datatables_data.php",
"dataSrc": ""
},
"columns" :[
{"data": "invoice_date"},
{"data": "final_total"}
],
Is it really the issue that the data is coming from the database? And is it correct what I did which is using ajax? Or the issue is not that, it is just another issue? Because even when I used ajax, and input 2 dates, I am always getting 0.00 total... I am really confused... By the way, I checked if the data is really being brought from the database, both using ajax or just using PHP and MYSQL and the data appeared well. Also, I tried entering data as pure HTML like the test case above everything worked 100%. So, I guess the issue is related to the data being brought from the database. Please I need you to confirm.
Sounds like you are having a problem with the totals from the footerCallback. The data source doesn’t matter. There might be a difference with the data. Use the browser’s debugger or console log statements to debug the footerCallback function.
Kevin
@kthorngren Could you please give me more details? Is what I did correct? Which is using ajax? Or no need for ajax? You said data source doesn't matter... But I think it does matter I am not sure, because for example, when using PHP and MYSQL, the total in the second table does not update because it is static, whereas using ajax the data is not static... Does it make sense? Or I am wrong? Because, as I said previously when I enter the data in the table using pure HTML as the test case, it works perfectly fine.
@kthorngren Ok, after a lot of testing I made it work! I found that I MUST use ajax in this situation, also my issue was in the date format. Ok, now I have this test case http://live.datatables.net/hobobabe/1/edit
For some reason, buttons are not showing in the test case but in my real project is showing, anyways. I need to show the PDF button and print button when the second table appear. Also, I need when I press on PDF button, download the table as PDF it is working, but it gives 0.00 as an amount... Same thing for print button. Why is this happening?
You are loading datatables.js including the buttons multiple times. Only load them once. I used the download builder to generate new CDN with buttons, etc and replaced everything you had.
You turned your second table into a Datatable. When the footerCallback of table1 updates the cell in table2 its using the jQuery method:
Now that table 2 is a Datatable you need to tell it about the update. Datatables does not know about this direct HTML update. See this FAQ for more details. In this case you can use
cell().data()
to update the Datatable. Note you will need to initialize the second table first or you will get errors when the first table initializes. Or useataTable.isDataTable()
to check if its a Datatable before using thecell().data()
command.Updated example:
http://live.datatables.net/xalahegu/1/edit
Kevin
@kthorngren Thanks Kevin! That worked! I did use isValid, but I think I need more of validation. Try to input dates that are not available in the table, it will show the table with 0.00 amount. I don't need that, I need to show no matching records instead of the table. So, the table mustn't show unless there is a valid date + date available in the first table. Last thing, If I press the PDF button and download the table it worked perfectly fine, but I need to change the width of the table, as you can see the width is too short in comparison of the table in the page...
One option is to get the number of rows in table 1 after the plugin runs. You can use
rows()
withcount()
to get the number of rows displayed, something like this:If the result is 0 then display "No matching records" otherwise show table 2.
See if this thread about setting columns widths when exporting PDF helps.
Kevin
@kthorngren Thanks Kevin! I fixed the width issue. This thread https://datatables.net/forums/discussion/62138/how-to-set-pdf-column-widths-using-customize
didn't fix the width issue. I used this https://datatables.net/forums/discussion/33464/export-pdf-with-100-width
and this
https://stackoverflow.com/questions/48120995/how-do-i-center-the-entire-datatable-in-the-pdf-using-jquery-pdfhtml5
to fix the width. Now regarding
table1.rows({search: 'applied'}).count(
Where should I put it?
Place it in your click event. Maybe something like this:
Kevin
@kthorngren Thanks Kevin! But the code you wrote only works when BOTH dates are not available in the table. But if one date is available, the second table will still appear...
Sounds like your search plugin is not hiding all of the rows the way you expect. I would start by commenting out the statements that hide table1 so you can see what is happening. Then make adjustments to your search plugin to hide the rows as per your requirements. I suspect the initial table shows all the rows and your click event only updates when both inputs are valid.
Kevin
@kthorngren Ok, I think I have a better idea... Since I am using ajax anyways, can I have only 1 datatables table, and I do the date range filter + calculations all server side from the database, meaning the date range filter will take both inputs directly from datatabase and calculate amount, and then showing the amount in 1 table rather than having 2 tables and rather than showing all rows for the first table and filter from the first table... Also, I think this should help of taking long time to load all records from the database and reduce load. I am using PHP and MYSQL. Is this better and possible?
Thats a fantastic idea. You can use
ajax.data
as a function for table2 to pass the two date inputs. The server script can fetch and compile the data the way you want for table2. In the change event useajax.reload()
to fetch the new data set. See this example for passing the parameters. You don't need to enable server side processing for this to work.Kevin
@kthorngren After searching on YouTube for video explanations on how to do it, all videos that I watched, data must be fetched/display in a table first to start using date range filter... What I need to do is that I don't want to fetch/display anything on a table, I just need on the screen the 2 date inputs, and then after I enter both dates, the salary must be calculated automatically and display in a table, without fetching/showing data in a previous table. Is that possible? And if possible please is there any explanations on how to do it?
There isn't much to change in the client. You will remove the search plugin and table 1. Table 2 will fetch the data via ajax and use
ajax.data
aas a function to send the min and max inputs as parameters. In the input change event you will useajax.reload()
instead ofmytable1.draw();
.You will need to use the
ajax.reload()
callback function to display the No matching rows or the table. Something like this:This will check the length of the returned JSON data. I didn't test the code so there might be errors but it should get you close.
Your server script will need to get the min and max parameters and handle them appropriately.
Kevin
@kthorngren It it really confusing to me... When I removed the search plugin, I can't now choose dates... Here is my HTML and Javascript code for now, could you please check it for me:
That doesn't make sense as the search plugin has nothing to do with choosing the dates. Maybe check the browser's console for errors. Otherwise its hard to say why the date picker isn't working. Please update your test case to show the issue.
If you need to use
"dataSrc": ""
then change line 38 toif ( json.length === 0 ) {
removing the.data
.Kevin
Also the
ajax.data
function you are using does not expect thereturn dtParms
in line 25. Remove it.Kevin
@kthorngren Ok, after I checked the code above, it seems that I removed
datetime
code by mistakeOk now the new full Javascript code is:
Now I can choose between dates. Also, I guess
dataSrc
, is important right?How can I post this as a test case? Since, I am using PHP and MYSQL as a server script. Also, I can't upload it on a live server/host at the moment... Please, If you can keep up with me here. So, does my JavaScript code ok for now?
ajax.dataSrc
points Datatables to the location of your row data in the JSON response. See the Ajax docs for details. If you are seeing the row data then you have it set correctly.Looks like you removed the
ajax.data
function but otherwise there aren't any obvious errors. When I said to remove it I meant just the unexpectedreturn dtParms
statement.Kevin
@kthorngren Thanks Kevin! I added this code
after looking on this post https://datatables.net/forums/discussion/44998/serverside-processing-range-search
But now after you told me to remove only
return dtParams
I removed it as you saidNow where should I do the calculation of the salary? Is it in client script or server script? Here is the server script, please check it for me:
Is the server script ok?