In-lined Javascript blocks not initialized - javascript

On a jQuery page, I have a login form. The code is simple enough:
<form method="post">
<div data-role="fieldcontain">
.... Form here
</div>
</form>
but the following form is submitted, JQM loads the next page via Ajax POST.
The problem is that any in-line Javasctipt on that new page is NOT initialized. I'm not talking about the $(document) elements etc. the entire in-lined Javascript blocks aren't initialized.
However if I add
data-ajax="false"
to the form tag, everything is fine. The page is loaded and initialized correctly.
Why does this happen, and is there a way to trigger a page initialization with the ajax loaded content?
I've observed this on both Firefox and the Android Webview clients.

Reason data-ajax="false" worked in your case is because it will force a full page reload which will incidentally trigger page markup enhancement.
This is a segment from jQuery Mobile documentation:
It's important to note if you are linking from a mobile page that was
loaded via Ajax to a page that contains multiple internal pages, you
need to add a rel="external" or data-ajax="false" to the link. This
tells the framework to do a full page reload to clear out the Ajax
hash in the URL.
Now in your case if you want to enhance new page content use this:
$('#pageID').trigger('create');
or in case you have also made changes to header and footer use this:
$('#pageID').trigger('pagecreate');
If you want better understatement take a look at my blog ARTICLE, were I am talking about page content markup enhancement in great details. There you will find examples for functions mentioned on top. It can be also found HERE.

If you load your page with the default jQuery Mobile implementation (which utilizes ajax), only the script blocks on the first page (<div data-role="page">) will get loaded.
You can turn off ajax loading via mobileinit which will disable ajax loading globally or you can disable it via the source link.
$(document).on("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
or
<a data-role="button" data-ajax="false"
href="myPageWithItsOwnScriptBlock.html">Link</a>
If you want to continue using ajax loading, you can place the script block inside of you "page" <div>
<div data-role="page">
<script src="myscript.js"></script>
<div data-role="header">
....
Details here:
http://jquerymobile.com/demos/1.2.0/docs/pages/page-scripting.html

Try to encapsule your inline JS code into something like this:
$(document).bind('pageinit', function(event) {
// your inline code goes here
});

Related

Loading a html page with pure Javascript using AJAX

There is a main page and there are links on that page. When the individual links are clicked, it is supposed to load the contents that link loads inside a div tag of the main page.
Example:
MainPage.htm
<html> ...
<body> ...
<div id="MainContent"> </div> ...
<a href='Link1.htm'>Link 1 </a>
...
</html>
Link1.htm
<script src="main.js">...
<div> other contents here </div>
When user clicks on the Link 1, the browser doesn't go to that page, instead AJAX is used to fetch that linked document and load inside #MainContent.
But, the problem is that the linked page has a table and there are table manipulation codes that needed to be run when it first loads. In fact that linked document has link to separate script and some functions that are supposed to run on window.onload.
When I simply load that Linked document using AJAX I am using following approach:
MainContent.innerHTML = XHR.responseText;
This is not helping run the window.onload codes on that linked document.
Are there any solutions or workaround for this type of problem?
Just for side note: I am just Using Javascript no other APIs like angular or jQuery or similar.
Something is wrong with your approach. The main problem here is that the context of the new content that you are getting via ajax is not gonna be executed because the window.onload is already done.
When you refer to "table manipulation codes" I assume that there are a couple of javascript functions that needs to be executed after the content is properly appended in the html, so what you can try over here is moving those "manipulations" to a separate js file and include it in the index.html and execute the proper functions in the success callback after getting the content via ajax.
I think this should be the more accurate approach.

JQuery: Combine multiple pages into one

I am developing an application by using phonegap and jQuery Mobile. Phonegap recommends a single document structure. As 5 divs or more in a document are pretty unclear, I'm trying to split up my pages (the div's) into multiple documents. As soon as phonegap loads the app, I want to insert these documents into the index.html.
function loadPage(external_document) {
var docname=external_document+".html";
$.get(docname, function(data) {
console.log(docname+" loading");
$("body").append($(data).find("body"));
$("head").append($(data).find("head"));
console.log(docname+" loaded");
});
}
document.addEventListener("deviceready", function(){
loadPage("DialogCredentials");
}, false);
DialogCredentials.html
<html>
<head>
<script type="text/javascript" src="js/DialogCredentials.js"></script>
</head>
<body>
<div data-role="page" id="dlg_credentials">
<div data-role="header"><h1>Login</h1></div>
<div data-role="content">
...
</div>
</div><!-- /page -->
</body>
</html>
As soon as the loadPage gets executed there should be a <div id="dlg_credentials"… and the corresponding javascript tag in the dom of my main document. But it isn't. There are no errors shown in the web inspector.
So what am I doing wrong here?
Without setting up a test case for you, if you really want to separate your pages to make your coding easier I would recommend to load the pages the standard way for jQuery Mobile i.e.
$.mobile.changePage( "about/us.html", { transition: "slideup"} );
This way you aren't reinventing the wheel and it satisfies your request. The overhead will be negligible compared to your proposed solution in any case let alone taking into account you want the first page to render quickly rather than to be blocked by inserting many pages before any html is rendered in any case. Since they will be local on the device in any case Phonegap will be able to serve them very quickly.
One thing to remember when loading pages through jQuery Mobile is that it strips out anything in the target page outside of the
data-role="page|dialog|popup"
tag and therefore to load custom page-specific javascript I would recommend you include the script tag directly below the
data-role="page"
opening tag and set any page initialization to occur on "pageinit"
<div data-role="page" id="options" data-theme="a">
<script type="text/javascript">
$(document).bind('pageinit', initializeOptions());
function initializeOptions() {
// do your page initialization here . . .
}
</script>
<!-- rest of page continues here . . . . -->
and then continue with the rest of your page as needed. That way it will be parsed when the page is loaded via the $.mobile.changePage method.
Hope that helps.
Dynamic loading is a feature of several Javascript frameworks. AngularJS and Backbone.js for example. Maybe take a look at their approach to loading multiple views?
I have previously worked on an app that did this by adding an empty div for each view to the index.html, and then dynamically loading the Javascript for each view on demand. The Javascript for the views was responsible for rendering the HTML into the div for that view.

