Using partials independently - javascript

I'd trying to work out if its possible load what I believe is referred to as a partial in linkedin-dustjs without loading its parent.
For example if I have this partial (login.dust):
{>layout/}
{<content}
<!-- Login Screen -->
{/content}
Which loads this page (layout.dust):
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
{+content/}
</body>
</html>
Is it possible to ouput login.dust without rendering layout.dust? The reason being that I might want to render the whole page when a user requests the login page. However if a user is on another page is tries to perform an action that requires login I might want to ajax load the login partial and add it to the existing page without requiring the layout as that would already be present.
If its not possible is there a way to 'pass' on template to another so I can render out the login template and pass it to the layout template.
I apologies if I'm not using the correct terms. Feel free to correct me as I'm not that well read on how linkedin-dustjs works.

You can achieve this by adding one more template. Your layout.dust template would remain unchanged. Your login.dust template would look like:
{>layout/}
{<content}
{>loginForm/}
{/content}
And the new loginForm.dust would contain your login form. Then you can include {>loginForm/} wherever you need to add the login form.

Related

Possible to disable CMS's conflicting native JavaScript onSubmit scripting?

I am building a very simple 5 question multiple choice quiz "game" that just asks 5 simple questions displayed using HTML radio buttons, and a JavaScript function that validates if the user's selection is correct, and iterates a "score" which, when the submit button is clicked, displays "You got X out of X correct." Basically a .js 101 project.
I'm using a Content Management System called Blackbaud Internet Solutions (BBIS). It is proprietary to Blackbaud, and allows the user to build a fully functioning website that integrated with Blackbaud's CRM database. It allows you to build layout using HTML, however in the built-in HTML editor you do not declare any !DOCTYPE or <body> or <head> tags, you just start with your first or whatever, and the system will build out each page using it's native .aspx functionality.
BBIS does have a sophisticated stylesheet section that allows you to create and stack .css, however JavaScript is not handled in the same way.
A web developer that wants to include JavaScript on a page must insert that script by creating what BBIS calls an "Unformatted Text Part." (a "part" is like a widget, or block etc.) The Unformatted Text Part allows you to insert whatever you have between <script> ... and ...</script> in the:
<head>
<body>
at the end of the <body>
Locally on my workstation the .html, .css, and .js files all work together perfectly. And in BBIS, the HTML renders great, the CSS looks good, however, the JavaScript aspect just doesn't work at all. When you click the submit button, the screen flashes and the form's 5 radio buttons just reset to unselected.
Using Chrome's developer tools I can see in the DOM that the CMS (BBIS) brings a whole lot of unnecessary JavaScript to the party. I'm sure that on a page with more elements, these scripts have a perfectly logical function. But this page is literally a white background with nothing but a quiz in the middle of the page. My onSubmit button function has 3-4 other "onSubmit" scripts running on the same page, and I cannot help but think that this is the problem.
In the DOM, I can see that my JavaScript function has been inserted into the <head> tag, because that is where I configured it to load inside of the BBIS "unformatted text part". All the native BBIS "onSubmit scripts" appear in the <body>. Is there a way that I can insert some JavaScript into the <head> that will "take out" those <body> BBIS "onSubmit" scripts?
when you get a blank page maybe you leave the CMS page on submit?
How does your html form look like?
Another thing is, are you using jquery? Most CMS bring their own version of jquery. Try to use jquery in no conflict mode https://api.jquery.com/jquery.noconflict/
Edit the unformatted text part, and select the 'advanced options' button. You can choose to drop your part in the <head> from there.

javascript will not load unless page is refreshed

I am working on a website that was started off by someone else. That person built the whole thing in one 1000-line html file, and links to different 'pages' just reference other sections in the main html file. So my task is to break the page apart into seperate html pages. Unfortunately, now the seperate pages do not load the javascript unless the page is refreshed.
Is there a standard way to fix this problem without forcing the user to manually refresh the page?
If you break that one big page into several smaller pages, make sure you include the JavaScript (and CSS) in the new pages. The most efficient way to do this is to have the JavaScript in an external JavaScript file, and bring that file into the new pages by putting the script tag inside the new pages' head tags like so:
<head>
<script src="path/to/javascript/app_name.js"></script>
</head>
When the user clicks on a hyperlink to see one of the new pages, when the browser receives the response from the server, it will parse the response and execute the JavaScript.
If I understand your problem correctly, I would wrap whatever "detailsScreen.js" does into a function and call it after you changed the page content.

Why I have to put all the script to index.html in jquery mobile

