Losing scope in jQuery AJAX Lightbox - javascript

My lightbox opens and the new content is displayed within it.
But the script doesn't seem to add the event listener to the links in the generated content. Thus nothing happens but a new pageload.
var lightbox = (function() {
var init = function() {
$('footer').append("<div id='lightbox'><div id='close'>x</div></div>");
$('#close').click(function() {
$('#lightbox').hide();
$('#lightbox').children(':not(#close)').remove();
});
ajax();
};
var ajax = function() {
$('.ajax a').add('#lightbox a').click(function(e) {
e.preventDefault();
$('#lightbox').children(':not(#close)').remove();
$.ajax({
url: $(this).attr('href'),
success: function(result) {
$('#lightbox').fadeIn(300).append(result);
}});
});
};
return {
init:init
}
})();

You don't actually invoke init which is where your close handler is bound. init is a local variable which is never returned from your IIFE, so obviously it's not being invoked from outside this function.
The answer is to invoke init. As it stands, your lightbox function doesn't do anything except for declare (and then immediately discard) two variables named init and ajax.

Related

How to call a function in javascript?

I want to call a function every time my update was successful. The update is working my only concern is the alert pop-up every successful update.
$.post(
{
url: 'update_question.php',
data:
{
id: id,
new_question: newText,
},
success: function()
{
that.replaceWith("<section>"+newText+"</section>");
if(text != newText)
{
popup();
}
}
});
var popup = function () {
$(document).ready (function(){
$("#myWish").click(function showAlert() {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
});
});
};
var popup = function () {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
};
On the first update, pop-up showed but it doesn't show on the 2nd update
I think it'll solve your issue
$.post(
{
url: 'update_question.php',
data:
{
id: id,
new_question: newText,
},
success: function()
{
that.replaceWith("<section>"+newText+"</section>");
if(text != newText){
popup();
}
}
});
function popup() {
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").alert('close');
});
};
The $(document).ready jquery function waits until the DOM is loaded into your browser before it executes the javascript code contained within it's function scope {}.
So remove $(document).ready from your code.
Also note that single page applications only need to list $(document).ready once and all the listener events you setup are defined within it's body.
So you should have it listed somewhere at least once and then you define all your initial event listeners within its body.

Why we use $(function() { }) like syntax in JS?

When I use this code it bind my $.post() to a form and prevent a page reload for submitting it:
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
But it doesn't trigger the debuggers I used in it, so it doesn't bind the event to my function correctly, but when I use this code fragment, it works perfectly:
$(function() {
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
});
I really don't understand why?
When you're working with jQuery (which you clearly are), wrapping a function in $( ) makes it a function that's called by the library when the "DOM ready" event is received from the browser. It thereby defers execution of your code until the DOM is fully built. That makes your code work because it ensures that the element with id "analyze_audio" is present.
There's nothing syntactically special about $( ) — it's just a simple function call, to a function named $ (which is the main entry point to the jQuery library).
You may see code that does something similar:
$(document).ready(function() { ... });
That does precisely the same thing (and is also a jQuery idiom). There's no reason to use that form unless you enjoy typing in extra characters.
$(function() {}); is just a shortcut for document.ready. It would work the same like this:
<script type="text/javascript">
$(document).ready(function() {
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
});
</script>
When you bind event to the form #analyze_audio it not present in DOM yet. If you put your script after the html with form, then it will work. Or you can use $(document).ready() to add your binding or just $(function(){}) both this functions will be executed when whole page will be loaded.

Javascript works only once when function calls via button

