0

I am trying to populate a HTML table from a database. The data is retrieved from the database fine.

The controller code:

public ActionResult Transaction(int pageNumber = 1, int resultsPerPage = 10)
{
    Logic.ManipulateTransaction.SelectTransactions(Guid.Parse(Session["UserId"].ToString()), Guid.Parse("013E3D0F-E755-495B-8D1E-4A3D1340ACF8"), 0, 9223372036854775807, false, DateTime.Now.Date, DateTime.Now.Date, pageNumber - 1, resultsPerPage);
    return View(currentPageTransactions);
}

When this page is visited for the first time, currentPageTransactions is returned to the view fine. The view recognises this as a model fine and populates the HTML table fine with the below code:

@{ int rowNumber = 0; }
     @foreach (var transaction in Model)
                {
                    <tr>                       
                        <td hidden>@transaction.transaction_id</td>
                        <td hidden>@transaction.category_id.ToString().ToUpper()</td>
                        <td>@transaction.name</td>
                        <td>@transaction.type</td>
                        <td>@transaction.amount</td>
                        <td>@transaction.description</td>
                        <td>@transaction.datestamp.ToString("MM/dd/yyyy")</td>
                        <td hidden>@(rowNumber += 1)</td>
                        <td width="20%">
                            <input type="button" class="btn btn-warning" value="Modify" onclick="EditTransactionModal(this)" data-toggle="modal" data-target="#modifyTransactionModal" />
                            <input type="button" class="btn btn-danger" value="Decimate" onclick="DeleteTransaction(this)" />
                        </td>
                    </tr>
                }
  1. When the dataset is returned to the view for the first time, the HTML table populates correctly.
  2. I manually insert a row into the database.
  3. A javascript function is then called, toinvoke ActionResult Transaction again. This gets called fine, and retrieves the entries from the database fine. When in debug mode, I can see the row that I inserted manually is present.
  4. The results are then returned to the view for a second time. When in debug mode on the view, I can see the new dataset, with new row as expected.
  5. However, when the razor code is executed to add it to the table, the table does not change at all.

Why is the HTML table not being updated, although data is being retrieved from the database fine?

Edit:

Javascipt/Ajax for calling ActionMehtod

function GetTransactions() {
                var paginationObject =
                {
                    pageNumber: $('#pageNumber').val(),
                    resultsPerPage: $('#resultPerPage').val()
                };
                $.ajax({
                    url: '/Transaction/Transaction',
                    data: JSON.stringify(paginationObject),
                    type: "POST",
                    contentType: "application/json;charset=utf-8",
                    error: function (errormessage) {
                        alert(errormessage.responseText);
                    }
                });
            }

Could it be something to do with POST? I have tried changing this to GET, but then I am not able to pass the properties of paginationObject to ActionMethod.

August Williams
  • 907
  • 4
  • 20
  • 37
  • 1
    The default HTTP verb for controller actions is `GET` so your calls might be getting cached. Are you using a library to issue your ajax request or just plain JavaScript? – StaticBeagle Apr 09 '19 at 18:25
  • Show us how you invoke the Transaction action. – Jasen Apr 09 '19 at 18:28
  • @Jasen I have included it into the question. – August Williams Apr 09 '19 at 18:31
  • @StaticBeagle I've not heard of using a library for such purposes so probably no. I included my JS function if that answers your question? – August Williams Apr 09 '19 at 18:33
  • 1
    With the POST request you shouldn't be getting caching issues. **However, you completely ignore the returned response.** Add a success handler and replace the existing html. – Jasen Apr 09 '19 at 18:36
  • @Jasen I suppose a better question for me to ask is how to post data but get data at same time? – August Williams Apr 09 '19 at 18:40
  • The code you posted is `jQuery` so even though it's pretty much ubiquitous in every example on the web, it's still a library. I was just trying to figure out what your code looked like. – StaticBeagle Apr 09 '19 at 18:54
  • @StaticBeagle I understand. Sorry for any confusion - I'm quite new to web scripting. – August Williams Apr 09 '19 at 18:57

1 Answers1

1

With AJAX, your browser will not navigate away from the current page and will not automatically reload the page. This is usually what we want when we use AJAX. Therefore, you'll need to trap the response from the AJAX POST and update the DOM yourself.

First identify or create a parent element.

<div id="parent">

    @* The table is what we want re-rendered after the POST, then inserted here *@
    <table>
    @{ int rowNumber = 0; }
    @foreach (var transaction in Model)
    {
        <tr>                       
            <td hidden>@transaction.transaction_id</td>
            ...
        </tr>
    }
    </table>

</div>

Then add a success handler and replace the HTML result.

$.ajax({
    url: '/Transaction/Transaction',
    data: JSON.stringify(paginationObject),
    type: "POST",
    contentType: "application/json;charset=utf-8",
    error: function (errormessage) {
        alert(errormessage.responseText);
    },

    success: function(htmlResponse)
    {
        $("#parent").html(htmlResponse);    
    }

});
Jasen
  • 14,030
  • 3
  • 51
  • 68
  • When we replace the HTML result, does this have a significant impact on efficiency or no? I'm assuming that since we already have the response, it is client sided too? – August Williams Apr 09 '19 at 18:59
  • The biggest benefit is the user doesn't experience a full reload -- it won't appear to have navigated away. If you are only replacing a few lines on the document then yes that is less traffic over the network. – Jasen Apr 09 '19 at 19:07
  • I understand. I've noticed something with your example. If I put a breakpoint anywhere in `GetTransactions()` , it will be hit the first time I do `POST` and the table refilled as expected. When I go again for a second time, the breakpoint is not hit, but the table is still refreshed as expected. How can it be obtaining the correct data when the `POST` is not being done? – August Williams Apr 09 '19 at 19:12
  • Is that script on the page also replaced along with the html content? – Jasen Apr 09 '19 at 19:17
  • Sorry for that unclear answer. I have looked at the HTML response. It includes the `` tags this is where all the scripts are being loaded. So yes, the script seems to be reloaded with the html content. – August Williams Apr 09 '19 at 19:39
  • 1
    If you created your breakpoint in script that is replaced, then the next run will be in a different debugging context. Write your main page so that the script does not get replaced and the table is the only html that gets replaced. I have another example here https://stackoverflow.com/a/26025503/2030565 – Jasen Apr 09 '19 at 19:54
  • Ah, partial view. That makes a lot more sense now. Only the HTML for the table is returned. Thank you for this info. – August Williams Apr 09 '19 at 20:54