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
});
Related
I've implemented a simple AJAX call that is bound to a button. On click, the call takes input from an and forwards the value to a FLASK server using getJSON. Using the supplied value (a URL), a request is sent to a website and the html of a website is sent back.
The issue is the AJAX call seems to run multiple times, incrementally depending on how many times it has been clicked.
example;
(click)
1
(click)
2
1
(click)
3
2
1
Because I am sending requests from a FLASK server to another website, it effectively looks like I'm trying to DDOS the server. Any idea how to fix this?
My AJAX code;
var requestNumber = 1; //done for testing purposes
//RUNS PROXY SCRIPT
$("#btnProxy").bind("click", function() . //#btnProxy is the button
{
$.getJSON("/background_process", //background_process is my FLASK route
{txtAddress: $('input[name="Address"]').val(), //Address is the input box
},
console.log(++requestNumber), //increment on function call
function(data)
{$("#web_iframe").attr('srcdoc', data.result); //the FLASK route retrieves the html of a webpage and returns it in an iframe srcdoc.
});
return false;
});
My FLASK code (Though it probably isn't the cause)
#app.route('/background_process')
def background_process():
address = None
try:
address = request.args.get("txtAddress")
resp = requests.get(address)
return jsonify(result=resp.text)
except Exception, e:
return(str(e))
Image of my tested output (I've suppressed the FLASK script)
https://snag.gy/bikCZj.jpg
One of the easiest things to do would be to disable the button after the first click and only enable it after the AJAX call is complete:
var btnProxy = $("#btnProxy");
//RUNS PROXY SCRIPT
btnProxy.bind("click", function () //#btnProxy is the button
{
btnProxy.attr('disabled', 'disabled');//disable the button before the request
$.getJSON("/background_process", //background_process is my FLASK route
{
txtAddress: $('input[name="Address"]').val(), //Address is the input box
},
function (data) {
$("#web_iframe").attr('srcdoc', data.result); //the FLASK route retrieves the html of a webpage and returns it in an iframe srcdoc.
btnProxy.attr('disabled', null);//enable button on success
});
return false;
});
You can try with preventDefault() and see if it fits your needs.
$("#btnProxy").bind("click", function(e) {
e.preventDefault();
$.getJSON("/background_process",
{txtAddress: $('input[name="Address"]').val(),
},
console.log(++requestNumber),
function(data)
{$("#web_iframe").attr('srcdoc', data.result);
});
return false;
});
Probably you are binding the click event multiple times.
$("#btnProxy").bind("click", function() { ... } );
Possible solutions alternatives:
a) Bind the click event only on document load:
$(function() {
$("#btnProxy").bind("click", function() { ... } );
});
b) Use setTimeout and clearTimeout to filter multiple calls:
var to=null;
$("#btnProxy").bind("click", function() {
if(to) clearTimeout(to);
to=setTimeout(function() { ... },500);
});
c) Clear other bindings before set your calls:
$("#btnProxy").off("click");
$("#btnProxy").bind("click", function() { ... } );
I have a page displaying data from a json feed and I also have a button which loads more of the feed on click of a button. My aim is to append some content inside the page for each feed item. I have been able to create a function which does this on load of the page, but I am unsure how to make this work with the aysynchronous loading of more data.
I understand I need to use the .done() callback to make this work but need some guidance how to implement it correctly.
This function appends the new content initially:
function appendFeed() {
$('.feed__item').each(function (index) {
$feedItem = $('.feed__item', $(this));
$feedItem.append('<div class="feed-gallery"></div>');
for (var i = 1; i <= 5; i++) {
var $count = i;
if ($count > 1) {
$('.feed.gallery', $(this)).append('<div><img data-lazy="//placehold.it/50x50"></div>');
};
});
}
This is where the .done() callback is referred, on click of a button:
$('button').click(function(){
$.getJSON(uri, function (json, textStatus) {
// do stuff
}).done(function (json) {
// do stuff - in my case this would be appendFeed()
});
});
I have already called the appendFeed() function, but if I put it inside the .done() callback on click the button, then it appends the feed again. How do i prevent the duplication for the feed that is already on the page?
This is how you will write.
<script type="text/javascript">
$.getJSON("/waqar/file.php").done(function (data) {
$(".output").append(data);
});
</script>
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.
I have a very simple scenario where I want to POST the form using JQuery's ajax() method but perform request some confirmation from the user before actually performing the post.
I have a JQuery UI dialog with localized buttons in place in case you wonder what all the code with buttons below is about.
This is my code so far:
var i18n_deleteButtons = {};
i18n_deleteButtons[i18n.dialogs_continue] = function () {
return true;
$(this).dialog('close');
};
i18n_deleteButtons[i18n.dialogs_cancel] = function () {
return false;
$(this).dialog('close');
};
$('#delete-dialog').dialog({
open: function () {
$(this).parents('.ui-dialog-buttonpane button:eq(1)').focus();
},
autoOpen: false,
width: 400,
resizable: false,
modal: true,
buttons: i18n_deleteButtons
});
$("form#form_attachments").submit(function (event) {
/* stop form from submitting normally */
event.preventDefault();
/* get some values from elements on the page: */
var $form = $(this), url = $form.attr('action');
// build array of IDs to delete (from checked rows)
var jdata = { 'attachmentIdsToDelete': [] };
$('input:checked').each(function () {
jdata['attachmentIdsToDelete'].push($(this).val());
})
$.ajax({
beforeSend: function (request) {
// Return false if you don't want the form submit.
$('#delete-dialog').dialog('open');
},
url: url,
type: "POST",
dataType: "json",
data: jdata,
traditional: true,
success: function (msg) {
$('#msg').html(msg);
}
});
});
The dialog actually opens up fine but clicking at any of the buttons results in nothing happening. The post doesn't happen and the dialog does not close regardless of which button was clicked.
How can I make this work?
Why not move the actual ajax call from the submit handler and trigger it when pushing a button in the delete dialog?
You could store you ajax call in a separat function and pass this functions and the url as parameters to the confirmation routine.
[pseudo code]
function callAjax() {
...
}
function submitHandler() {
confirmDialog({callback:callAjax,param:you_url});
}
function confirmDialog(obj) {
$('#yes_btn').click(function() {
// call the callback
obj.callback(obj.param);
});
$('#no_btn').click(function() {
// just close the dialog
});
}
This way the confirmDialog don't have to know anything about the ajax call, it will just execute the callback with the given parameter when the user clicks ok.
Because the default jquery UI dialog is a bit cumbersome for regular use and trouble to configure in some custom scenarios I looked around and found this Easy Confirm plugin which is based upon jquery&jquery UI default stuff. It also allows for very simple internationalization.
https://github.com/wiggin/jQuery-Easy-Confirm-Dialog-plugin
Consider the following:
wrap callback in anonymous function (works)
$('#updateView').change(function(e) {
$.post(URL + "actions/updateView.php",
{ view: $(this).val() },
function() {reloadPage();}
);
});
call function directly (cookie is set but doesn't seem to update before page reload)
$('#updateView').change(function(e) {
$.post(URL + "actions/updateView.php",
{ view: $(this).val() },
reloadPage()
);
});
For what i am doing the first works but the second doesn't. the function reloadPage (shown below) reloads the page after updateView.php updates a cookie. For some reason using the second version the cookie isn't getting set before the page is reloading. but if i refresh the page my self, it "finds" the new value for the cookie.
is there something in the jQuery docs about this? I couldn't find anything.
function reloadPage() {location.reload(true);}
I am using jQuery 1.4.1, Php 5.2.5, Apache 2.2.11
Try this:
$('#updateView').change(function(e) {
$.post(URL + "actions/updateView.php",
{ view: $(this).val() },
reloadPage
);
});
reloadPage() isn't a function name, but reloadPage is :)