3

The .hide function in my partial view is not rendering for second and third person initially, then the delay .hide and .fadein will not work either. I am new to js and jquery so I am probably missing something obvious... Why would this js script not be working inside of a partial view?

Everything works when it is all in the main view, but the reason I need a partial view is because I do not want to reload the entire page every 15 seconds. I have done some research and there might be something wrong with getting an html data type?

Main View:

@model IEnumerable<project.Models.MyList>

<div id="scrolllist">
    @Html.Partial("_ScrollList")
</div>

@section Scripts{
<script>
function loadScrollListPV() {
   $.ajax({
    url: "@Url.Action("ScrollList")",
    type: 'GET', // <-- make a async request by GET
    dataType: 'html', // <-- to expect an html response
    success: function(result) {
                $('#scrolllist').html(result);
             }
   });
}
$(function() {
    loadScrollListPV();
    // re-call the functions each 15 seconds
    window.setInterval("loadScrollListPV()", 15000);
});
</script>
}

Controller Action:

    public ActionResult ScrollList()
    {
        return PartialView("_ScrollList", db.MyList.ToList());
    }

Partial View:

@model IEnumerable<project.Models.MyList>


<div id="firstperson">
@*Get lastest record and display.*@
@foreach (var donor in Model.OrderByDescending(p => p.ProcessTime).Take(1))
{
}
</div>

<div id="secondperson">
@*Get second lastest record and display.*@
@foreach (var donor in Model.OrderByDescending(p => p.ProcessTime).Skip(1).Take(1))
{       
}
</div>

<div id="thirdperson">
@*Get third lastest record and display.*@
@foreach (var donor in Model.OrderByDescending(p => p.ProcessTime).Skip(2).Take(1))
{        
}
</div>

@section Scripts{
<script>
$("#secondperson").hide();
$("#thirdperson").hide();
function person() {
    $("#firstperson").delay(5000).hide(0, function () {
        $("#secondperson").fadeIn();
        $("#secondperson").delay(5000).hide(0, function () {
            $("#thirdperson").fadeIn();
            $("#thirdperson").delay(5000).hide(0, function () {
                $("#firstperson").fadeIn();
                person();
            });
        });
    });
}
</script>
}

Any help would be awesome and thanks in advance!

Alex
  • 175
  • 1
  • 3
  • 10
  • Your reason for using a Partial View is flawed. Your ajax success handler is only replacing the contents of `#scrolllist`, so with or without a Partial View you are not reloading the page. Additionally, the Partial View gets rendered (inserted into) the html stream. There is no difference in markup as far as the browser is concerned. Perhaps you are confusing MVC's Partial View with WebForm's UpdatePanel. – Sam Axe Sep 14 '17 at 18:57
  • @adiga thank you! I have implemented and works great. – Alex Sep 14 '17 at 21:12
  • Scripts NEVER go in partials. And `@section Scripts{` is not supported in partials anyway –  Sep 14 '17 at 21:47

3 Answers3

9

I am not 100% sure here, but I think there may be a problem with rendering the @script section in partial views according to this answer. It is mentioned that Partial Views are not able to use the @section element by default.

Try removing the razor syntax around the script section and just use:

<script type="text/javascript">
    $("#secondperson").hide();
    $("#thirdperson").hide();
    function person() {
    $("#firstperson").delay(5000).hide(0, function () {
        $("#secondperson").fadeIn();
        $("#secondperson").delay(5000).hide(0, function () {
        $("#thirdperson").fadeIn();
        $("#thirdperson").delay(5000).hide(0, function () {
            $("#firstperson").fadeIn();
            person();
        });
    });
});
}
</script>
MUlferts
  • 1,310
  • 2
  • 16
  • 30
  • So that worked for hiding those divs but the delay .hide and .fadein are still not working. is it possible I would need to the document.ready identifier for function person? – Alex Sep 14 '17 at 19:10
  • I was just thinking that, you can try wrapping the jquery with $(function () { }). Other than that, where do you call the named function "person" ? – MUlferts Sep 14 '17 at 19:12
  • Adding $(document).ready( before function and completing it at the end worked. This saved my day thank you! – Alex Sep 14 '17 at 19:13
2

1) Remove the @section Scripts{ and your code will work.


2) You should avoid the callback hell of hide() and fadeIn(). If there are 10 divs, you'd have to add 10 layers of that code. The below approach would work with any number of divs in your partial view:

You can assign your divs a class. Make only the first div visible by default. Create a function which will be called every 5 seconds.

// gets the currently visible div. Hides it.
// If this is last content `div`, shows the first div, else shows the next div
function incremental() {
  $visible = $(".content-div:visible");
  $visible.hide();

  $visible.next().is('.content-div') 
    ? $visible.next().fadeIn()
    : $(".content-div").first().fadeIn();
}

setInterval(incremental, 3000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="content-div">first content</div>
<div class="content-div" style="display:none">second content</div>
<div class="content-div" style="display:none">third content</div>

This partialIntervalRef variable will be defined in the global scope (Main View). And every time before loading your partial view, you should clear it.

<script>
    var partialIntervalRef;

    function loadScrollListPV() {
        clearInterval(partialIntervalRef);
        -----
        ----
        }

This is much more cleaner and extensible than the using the callbacks.


3)window.setInterval("loadScrollListPV()", 15000) should be changed to window.setInterval(loadScrollListPV, 15000)

adiga
  • 34,372
  • 9
  • 61
  • 83
  • Is there any downside to removing the `@section Scripts { }` from a partial view? Because now there is an inconsistency between where main views and where partial views render the `` tag. – Lukas Jul 06 '21 at 13:58
0

You can't call a section from within a partial view. You can call it as an action with Layout = null; to achieve a similar result.

Joshua Morgan
  • 678
  • 6
  • 18