Search code examples
javascriptjqueryajaxasp.net-mvcdelay

Change webpage back and forth using jQuery and ASP.NET MVC?


It is an ASP.NET MVC web application for which I wish to display content of two different websites after a delay of 30 seconds. The two websites are properly displayed given their respective URLs. Now, only remains to swap the two pages after the given delay.

HomeController

public class HomeController : Controller { 
    public HomeController(SomeViewModel viewModel, Uri otherWebsiteUri) {
        this.otherWebsiteUrl = otherWebsiteUrl;
        this.viewModel = viewModel;
    }

    public ActionResult Index() {
        return View(viewModel);
    }

    public ActionResult OtherWebsite() {
        return View(otherWebsiteUrl);
    }

    private Uri otherWebsiteUri;
    private SomeViewModel viewModel;
}

Index.cshtml

@model MyProject.ViewModels.SomeViewModel

@section header {
    <!-- Header content here... -->
}

<div>
    <!-- Page content here... -->
</div>

<script type="text/javascript">
    $( document ).ready( function() {
        var displayWebsiteContent = function ( url ) { 
            $.get(url, $( body ).html(data)); 
        };

        var milliseconds = 30000;
        var rootUrl = window.location.protocol + "//" + window.location.hostname;
        var currentUrl = window.location.pathname;
        var otherWebsiteUrl = rootUrl + "/Home/OtherWebsite";

        $( "body" ).delay( milliseconds ).queue( function() {
            if ( currentUrl.toLowerCase().indexOf( "other" ))
                displayWebsiteContent(rootUrl);
            else
                displayWebsiteContent(otherWebsiteUrl);
        });
    });
</script>

OtherWebsite.cshtml

@model System.Uri

<iframe src="@Html.DisplayForm(m => m.AbsoluteUri)" 
        width="98%" 
        height="1000px" 
        frameborder="0" 
        scrolling="no">
</iframe>

So far, I have come across these related SO Q/A:

I thought that I had to put the jQuery delay script inside the Index.cshtml as this is the first page being loaded, and that I do not which the timer to execute when outside of these two pages/controller methods.

Any hints and tips on how to make it?

EDIT Following Chris Pratt's recommendation

I have opted for a single script per page which redirects to each page.

Index.cshtml

<script type="text/javascript" src="../../Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $( document ).ready( function() {
        var displayWebsiteContent = function ( url ) { 
            $.get(url, $( body ).html( data )); 
        };

        var milliseconds = 30000;
        var rootUrl = window.location.protocol + "//" + window.location.hostname;
        var otherWebsiteUrl = rootUrl + "/Home/OtherWebsite";

        $( "body" ).delay( milliseconds ).queue( function() { 
            displayWebsiteContent( otherWebsiteUrl ); 
        });
    });
</script>    

OtherWebsite.cshtml

<script type="text/javascript" src="../../Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $( document ).ready( function() {
        var displayWebsiteContent = function ( url ) { 
            $.get(url, $( body ).html( data )); 
        };

        var milliseconds = 30000;
        var rootUrl = window.location.protocol + "//" + window.location.hostname;            

        $( "body" ).delay( milliseconds ).queue( function() { 
            displayWebsiteContent( rootUrl ); 
        });
    });
</script>    

Notice that I have blindly tried to add the <script src="jquery-1.7.1.min.js"> and the behaviour changed from Microsoft runtime error: '$' is undefined to an almost working piece of code.

Only now, an exception or the like is thrown stating that data is not declared, which I can partially understand. So I have also tried the following while doing the get request.

var displayWebsiteContent = function ( url ) {
    $.get( url
        , function ( data ) {
              $( body ).html( data );
          });
};

And this does nothing.

To make it clear, I wish to be able to perform this:

Index() (wait 30 seconds)
OtherWebsite() (wait 30 seconds)
Index() (wait 30 seconds)
OtherWebsite() (wait 30 seconds)
...

EDIT After further diggings, following Chris Pratt's hints about having a script on each single page the swapping is applicable to.

Solution

Further diggings conducted me to find this solution which was the missing masterpiece to my chef-d'oeuvre. =P

MVC Redirect to View from jQuery with parameters

The key to the masterpiece is window.location.href over the $.get() method.

Index.cshtml

<script type="text/javascript" src="../../Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $( document ).ready( function() {
        var displayWebsiteContent = function ( url ) { 
            window.location.href = url; 
        };

        var milliseconds = 30000;
        var rootUrl = window.location.protocol 
                    + "//" 
                    + window.location.host;

        $( "body" ).delay( milliseconds ).queue( function() { 
            displayWebsiteContent( rootUrl ); 
        });
    });
</script>    

OtherWebsite

<script type="text/javascript" src="../../Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $( document ).ready( function() {
        var displayWebsiteContent = function ( url ) { 
            window.location.href = url;
        };

        var milliseconds = 30000;
        var rootUrl = window.location.protocol 
                    + "//" 
                    + window.location.hostname;            

        $( "body" ).delay( milliseconds ).queue( function() { 
            displayWebsiteContent( rootUrl ); 
        });
    });
</script>    

Et voilà !


Solution

  • The JavaScript on page is only good for that page. You can't write JavaScript that applies to the actual browser tab/window or something outside of creating a browser extension. So, you can either add code to each page that redirects you to the other, or pretty much your only other option is to use a frameset or iframe, such that you can have some global JavaScript that cycles the frame/iframe URL without having to actually move off the main loaded page in the browser tab/window.