Jquery: Change HTML content of jqXHR from Get Request - javascript

I have a separate HTML file that I am loading in via $.get() and then turning into a Bootstrap modal dialog:
$.get("src/html/foobar.html", function (data) {
var md = $(data).modal({
backdrop:'static',
keyboard: false
});
});
However, before I turn this into a modal dialog and show it, I want to load in some content from the server. We know from jQuery's documentation that $.get() returns a jqXHR object. Is there a way to somehow change the content of the HTML returned in the data before I show it as a modal?
EDIT: I should be a little more specific and ask what operations can I perform on the object to edit its contents.

You could, of course, just modify data inline within your callback function before passing it to .modal
However a neater mechanism is to just chain a .then call from the Promise that is the jqXHR object:
$.get(url).then(function(data) {
// modify the data here
...
return modified_data;
}).then(function(data) {
// show data modally
});
NB: this assumes jQuery 1.8 or later, with the improved (i.e. corrected) semantics for .then
To avoid writing lots of inline functions, make the modifier function and the modal function separate named functions, then you can write:
$.get(url).then(modify).then(display);
Promises are the "new" way (since jQuery 1.5) to allow for separation of responsibility - as you can see from the example above the Promise chain allows you to completely detangle the three separate acts of retrieving, modifying and subsequently displaying the remote data.

Related

Javascript one function name in multiple files

What I need is pretty simple, although I don't know if possible..
I'm attaching all my event handlers to the object themselves instead of to $(document).
But, I need to attach them on the .ready() method, to make sure the object is created before the handler is attached. Since there are a lot of handlers to attach, to keep my code cleaner I want to create a function called attachHandlers() that will be called on document.ready().
But.. this function should execute codes that are in multiple files.
My question is.. is there a way of declaring the same function multiple times, and then calling it just once to execute them all?
But.. this function should execute codes that are in multiple files.
My question is.. is there a way of declaring the same function
multiple times, and then calling it just once to execute them all?
If interpret Question correctly, you want to request javascript from multiple files at .ready() . You can create an array containing url of file to request, use $.when(), $.map(), $.getScript() to call the javascript within the files
jQuery.getScript( url [, success ] ) Returns: jqXHR
Description:
Load a JavaScript file from the server using a GET HTTP request, then
execute it.
The script is executed in the global context, so it can refer to other
variables and use jQuery functions. Included scripts can have some
impact on the current page.
$(document).ready(function() {
var files = ["1.js", "2.js", "3.js"];
$.when.apply($, $.map(files, function(file) {
// request file
return $.getScript(file)
}))
.then(function() {
// complete
// do stuff
}, function err(jqxhr, textStatus, errorThrown) {
// handle error
});
});
Create a global JS file that has this function (and future functions that you want to be run on all pages). Call this script at the top of each file in the head element. Calling it in the head should do what you need (at least that is what i use in my projects and works for me).
Can u package your multiple files in modules and every one of them has a method attachHandlers? Then try use requirejs to load all of them. In document.ready, call the attachHandlers method from all these modules? It will be neater

How to utilize generic AJAX call with multiple success functions