I have a page with Javascript that calls a Django URL, but this call just work once.
The html code is here:
<script>
function myFunction(pk) {
if ($.data(this, 'submitted')){
return false;
}
$.data(this, 'submitted', true);
$.get("{%url 'myViewURL' %}",{req:pk}, function (data) {
$.data(this, 'submitted', false);//libero
});
}</script>
Button code
<button onclick="myFunction({{id}});">Click Me</button>
The view code:
def myFuncView(request):
p_id=request.GET['req']
do_stuff(p_id)
return redirect('anotherURL',p_id,permanent=True)
When is the first time I press the button, it fires, but after that it does not work anymore, even if I refresh the page or go to another page and come back!
this inside the get function refers to the ajax request, not the button which initiated it.
You need to store a reference to this, so you can then use it in a different context:
var self = this;
$.get("{%url 'myViewURL' %}", {
req: pk
}, function (data) {
$.data(self, 'submitted', false); //libero
});

Calling A Method In Mootools, The Correct Way?

I have created a class in mootools that when the initialize() method is first called it creates a div elements which is then appended to the document.body. I then attach a context menu handler which will call functions when an option from the context menu is selected in the browser.
The trouble I am having is that the context menu handler will not actually call any functions and I can't quite figure out why and was wondering if anyone here could spot the problem?
Here is the class I have created and the attached context-menu handler, some of the other code has been removed for brevity:
var uml_Canvas = new Class({
initialize: function()
{
this.mainCanvasDiv = document.createElement("div");
this.mainCanvasDiv.id = "mainCanvas";
this.mainAppDiv.appendChild(this.mainCanvasDiv);
this.paper = Raphael(this.mainCanvasDiv.id, 500, 400);
this.paper.draggable.enable();
$("#"+this.mainCanvasDiv.id).contextMenu('canvasPanel_Menu',
{
bindings:
{
'clear': function(t)
{
this.clearPaper();
}
}
});
},
clearPaper : function()
{
this.paper.clear();
}
});
So a quick overview, an object is created which creates a div and then appends it to the body. The div then has a context-menu assigned. When the 'clear' option is called the method clearPaper() should be called be for some reason it is not. If, however, I replace the this.clearPaper(); line with a simple alert() call, it does indeed run.
Can anyone see a reason why it is not possible to call a method?
BTW the error I get is this.clearPaper is not a function if that helps.
Try binding "this" to your clear function:
'clear': function(t)
{
this.clearPaper();
}.bind(this)
This takes the "this" scope and allows the anonymous function to use it as if it were a member of that class.
Note that you have to do this whenever you try to use "this." inside of any anonymous function. For instance, if you have inside a class:
method: function() {
button.addEvent('click', function(e) {
new Request({
onComplete: function(res) {
this.process_result(res);
}
}).send();
});
},
process_results: function(res) {...}
You have to bind all the way down:
method: function() {
button.addEvent('click', function(e) {
new Request({
onComplete: function(res) {
this.process_result(res);
}.bind(this)
}).send();
}.bind(this));
},
process_results: function(res) {...}
Notice the new bind()s on the event function and the onComplete function. It may seem like an annoying extra step, but without doing this, you'd have scope free-for-all. Mootools makes it extremely easy to take your class scope and attach it to an anonymous function.

jquery click event

I have some jquery that looks like this,
$('.career_select .selectitems').click(function(){
var selectedCareer = $(this).attr('title');
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
}
});
});
My problem is that if the user keeps clicking then the .hfeed keeps getting data appended to it. How can I limit it so that it can only be clicked once?
Use the one function:
Attach a handler to an event for the elements. The handler is executed at most once per element
If you wanted the element to only be clicked once and then be re-enabled once the request finishes, you could:
A) Keep a state variable that updates if a request is currently in progress and exits at the top of the event if it is.
B) Use one, put your code inside a function, and rebind upon completion of request.
The second option would look like this:
function myClickEvent() {
var selectedCareer = $(this).attr('title');
var that = this;
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
},
complete: function() {
$(that).one('click', myClickEvent);
}
});
}
$('.career_select .selectitems').one('click', myClickEvent);
You can either use a global variable like
var added = false;
$('.career_select .selectitems').click(function(){
if(!added) {
// previous code here
added = true;
}
});
or use .one("click", function () { ... }) instead of the previous click function to execute the handler at most once per element. See http://api.jquery.com/one/ for more details.

Categories

Resources