Angular.js in ASP.Net MVC -- need to reload page twice - asp.net-mvc

I minimized the problem to this simple reproduction. Create new Asp.net MVC app, add Angular.js via nugget.
_Layout.cshtml:
<head>
<!-- Other stuff -->
#RenderSection("JavascriptInHead", required: false)
</head>
_Index.cshtml
#section JavascriptInHead {
<script src="~/Scripts/angular.min.js"></script>
}
<div ng-app>
{{2 + 2}}
</div>
So this works (obviously), however when I click, say About or Contact menu to reload another view and then go back to Home, I get
{{2 + 2}}
Then I click page reload two times and I get
4
Please help me understand this..

Angular bootstraps when the document loads. So if you are loading html that contains angular into your page without doing a full page refresh, you'll need to bootstrap angular manually. Try adding this script to your partial page:
angular.element(document).ready(function() {
angular.bootstrap(document);
});
btw, I for one appreciate you posting a concise example rather than 100 lines of code from your actual project. If your actual project has an app name, however, like this...
<div ng-app="myApp">
then the js you put into your partial page should look like this...
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
Documentation for manually bootstrapping Angular can be found here: https://docs.angularjs.org/guide/bootstrap

Related

Refresh page content after form submission

I have a PHP file that generates a JQuery-Mobile page using SQL-Queries:
<!DOCTYPE html>
<html>
<head>
[...]
</head>
<body>
<div data-role="page" id="page1">
[... a listview and a form ...]
</div>
<div data-role="page" id="page2">
[... some stuff ...]
</div>
</body>
</html>
The form has the same PHP file as action that generates the whole page. So, JQuery Mobile will submit the request to this file and refresh the page content (at least theoretically).
When submitting one of these forms, the content of the page get's updated. But after switching between the pages, the new content is lost.
I already tried to disable caching, but this did not work.
Also I read the documentation of jquerymobile, but I do not really understand how this ajax submission works. What should my PHP file return in case of an submission? The entire site?
Cheers
I would keep the form action outside the first file so that code is seperate. You could then submit the form using ajax and make the form action return some sort of JSON data to indicate whether the submit was successful (something like {code : 200, message : "Success"} should do)

jQuery Mobile ajax links not working properly in ASP.NET MVC application

I have a master layout looking somehow like this
<html>
<head>
...
</head>
<body>
<section data-role="page" data-theme="d">
<section data-role="content">
#RenderBody()
</section>
...
#Scripts.Render("~/bundles/jquery.mobile")
</section>
</body>
</html>
And I have a couple of controllers and templates pushing some code into content section of master layout.
When i click on a link:
Some order
the ajax loader is shown, the url changes, but all I see is the broken markup of the original page. If I inspect the code I will see that there are two page sections in the DOM (which means that the target page is successfully injected but isn't shown).
If I refresh page I will see the target page.
So what's wrong? Why can't I get the fancy JQM page transitions? thank you.
Add the data-ajax='false' on the links who were responsible for redirect you to another page.
JQuery Mobile uses AJAX navigation unless you tell it otherwise. The ASP.NET redirects have no problem to normal requests, but cause issues with AJAX. So my answer in this case is to turn off AJAX. For that, all you have to do is add the attribute data-ajax='false' to the tag.
In my case, an easy solution could be (as changing each Html.ActionLink/Url.Action is time consuming), adding this at the end of the _Layout.cshtml (just before closing of the 'body' tag).
$(document).on('pageinit', function() {
$('a').each(function() {
$(this).attr("data-ajax", "false");
});
});
That would be fine assuming you don't want jQuery mobile to use any Ajax with links too.
You can go ahead and use Ajax in most circumstances and only turn it off selectively where it can cause a problem.

jQuery .load() within .load()

i have 3 partial views
View 1:
//_yard.cshtml
#model Yard
<div>#Model.Name</div>
<div class="yard"></div>
#foreach(var house in Model.Houses)
{
<script type="text/javascript">
$(document).ready(function{
$(".yard").load("/community/Houses");
});
</script>
}
View 2
//_houses.cshtml
#model House
<div>#Model.Name<div>
<div class="house"></div>
#foreach(var level in Model.levels)
{
<script type="text/JavaScript">
$(document).ready(function{
$(".house").load("/Community/Levels");
});
</script>
}
View 3:
//_levels.cshtml
#model Level
<div>#Model.Name<div>
<div class="room"></div>
#foreach(var room in Model.Rooms)
{
<script type="text/JavaScript">
$(document).ready(function{
$(".room").load("/Community/Rooms");
});
</script>
}
The above sample, shows that i am loading a View 1 within another view using jQuery Load(), i then load View 2 withing View 1, and then and so forth, however, the first load() works fine, but the subsequint loads does not fire.
I think it is due to the $(document).ready(); function not being reset, however, i am not sure how to reset it on each load.
Problem Solved
With MVC the default template renders the jQuery script at the bottom of the page. I moved it to the top, and the ajax loads worked.
I know this makes no sense, but it fixed the problem. I will update the question after doing a little bit more investigation as to why this solves the problem.
Edit:
The answer below in general is helpful, but I think the real problem is syntax errors in your JavaScript. The .load() lines of code all have one too many ) at the end. Fix that, make sure you do not have more syntax errors by checking the JavaScript console in your browser, then also use the advice below :-)
Thinking about $(document).ready(); being "reset" is unhelpful, because it isn't and cannot be "reset".
It is an event that is fired the first time the DOM has been fully loaded and ready to be manipulated by JavaScript. The event happens once, and only once, when a web page is loaded for the first time. Any subsequent AJAX requests will not fire new $(document).ready(); events on the page. They will, however, fire other events - but not $(document).ready();.
Remove $(document).ready(); from View 2 and 3 and your code will work. (Tip: you should wrap your JavaScript in <script> tags, otherwise you may get some weird behaviour in some browsers).
The events that fire when AJAX requests have finished may help you out:
$.ajax(); has a success/error/complete handlers.
.load(); has a complete handler.

