depending upon UI inputs, i need to dynamically change (create or hide) other UI elements.
Also i don't want to refresh my page.Is it good to generate Html page elements using AJAX queries? Also what is the best way to do it?
I am using Knockoutjs's html binding to do the work. Here is the idea:
Create a global viewModel:
var _viewModel = {
body: ko.observable()
}
In the html page:
<div id="dynamic-part" data-bind="html: body" ></div>
In the javascript
ko.applyBindings(_viewModel, $('#dynamic-part')[0]);
whenever you want to load the dynamic-part, you can have kind of javascript code like follows:
$.get('/some/new/page/part', function(data) {_viewModel.html(data);});
When you apply the above technology along with sammy and LAB, you will get a very powerful one-page web application, where all the pages of the application can be load with ajax call.
Normally the way it's done is that the initial page has tags with identifiers, but no content in the divs. As your AJAX results come back, you set the innerHTML of those divs to the retrieved content, addressing them by identifier. Here's a page which explains it well.
At first you have to copy with the technical stuff.
How to make an AJAX request in the first place?
I would choose the jQuery library. This has a ajax function.
Then you decide:
Do you give back just some data and build the HTML content in JavaScript? (Here again jQuery is a good way to do it)
Or do you build the HTML on the server-side and just put it in my document using the ajax callback method success?
That's for starter
Related
I'm adding some html to a div using the following jQuery method:
$('#pageTabContent').append($('\
<div class="tab-pane" id="'+ticketId+'">\
And a whole lot more html here..
</div>'));
This works fine, but because I've got way too much html in my javascript I want to move that to a separate file. The problem is that I also need to insert the ticketId in the html. Is there a way using Javascript/jQuery to load the html from a separate file, but still insert the ticketId in it?
[EDIT] Please note that the ticketId is different for every time this piece of code is used. I will be used multiple times within one page load, so I cannot load the ticketId in the html using php. I has to be done client side.
All tips are welcome!
For that specific example, it's pretty straightforward:
$.get("/path/to/file.html", function(html) {
var newStuff = $(html);
newStuff.find("div.tab-pane:first").attr("id", ticketId);
newStuff.appendTo("#pageTabContent");
});
You can generalize that a bit, the basic concept is: 1. Load the HTML, 2. Use jQuery to create DOM elements from it, 3. Use jQuery to find the element in question and modify it, 4. Add to the element.
Another approach is to use some form of templating, either a templating plugin or just DIY:
$.get("/path/to/file.html", function(html) {
html = html.replace("{{ticketId}}", ticketId);
$("#pageTabContent").append(html);
});
Again, there are plugins and templating systems to do that for you, which would offer various features over doing your own.
I generally recommend avoiding dynamic html generation in javascript.
There are several good template based frameworks out there. One I like to use in KnockoutJS http://knockoutjs.com/
Another benefit of this approach is change tracking between your model and your html elements.
I am working on standalone JavaScript application which is being coded in HTML 5.
It has almost 50-60 html pages including repetitive markup such as header, footer and nav.
But if I have to make change in header then I have to make changes in 56-60 pages.
Is there any solution to use reusable html markup so if I did changes in one page it will reflect to other pages?
I can't even use php.
Prepare one javascript function. Write your html elements through javascript or jquery function. run it in page load event. and call the function in html by div.
Put this javascript function in separate .js file. And call this js file in wherever you want. And just place the div wherever you want in the html page.
See this jsfiddle DEMO
I Hope this demo will useful to you in this situation.
If you are using HTML (.html) pages and do not have Server-Side-Includes option then you can use a JavaScript template (which is not too difficult).
Second option : use of iframe.
Write the whole javascript code in common_layout.js
Add every statement using id of that div and add this file with main layout.
$( document ).ready(function() {
$('#header').html('<b>Header</b><ul><li>First Link</li><li>Second Link</li></ul> ');
});
UPDATE: One of my favorite post from TutsPlus : Best practices when working with JS Templates
If you are just started with this application. You can think of using client side java script frameworks like - AngularJS. It would be lot easier to maintain the code and solve such trivial issues.
You can use object tag like this:
<object name="header" type="text/html" data="header.html"></object>
Assume I have a home.jsp made of
/common/_header.jsp
/_homebody.jsp
/common/_footer.jsp
And search.jsp made of
/common/_header.jsp
/_searchbody.jsp
/common/_footer.jsp
The header has a search box. On submitting a string, I want to move to search page, but would be prefer an ajax call. So what is the best way to display the search page. I have the following solution.
Remove the _homebody content using $(selector).empty() or $(selector).remove()
Add the _searchbody content using $(selector).append(content)
The removal part is fine, but the appending part is dirty and error prone as I need to store the HTML String in my javascript. Any work arounds? Two probable solutions could be
A better way of storing the HTML String in javascript
OR
A method that can remove a child element of JSP and add a new one.
Or any better solutions.
Thanks in advance
If you setup your server to return the search results as a HTML, you can just use http://api.jquery.com/load/ to insert the generated results.
A way to go about this would be hiding the _homebody content and showing a div which you can just routinely update its content. Then after every search, replace the content with that of the loaded content
You may use the html() function to replace the contents
in the ajax success
$(selector).html(content);
As I know that in JQuery Mobile, every page changing is equivalent to create new "page" div, Can we just change a portion in the "content" of the page, something like subpage?
jQuery Mobile doesn't require you to manage pages by creating additional div element in the same HTML file - you can do it perfectly fine in a different HTML file and make a transition to it (perhaps with data-prefetch attribute set) using <a>.
Nothing prevents you from writing a jQuery plug-in, jQuery UI plug-in or (scary though, I know) pure JavaScript that will alter the contents of the DOM element dynamically and manage pages loading according to data received from server - with necessary calls to things of the listview('refresh') ilk - to ensure proper styling.
With that said you have to ask yourself two things:
Why do you need to do it? Can't you manage by pre-creating the page using jQuery Mobile paradigm and just retrieving and inserting the data into the new page?
What will the performance implication (if any) will be, if I have to perform DOM manipulations on every 'page transition'?
As a side note - jQuery Mobile provides you with methods that allow for page manipulation:
$.mobile.changePage and $.mobile.loadPage that you can use (look at pageContainer option).
See API docs here
I am trying to use right now a jQueryMobile plugin for subpages: https://github.com/ToddThomson/jQuery-Mobile-Subpage-Widget
I didn't make it work yet but i think it should work :).
I love jQuery but am running into a problem with larger site and multiple pages. My problem is that each page has unique requirements and I need to know the best way to tell jQuery which pages to activate certain things. For example, some forms need the Validator plug-in and some don't, some tables use DataTables plug-in and some don't, etc.
Now I guess I could build complex logic (switch statements) into my application JavaScript file that fire different actions depending on what page they are on, but that just seems smelly. What is the Best Practice here?
UPDATE: There have been lots of good ideas on this question but not quite what I'm looking for. Let me rephrase the question in a more general way.
Currently I am using Rails and its Prototype helpers to build my AJAX components, but I want to move to UJS. How do I tell jQuery which links/buttons to make AJAX and which to avoid? And, given that I can differentiate the that are supposed to have AJAX, how do I give each link its own parameters (method, update, etc.) like I could with the helpers?
I mean besides building a huge page of specific jQuery selectors targeting each individual link/button. :)
jQuery plugins usually are activated upon DOM elements, for example:
$("#element").myPlugin();
If the element doesn't exist on the page, plugins usually behave safely by not activating the plugin.
If your plugin doesn't follow this structure I would suggest doing something like this:
if($("#element").length) $("#element").myPlugin();
A good practice is to have code that is required by all pages in one file and to have specific javascript files for pages that require specific functionality. It sounds as though this is what you are doing anyway, so we have a good basis to build upon.
There are numerous ways in which you could build in what pages need what files, but remember that in normal circumstances, javascript files are cached by the browser such that those files need only downloading once.
In light of this comment
Yes, but what if you have multiple
pages with the same DOM elements? For
example, my validator() plugin is set
up like $('form').validate(), but
sometimes I don't want it to act on
all the forms on the page, only some
of them. What do I do in this case?
I suggest coming up with a convention by which to label elements common across pages that require certain jQuery plugins "attached" to them. For example, if you have a <form> element on a number of different pages that requires a validator() plugin, but there is more than one <form> element on any one particular page (and not all <form> elements should have the validator() plugin), then I suggest using a CSS class to distinguish the <form> elements that do need the plugin.
<!-- HTML -->
<!-- need to apply plugin to this -->
<form class="validator"> ... </form>
<!-- but not to this -->
<form> ... </form>
<script type="text/javascript">
// jQuery Code (in a separate file)
$(function() {
$('form.validator').validator();
});
</script>
That way, the plugin will be applied only to those <form> elements matching the selector.
EDIT:
I'm not sure how the helpers in rails work, but you can pass data to an event handler in jQuery using the data parameter of the bind() method for any data that is not directly part of an <a> element itself (such as an attribute like href). If some of the links require AJAX, then it may make sense to label those with a CSS class and store the URL in the href for the element. Then in your jQuery code that can be used on any pages that have links that make requests through AJAX, you could do something like
<a class="ajax-link" href="/get/someData.php">Data retrieved through AJAX</a>
Standard link with no AJAX
<script type="text/javascript">
$('a.ajax-link').bind('click',ajaxRequest);
function ajaxRequest(e) {
e.preventDefault();
$.get(e.target.href, function(data) {
$('#loadDiv').html(data);
});
}
</script>
the link will work as per a normal link when a user has JavaScript disabled, but will make an AJAX request for data when JavaScript is enabled. I've used a named function here, ajaxRequest as it can make it easier to debug the script (and perhaps also reuse), but you could use an anonymous function if you prefer.
Found nice custom solution
http://topsecretproject.finitestatemachine.com/2010/04/how-to-organizing-javascript-in-ruby-on-rails/
One thing I always do is add an id to the body tag of each page, where the id is the name of the page (<body id="contact">). That makes both javascript and css selection very easy.
For example:
<!-- HTML -->
<!-- need to apply plugin to these forms -->
<form> ... </form> on the about.php page
<!-- but not to this -->
<form> ... </form> on the index.php page
<script type="text/javascript">
// jQuery Code (in a separate file)
$(function() {
$('body#about form').validator();
});
</script>
You could pass key value pairs to your main JavaScript module informing which plugins should be imported. This technique is used by scriptaculous.
<script type="text/javascript" src="scriptaculous.js?load=effects,dragdrop">
Another approach is to define in server side which media files are needed for each form/page, so the html can be rendered automatically with links to the scripts that are going to be used. Django has a good implementation of this technique:
class CalendarWidget(forms.TextInput):
class Media:
css = {
'all': ('pretty.css',)
}
js = ('animations.js', 'actions.js')