$(select).selectmenu('open') doesn't work if page is loaded using ajax

I have a button that shows a dropdown menu when clicked. This code works on pages that are loaded with data-ajax="false":
$('#btnMainMenu').live('click', function() {
$('#dpMainMenu').selectmenu('open');
});
But there are some anchors on the website where data-ajax="true", so whenever the users load those pages - the codes above doesn't seem to work.
Pages that are loaded with data-ajax="true" only load a specific part of the pages (which is the default behaviour for jQuery Mobile). Namely everything between <div data-role="page">...</div>. Does your code work even though pages are loaded this way?
References: Linking Pages
I just had the same problem and my solution was to include the code bellow in the body of the page that is being loaded via Ajax (I put it just bellow the form).
<script>
$('document').read(function () {
$("#form-id").trigger("refresh", true);
});
</script>
With this, when the page is ready Jquery recreates the form where the selectmenu is and so all behaviours are back again.

Jquery mobile navigation model

I am building a mobile site and I am using the jquery.mobile library. I am facing problems wrt how jquery.mobile is handling the navigation. It is using ajax for all navigation calls and replacing the DOM.
I want normal postbacks and do not need the ajax method.
also, there is a loading <div> on all the pages at the bottom. I do not want that. I know its something to do with the ajax request method.
does anyone have any experience with it? thanks a lot.
Amit, it is not true that jquery mobile uses ajax for all navigation. You can manually navigate between pages programmatically via
$.mobile.changePage('#newpagediv');
You can have multiple pages in the html, preloaded and navigate via button click
<div id="first" data-role="page">
Go to second
</div>
<div id="second" data-role="page">
</div>
Try disabling it in the $.mobile settings like:
$.mobile.ajaxLinksEnabled = false;
The JQM Documentation actually specifies:
$.mobile.ajaxEnabled = false;
Or you could also specify
rel=external
directly on your tags to let JQM load the page "normally" and without ajax.
PS: note that in this case the whole JQM will need to re-initialize (as well as your code) on each new page load.

('#').dialog is not a function error after using jQuery's .load() function

I have the following code:
<?php
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
'id'=>'mydialog',
// additional javascript options for the dialog plugin
'options'=>array(
'title'=>'Confirmar',
'resizable'=>'false',
'autoOpen'=>false,
'modal'=>true,
'buttons'=>array('Eliminar'=>'js:function(){deleteMessage();$(this).dialog("close");}',
'Cancelar'=>'js:function(){$(this).dialog("close");}',),
),
));?>
<div style="display:none">Do you confirm you want to delete the item?</div>
<?php
$this->endWidget('zii.widgets.jui.CJuiDialog');
?>
<input type="button" onclick="js:openDlg()" value="Open the dialog">
<script language="javascript" type="text/javascript">
function openDlg(){
$("#mydialog").dialog("open");
}
</script>
This works PERFECTLY, until i needed to call jQuery's .load() function. For testing purposes, i have a button which calls the .load() method (although supposedly it should be called when the doc is ready). If i hit the open dialog button before clicking this trial button, the dialog opens correctly. Else, it fails with the following error:
$("#mydialog").dialog is not a function
$("#mydialog").dialog("open");
Trial button:
<input type="button" onclick="js:load_wall()" value="Load Messages">
function load_wall(){
var liga = $("#liga_id").val();
$('#div_wall_messages').load('displayMessages',{liga_id: liga}, function(){
});
Please, any help is more than welcome. This error is driving me crazy. thank you!!
What's displayMessages? Is it a page with scripts in it? Is it a page that includes another copy of jQuery? If you include a second copy of jQuery you will be overwriting your existing copy—possibly you are overwriting a jQuery that has the Dialog plugin loaded into it with a new one that doesn't.
If you want to load into a div and what you've got in the file being loaded is a full page of HTML (including <head>, <script>s et al), then you should only load the fragment of content (by id) that you want into your target. In all cases avoid load()ing HTML content that contains <script>; the results are, depending on circumstance, either nothing, or nothing sensible.
Also js: in all your code above does nothing and should be omitted.
If the load is the problem, it's likely that you've loaded (and overwritten) the currently loaded libraries, which might include jQuery with your dialog plugin. Make sure you load a clean page, (Whenever I AJAX, I generally only generate a single <div> or a <ul>, whatever I need, and not the entire webpage.
If that fails, make sure the proper javascript files are included, that include jQuery and seemingly also jQuery UI.
Check in your browser's network/resources tracking what's up with those script files, and see if there are any other error messages (maybe a 404 not found?) on the javascript files.
As already explained above, you probably override the libraries.
One way of dealing with it is to ensure that the correct files are loaded.
Another way is to insert an iframe between the dialog and the content in the dialog. Iframes are treated by the browser as a separate page with its own scripts. So the scripts of the content "on top of" the iframe, will be separate from the scripts of the dialog "under" the iframe.
Since you are using Yii, check this wiki.

Categories

Resources