Jquery Mobile Javascript not working on ajax load

Have the following markup in my html page to toggle a search bar based on if a search icon is clicked:
<a id="searchIcon" href="/"></a>
<div id="searchWrapOuter" style="display:none;">
<div id="searchWrapInner">
<div id="formContainer">
<form id="searchForm" action="#">
<div>
<input type="search" name="search-mini" id="search-mini" value="" data-mini="true" />
</div>
</form>
</div>
</div>
</div>
Width the following javascipt/jquery:
$(function() {
$(document).on("click", "#searchIcon", function () {
var searchWrapper = $("#searchWrapOuter");
$(searchWrapper).slideToggle();
return false;
});
});
This code works as expected on a page load direct off a Url. When coming into the page off a link which is Ajax loaded, loads the contents of the page into the DOM, and the DOM ready handler only executes for the first page.
I have read about using the
$(document).on('pageinit'), not $(document).ready()/$(function()
I still haven't been able to get this to work when coming in off an ajax link however. What would be the correct way to implement these events to get the code to work coming in from an Ajax link?
Thanks,
Most likely it is because you are using IDs instead of classes. jQuery Mobile doesn't work well with IDs because it caches pages into the DOM so if you open a page, close it, then go back to the page, you might have your page twice inside the DOM (one visible, one hidden/cached). So when you do $("#searchWrapOuter") you don't know which element you are actually dealing with (in your case, probably the hidden one).
The solution is to change your IDs to classes. This is not very intuitive but I found that is the best way to work with jQuery Mobile.
Also note this comment in the doc which might also be relevant to you:
The id attribute of all your elements must be not only unique on a given page, but also unique across the pages in a site. This is because jQuery Mobile's single-page navigation model allows many different "pages" to be present in the DOM at the same time. This also applies when using a multi-page template, since all "pages" on the template are loaded at once.
http://jquerymobile.com/demos/1.2.0/docs/pages/page-anatomy.html
You can manually adjust delay time to 500ms and 1s.
$(searchWrapper).delay(1000).slideToggle();
My issue is that the page id was below the pages tags. So once I moved the page div above it, the javascript was included in the ajax page load. Previous to this

jQueryMobile page events not firing when navigating to a different html page

I'm trying to navigate to a different .html page using
$.mobile.changePage( "PlayGame.html", { transition: "slideup"}, true, true)
PlayGame.html is being transitioned to, however, none of the following are firing:
$(document).bind("mobileinit", function()
{
alert(1);
});
$('#gamePage').live('pageinit',function(event, ui)
{
alert('pageinit');
});
$('#gamePage').live('pagebeforeshow',function(event, ui)
{
alert('booooo');
});
However, if I do window.location.href = "PlayGame.html" then everything fires accordingly.
What am I missing?
Thanks
Tom
If the code in your example is in the <head> of the PlayGame.html document then it will not be included when the jQuery Mobile framework grabs the page via AJAX. That is why your custom code runs when you load the whole page but not when clicking on a link from another page.
You will want to either put your custom JavaScript in a single file and include it on every page (so it will be available no matter what page the user enters your site from) or you will want to move the custom JavaScript for each page into the <div data-role="page"> element for each page (so it will be included when the page is pulled into the DOM).
The reason is that when you click on a link to an external file, jQuery Mobile uses AJAX to pull out the first instance of a <div data-role="page"> element and places that element in the current DOM, everything else in the document is discarded.
Here is some suggested reading about how jQuery Mobile navigation works: http://jquerymobile.com/demos/1.0rc2/docs/pages/page-navmodel.html

Resources