I have used $.mobile.changepage to do the redirect in my phonegap+jquerymobile projects. However what makes me confused is that I need to put the script of all the pages to the same file index.html. If not, the redirect page can not execute the function in its header.
for example, my index.html seem to be
$(document).bind("deviceready",function(){$.mobile.changepage("test.html");})
then, my device will redirect to test.html which seem to be
$("#btnTest").click(function(){alert("123");})
<button id="btnTest">Test</button>
However, the script will never execute in test.html. Then I put the script to index.html, what I expect to be is done. Whatever, if I put all the script to the same page, the project will become harder and harder to be preserved. Appreciated for your help.
Intro
This article can also be found HERE as a part of my blog.
How jQuery Mobile handles page changes
To understand this situation you need to understand how jQuery Mobile works. It uses ajax to load other pages.
First page is loaded normally. Its HEAD and BODY is loaded into the DOM, and they are there to await other content. When second page is loaded, only its BODY content is loaded into the DOM. To be more precise, even BODY is not fully loaded. Only first div with an attribute data-role="page" will be loaded, everything else is going to be discarded. Even if you have more pages inside a BODY only first one is going to be loaded. This rule only applies to subsequent pages, if you have more pages in an initial HTML all of them will be loaded.
That's why your button is show successfully but click event is not working. Same click event whose parent HEAD was disregarded during the page transition.
Here's an official documentation: http://jquerymobile.com/demos/1.2.0/docs/pages/page-links.html
Unfortunately you are not going to find this described in their documentation. Ether they think this is a common knowledge or they forgot to describe this like my other topics. (jQuery Mobile documentation is big but lacking many things).
Solution 1
In your second page, and every other page, move your SCRIPT tag into the BODY content, like this:
<body>
<div data-role="page">
// And rest of your HTML content
<script>
// Your javascript will go here
</script>
</div>
</body>
This is a quick solution but still an ugly one.
Working example can be found in my other answer here: Pageshow not triggered after changepage
Another working example: Page loaded differently with jQuery-mobile transition
Solution 2
Move all of your javascript into the original first HTML. Collect everything and put it inside a single js file, into a HEAD. Initialize it after jQuery Mobile has been loaded.
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script src="index.js"></script> // Put your code into a new file
</head>
In the end I will describe why this is a part of a good solution.
Solution 3
Use rel="external" in your buttons and every elements you are using to change page. Because of it ajax is not going to be used for page loading and your jQuery Mobile app will behave like a normal web application. Unfortunately this is not a good solution in your case. Phonegap should never work as a normal web app.
Next
Official documentation, look for a chapter: Linking without Ajax
Realistic solution
Realistic solution would use Solution 2. But unlike solution 2, I would use that same index.js file and initialize it inside a HEAD of every possible other page.
Now you can ask me WHY?
Phonegap like jQuery Mobile is buggy, and sooner or later there's going to be an error and your app will fail (including loaded DOM) if your every js content is inside a single HTML file. DOM could be erased and Phonegap will refresh your current page. If that page don't have javascript that it will not work until it is restarted.
Final words
This problem can be easily fixed with a good page architecture. If anyone is interested I have wrote an ARTICLE about good jQuery Mobile page architecture. In a nut shell I am discussing that knowledge of how jQuery Mobile works is the most important thing you need to know before you can successfully create you first app.
Unlike normal ordinary HTML pages, jQuery Mobile uses ajax technology when navigating between pages. So make sure to import all your JS files and libraries in all your html pages.
If you notice closely you will see that JS files from previous page is taken into consideration when loading the second page. But if you force rrefresh the current page then the js files of the current page will be effective.
So as I said earlier make sure to import the js files in all the html files.
Also no need to call deviceready, use following syntax to call your page specific js functions
$(document).on('pageshow', '#YourPageID', function(){
// Your code goes here
});
Jquery Mobile uses ajax to load a "page". A "page" here is a div with data-role=page. If you load a physical page index.html, you can navigate using changePage to any "page" div inside that page.
However, if you want to load a "page" from other physical page, jQM will only load the first "page" div from that page. What actually happen is you do not change page, jQM just load that particular "page" div using ajax and inject it to your current page.
You have two possible architecture where you put all your "pages" in a html page and navigate from there. Or you can have multiple page architecture. You can always mix this.
To physically change page, you need to add rel=external to your link.

Loading a page via Ajax into Div Best Practice?