I am making an ajax call that returns XML. This XML needs to be handled differently based upon the section of the page within the site the user is on. Thus, I would like to implement 1 ajax function that makes the calls, and has a variable success function... I'm sure it is simple but I've searched for a while and cannot figure it out..
function makeAjaxCall(variableSuccessFunction) {
$.ajax.... (ajax stuff goes here)...
success: variableSuccessFunction(xml)
}
function ViewOne(xml) {
//take the XML and update the dom as appropriate
}
function ViewTwo(xml) {
//take the XML and update the dom as appropriate
}
$(document).ready(function() {
//be able to call either one of these functions
makeAjaxCall(ViewOne);
makeAjaxCall(ViewTwo);
}
You've basically got it! Just one tweak:
function makeAjaxCall(variableSuccessFunction) {
$.ajax.... (ajax stuff goes here)...
success: variableSuccessFunction // no (xml)
}
You're passing around function references. success is passed a reference to variableSuccessFunction (whatever that may be) and will call it just like it would if you had supplied an anonymous function to it. No need to invoke it inside of makeAjaxCall.

javascript - how to call a function newly added from ajax

I have a coding difficulty which have been asked in this forum before:
Calling a JavaScript function returned from an Ajax response
But I didn't find the answers quite satisfying. To be more precise of the problem I'm dealing, here is the detail:
I dynamically load a document (HTML and javascript) using jquery
var url = 'document.php';
$('#container').load(url);
Example of what the document.php looks like:
<form>
<input name="firstname"></input>
</form>
<script>
function dosomething()
{
console.log($('input[name=firstname]').val());
}
</script>
*The dosomething() function is the one I'd like to call later
And then I want to call the functions from that document.php. Due to my requirement, I don't want to call the function after the documents' loaded, but rather to call it later when I need it. Because it was dynamically loaded, the DOM doesn't recognize the functions. How to properly call this function?
Thank you
the DOM doesn't recognize the functions
This sounds like your other functions are wrapped in $(document).ready() in the remote page. If that is the case they are out of scope for you to call them from code in the main page and you need to move them out of the ready handler to make them globally accessible.
EDIT: Other possibilities
Script tags in head- move to body after html, or use $.getScript in ajax callback to retrieve
I think that you're trying to implement the technique called on-demand javascript (or lazy-loading). In other words, your page should initially load just a small script - but use a bunch of objects and functions, which are available in some other files, but will be loaded when they're required.
If that's the case, I have to warn you: you'll probably need to update your existing code. Instead of just calling some function right as it is, in all gun-blazing glory, you should check for its existence first - and if it's not available, wait for its loading:
if (typeof lazyObjects.someLazyFunction !== 'function') {
lazyLoad('lazyFunction.js');
}
lazyObjects.someLazyFunction();
The key point here is that lazyLoad should be synchronous. In other words, you'll have to wait until the script containing your function is actually loaded. Otherwise someLazyFunction just won't be defined when it's called, even with this sort of checks.
lazyFunction.js, in turn, will contain some code that will alter lazyObjects, adding to them the required method as a property:
// in lazyFunction.js
lazyObjects.someLazyFunction = function() { ... }
While it's technically possible to use global (=window) object for these cases, I usually don't do this - and won't recommend doing it either.
See, it's not that simple. ) I'd recommend reading this article to find out more about this technique - and actually using some established components to implement it in your code (some of them are mentioned in the linked article).

CoffeeScript Class Properties Within Nested Anonymous Functions

I'm familiar with the hidden pattern methodology however I'm still wrapping my head around object prototypes.
I'm trying to create a basic class for controlling a section on my site. The problem I'm running into is losing defined class variables within a different scope. For example, the code below works fine and creates the properties within the object perfectly. However when I jump into a jQuery callback I lose all knowledge of the class variables storing some of the jQuery objects for multiple uses.
Is there a way to grab them from within the callback function?
class Session
initBinds: ->
#loginForm.bind 'ajax:success', (data, status, xhr) ->
console.log("processed")
return
#loginForm.bind 'ajax:before', (xhr, settings) ->
console.log #loader // need access to Session.loader
return
return
init: ->
#loginForm = $("form#login-form")
#loader = $("img#login-loader")
this.initBinds()
return
jQuery's AJAX callbacks are executed in the context of:
... an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax)
so # (AKA this) isn't your Session instance when the callbacks are called. The CoffeeScript-ish way around this is to bind the callback to your Session instance using a fat-arrow:
The fat arrow => can be used to both define a function, and to bind it to the current value of this, right on the spot. This is helpful when using callback-based libraries like Prototype or jQuery, ...
I think you want to say this:
#loginForm.bind 'ajax:before', (xhr, settings) =>
console.log #loader // --------------------^^
return
And you don't need the return at all unless the last statement in your callback might accidentally evaluate to false when you don't want to cancel the AJAX call; if you want to be paranoid (a reasonable position since they really are out to get us) then a simple true at the end would suffice to get a non-false value returned from the callback:
#loginForm.bind 'ajax:before', (xhr, settings) =>
console.log #loader // --------------------^^
true

javascript asynchronous calls that populate some property

I have an javascript object that includes some image strings as its property. Upon instantiating this object, an AJAX call is made immediately to populate this property.
My view functions, at the same time, tries to read newly instantiated instances and tries to display this object. As expected, the AJAX call may not have finished by then yet, so it will not be able to read the right image url.
One solution to this problem is to pass in some call back function with the AJAX call that modifies the source of image upon completion, but this is introducing a lot of dependency on the model and the view and I'm trying to keep my MVC as separate as possible, so my view function right now just takes that object as an parameter, reads all the properties, and shows it.
Making the AJAX synchronous isn't an option because I have quite a lot of these objects being initialized and only one will be displayed at a time, so making all AJAX calls synchronous will be too expensive of a tradeoff.
What's a good way to solve this problem? The view function is something in the form of:
function displayObj(object) {
var prop1 = object.getProp1();
// this could be the image file that depends on AJAX result
var prop2 = object.getProp2();
}
Ideally, I would like to delegate this task to the getter, so that the view function doesn't have to worry about the interval state of the the object. The getter could handle this by checking whether the image is there yet, if not, wait, then only return if the actual image string is there. However, a blocking wait would for sure block the AJAX process so it's a deadlock, and non-blocking wait will let the getter return and the view function will get null data.
Please shed some light on this situation or suggest alternative ways that I can organize my code. Thank you very much!
I'd be a little bit less strict with the MVC roles and let the model object return the DOM <img> object.
// model object starts loading upon instantiation
var loader = new Loader();
// however the img tag is available immediately.
// the loader will update the src when ajax
// calls complete.
document.body.appendChild(loader.getImg());
Since, from your comments, you are using jQuery I recommend you call the done() method of the request returned from the ajax() method. For example,
var request = $.ajax("example.php");
request.done(notifyWhenSuccess);
request.fail(notifyWhenFailed);
This request returned by jQuery is a superset of the Promise pattern from CommonJS. Also, just because it is in jQuery don't cosider the ajax call part of the view but rather view it as part of the model. Use the done() method to update the model then notify the view with a data changed event.

Categories

Resources