I'm using the method below to load a remote page into a div I have on the page.
$('#result').load('www.myurl.com/results.html');
I'm curious, is it a bad practice to load an entirely formatted HTML page within another page? My concern is more towards loading css or additional javascript includes that might overwrite other elements on the primary page.
I haven't experienced any issues during my initial tests, I'm just not sure if this is the best practice.
To Clarify: If I have a primary page like so
<html>
<head>
<script src="jquery.js"></script>
<link href="mycss.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="remoteContainer"></div>
<script>
$('#remoteContainer').load('www.myurl.com/results.html');
</script>
</body>
And results.html code that looks like this:
<html>
<head>
<script src="jquery.js"></script>
<link href="myResults.css" rel="stylesheet" type="text/css">
</head>
<body>
<header>
<h1>My Results Page</h1>
</header>
...
</body>
Will the CSS and JS overwrite each other,or will the pages function as 2-separate entities?
This will work fine and the browser will handle it properly. From the jQuery docs:
... browsers often filter elements from the document
such as <html>, <title>, or <head> elements. As a result, the elements
retrieved by .load() may not be exactly the same as if the document
were retrieved directly by the browser.
However, it's probably better practice to specify the element in the returned HTML that you want to insert:
$('#remoteContainer').load('www.myurl.com/results.html #containerDiv');
Ok, so maybe I should have just taken a look at DevTools before I asked the question.
After reviewing the Element Inspector, I now see that (at least in Chrome) that the browser strips out the HTML, HEAD, and Body tags. It also removes the additional jquery include. However it does leave the
<script>my js functions here</script>
Although I understand that I can't trust that all browsers will be as efficient, at least now I have seen the light.
I agree that it 'should' work 'fine'. But consider the extra overhead you are creating that could be eliminated by returning only the content that you need from the server. You might be hitting the database to retrieve data that is rendered in the parts of the page that you are discarding. For example, you might have information about the user displayed at the top of every page. Or you might be looking up other information that goes into your page meta tags in the head. You probably have some type of server side templating going on to create these excess parts of the page. Then you are putting this excess content in a response, sending it over a wire, then asking the browser to parse it, create html elements out of it, then remove the parts that are not wanted for you.
This may not be a big deal. It depends on how much traffic you get, how much extra work the server is doing to render the full page, how much of a load the server is under, and how much time/money/man power you have versus how much it would take to be able to send a trimmed down response instead. If it's a small project, with light traffic, it might not be worth changing. But it's also probably an easy change to make. And since the question is about a best practice, I would say no, loading a full page to render just a portion of the page not a best practice. The best practice is to return just what you need from the server, and to use all of it to update the page. This could be pre-rendered HTML or it could be JSON, but that is another discussion altogether.
A trivial solution in PHP could be as simple as the following, using ?format=ajax in your query string:
<?php
$ajax = $_GET['format'] == 'ajax';
if (!$ajax) {
render_head_and_stuff();
}
render_results();
if (!$ajax) {
render_footer_and_stuff();
}

Access content of jQuery Mobile (sub)page using JavaScript

I've been trying many of the "standard" JavaScript DOM functions to access elements in an HTML document (getElementById, getElementsByName etc.), but I can't get it working with jQuery Mobile - when a subpage is loaded, the values returned from getElementById("elementOfInterest").innerHTML still contains the value from the master page.
I'm trying to implement this in an iPhone app, to extract and display the respective subpages' titles in a navigation bar (the page is displayed in an UIWebView), but I think (and hope) that the problem and solution is more or less "platform independent".
Anyone with thoughts of how to achieve this using JavaScript (or possibly some jQuery function)? I couldn't find anything in the jQuery Mobile Docs, though.
As per default behavior of jQuery Mobile configuration, it will automatically handle link clicks and form submissions through Ajax, when possible. So when you open a new page (sub page), new page will be appended to master page's DOM. During this time you loose JavaScript written on new page.
As per my thinking you can disable Ajax form and link.
To do so, write a link as follow:
Create
You can also do it for all the links by overriding default configuration:
<script src="/js/jquerymobile/jquery-1.5.min.js"></script>
<script type="text/javascript">
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled= false;
});
</script>
<link rel="stylesheet" href="/css/jquerymobile/jquery.mobile-1.0a3.min.css" />
<script src="/js/jquerymobile/jquery.mobile-1.0a3.min.js"></script>
In both the way, pain is, you will loose framework's generated back button!
Read more at:
http://jquerymobile.com/demos/1.0a3/#page.html&subpageidentifier
Edit:
To add back button in new page, you may put it manually like:
<div data-role="header">
Back
<h1>
List items
</h1>
</div>

Categories