On a button click I'm calling a python script and I'm populating the result into an array. Once done, I create <a href> as many <a href> objects as the length of the array. Problem is, once the links are displayed, they vanish immediately.
Body:
//I obviously get the same effect by putting the onclick event in the submit button
window.onload = function() {
alert("loaded");
document.getElementById('submit_searchsubs').onclick = function () {
FindSubtitles();
};
};
function FindSubtitles() {
postData = {"movie": "Outlander", "season":"1", "episode":"2"};
$.ajax({
url: "/cgi-bin/find_subtitles.py",
type: "post",
datatype:"json",
async : false,
data: {postData},
success: function(response){
var subs = new Array();
var json = $.parseJSON(response);
for (var i=0;i<json.length;++i) {
subs[i] = new Array(json[i].IDSubtitle, json[i].SeriesEpisode, json[i].SubHash, json[i].SubDownloadsCnt, json[i].SeriesSeason, json[i].ZipDownloadLink, json[i].MovieName, json[i].id, json[i].SubFileName);
}
DisplaySubtitles(subs); //show the users the new words found in this subtitle
}
})
.fail(function(err) {
alert("error" + err);
});
}
function DisplaySubtitles(subs) {
var SubtitleDiv = document.getElementById("SubtitleDiv");
var a = document.createElement('a');
for (i = 0; i < subs.length; i++) {
var linkText = document.createTextNode(subs[i][8]);
a.appendChild(linkText);
SubtitleDiv.appendChild(a);
}
}
So what happens:
Page loads
alert("loaded") is displayed as it's fired in window.onload
FindSubtitles runs
DisplaySubtitles runs and <a> links appear
<a> links disappear and alert("loaded") is displayed again.
I don't know if I should use async: true, because in that case I get [Object object] error, which is strange because in case of another script I use that, otherwise it would freeze the UI.
Any ideas?
As Kieveli mentioned, if submit_searchsubs is a form button that submits, it may be refreshing the page after submit. Try using return false; to bypass the default browser onclick action.
document.getElementById('submit_searchsubs').onclick = function () {
FindSubtitles();
return false;
};
Related
Really stuck on this one, I've inherited a website that was built using a page builder vomits
I've created a script that guards the downloads on this page (resources) the user must fill out a form and input their details, the form submission works correctly and when it completes I open the resource using window.open(href, '_blank') this works correctly on the first submit but if you try and download a second resource it always returns the first clicked href and opens that.
Here is my code: Im getting all the anchors on the page, looping over them and adding an onClick event listener, when a user clicks the link it opens the modal, then jquery to submit the form. As you can see in the comments the href is logged correctly when outside of the submit function, however when inside the submit function it always reverts back to the first href clicked.
e.g user clicks resource1, submits the form and downloads, user then clicks resource2, submits the form but is directed to resource1 :'(
jQuery(document).ready(function ($) {
const anchors = Array.from(
document.querySelectorAll('.page-id-17757 .elementor-element-7121f28 .elementor-widget-icon-list a')
);
const modal = document.querySelector('#resources-modal');
function getFormData($form) {
var unindexed_array = $form.serializeArray();
var indexed_array = {
data: {},
};
$.map(unindexed_array, function (n, i) {
indexed_array.data[n['name']] = n['value'];
});
return indexed_array;
}
function updateFormResponse(status, anchor) {
if (status == 200) {
$('.form-response').html('Success.');
modal.close();
$('.form-response').html('');
$('#resources-submit').prop('disabled', false);
} else {
$('.form-response').html('There has been an error, please refresh the page and try again');
$$('#resources-submit').prop('disabled', false);
}
}
anchors.forEach((anchor) => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
modal.showModal();
let href = e.target.parentElement.href;
$('.resources-download').submit(function (e) {
console.log(e);
e.preventDefault();
e.stopImmediatePropagation();
let form = $(this);
$('#resources-submit').prop('disabled', true);
let formData = getFormData(form);
$.ajax({
url: '/wp-content/themes/hello-elementor/raisley/resources-download.php',
type: 'POST',
data: formData,
dataType: 'json',
complete: function (data) {
updateFormResponse(data.status, href);
if (data.status == 200) downloadResource();
},
});
});
console.log(href); // this logs the correct href
function downloadResource() {
console.log(href); // logs incorrect href, always returns the first clicked href
window.open(href, '_blank');
}
});
});
});
I'm really struggling with this one, need some pro help please!
Thanks,
This question already has answers here:
What does "async: false" do in jQuery.ajax()?
(7 answers)
Closed 3 years ago.
I have an ajax function and thought it would be nice to include a little ajax-spinner to tell the enduser something is actually happening. This is my current jQuery function:
$('#contact-form').submit(function(e)
{
e.preventDefault();
let overlay = $('#overlay'),
loader = $('#loader-popup');
console.log(overlay);
console.log(loader);
console.log('===================');
//show overlay
overlay.removeClass('hidden');
loader.removeClass('hidden');
console.log(overlay);
console.log(loader);
let formData = new FormData($(this)[0]),
params = [];
$.ajax({
data: formData,
type: 'post',
url: '/pages/contact-us/action/send.php',
cache: false,
contentType: false,
processData: false,
success: function(res)
{
if (res == 1) {
params['type'] = 1;
params['msg'] = 'We will be with you as soon as we can!'
} else {
try {
res = $.parseJSON(res);
let data = [];
$.each(res, function(key, value) {data.push(value)});
params['type'] = 2;
params['msg'] = data.join('<br />')
} catch(e) {
console.log(e);
alert('Huh. that\'s weird, something went wrong! Please try again');
//cause syntax error to stop script working
die()
}
}
validator.displayAlert(params['type'], params['msg'])
},
error: function(res)
{
console.log(res);
alert('Don\'t worry.. it\'s not you, it\'s us.')
}
});
//hide overlay
overlay.addClass('hidden');
loader.addClass('hidden');
});
But weirdly the overlay doesn't show, nor does the loader. What makes this hard to kinda debug and fathom is the console.log output.
first console.log(overlay)
Object [ div#overlay.hidden ]
second console.log(loader)
Object [ div#loader-popup.hidden ]
third console.log(overlay)
Object [ div#overlay ]
fourth console.log(loader)
Object [ div#loader-popup ]
So I can see that my .removeClass() function is working, however, inspecting my page once the form is being submitted shows the elements with the hidden class. If I manually remove that hidden class in the inspector tab then everything shows, so I know it's not a CSS issue.
You can see this happen on a much simpler scale here
I've also tried with .toggle() with no avail.
How do I even begin to debug something that seems to work behind-the-scenes but, not on screen?
You should call hide the overlay in your callback, because it'll be executing asynchronously.
Something like
try {
res = $.parseJSON(res);
let data = [];
$.each(res, function(key, value) {
data.push(value)
});
params['type'] = 2;
params['msg'] = data.join('<br />')
} catch (e) {
console.log(e);
alert('Huh. that\'s weird, something went wrong! Please try again');
//cause syntax error to stop script working
die()
} finally {
//hide overlay
overlay.addClass('hidden');
loader.addClass('hidden');
}
The logic within the $.ajax() call is asynchronous. As such you remove the class then immediately add it back in as the AJAX request is in progress.
To fix this, change the addClass() calls to be made after the AJAX request completes. In your case the best place to do this would be in the complete callback as it will fire whether the AJAX request completed successfully or with an error:
$('#contact-form').submit(function(e) {
e.preventDefault();
let $overlays = $('#overlay, #loader-popup').removeClass('hidden');
let formData = new FormData(this),
params = [];
$.ajax({
// ajax settings...
complete: function() {
$overlays.addClass('hidden');
}
});
});
the title may be a bit misleading but I'm not sure how to phrase it better, so I apologize for that.
I'm creating a custom handler so the site doesn't refresh when new content is pressed (similar to how youtube works, for example).
For that I'm using this script:
$('.sidebar2 li a').click(function (e) {
test = true;
var button = $(this);
var noteId = button.data("noteid");
$(".sidebar2 li.active").removeClass("active");
var postData = { id: noteId };
$.ajax({
url: '/API/Note',
type: 'get',
data: postData,
success: function (resp) {
if (resp.success == true) {
$('#app-bar-left').html(resp.note.navBarHTML);
$('#cell-content').html(resp.note.noteContentHTML);
window.history.pushState({ path: window.location.href }, resp.note.title, '/MyNotes/Note/' + resp.note.noteId);
document.title = resp.note.title;
$('*[data-noteId="'+resp.note.noteId+'"]').parent().addClass("active")
e.preventDefault();
test = false;
return false;
}
}
});
});
even though I've stated e.preventDefault() to trigger, javascript loads the new content into the current frame without refreshing, but the browser refreshes again anyway.
I've tried to use href="#" however in this case when I go back and handle that, I always end up with two same pages, one without and one with # at the end, and in addition to that it wouldn't be very user friendly to have all links href="#"
What am I doing wrong to make the browser redirect "normally" even though I've told him no no no?
I've also tried adding onclick="javascript:void(0)" on a elements and that didn't help
ajax is async. By the time success callback is called event will already be bubbled up the DOM tree and processed. You need to call preventDefault before sending a request.
$('.sidebar2 li a').click(function (e) {
e.preventDefault(); // here for example
test = true;
var button = $(this);
var noteId = button.data("noteid");
$(".sidebar2 li.active").removeClass("active");
var postData = { id: noteId };
$.ajax({
url: '/API/Note',
type: 'get',
data: postData,
success: function (resp) {
if (resp.success == true) {
$('#app-bar-left').html(resp.note.navBarHTML);
$('#cell-content').html(resp.note.noteContentHTML);
window.history.pushState({ path: window.location.href }, resp.note.title, '/MyNotes/Note/' + resp.note.noteId);
document.title = resp.note.title;
$('*[data-noteId="'+resp.note.noteId+'"]').parent().addClass("active")
test = false;
// returning here makes no sense also
// return false;
}
}
});
});
I have an Iframe with fields which sent data to php file through ajax. If it was successful I close (it is working) iframe and create new one with another information (doen't work). So question is: how to close the old iframe and open another one?
so here is ajax function that works but doesn't open a new iframe
$.ajax({
type: "POST",
url: "sign.php",
data: {name : name,
data: canvasData
},
success: function () {
//frame_activation(); //if it will be here it will open iframe inside the old one iframe.
alert('done');
close_frame ();
$(body).html(argument[0]);
//windows.top.frame_activation();
frame_activation(); // does't work
}
});
So the result is - the old iframe sent information and close it, but doesn't open a new iframe.
frame activation :
function frame_activation() {
//document.getElementById('bg_frame').style.visibility = 'visible';
reg = document.createElement('iframe');
document.body.appendChild(reg);
reg.id = 'iframe';
reg.src = 'activate.html';
reg.style.width='600px';
reg.style.height='200px';
position_frame(reg);
reg.style.border='solid 5px #d4d4d4';
alert('here');
return false;
}
function to close iframe:
function close_frame () {
parent.document.getElementById('bg_frame').style.visibility = 'hidden';
var el = parent.document.getElementById('iframe');
el.style.display='none';
parent.document.body.removeChild(el);
return(false);
}
function for creating first iframe with fields
function frame_reg() {
document.getElementById('bg_frame').style.visibility = 'visible';
reg = document.createElement('iframe');
document.body.appendChild(reg);
reg.id = 'iframe';
reg.src = 'frame.html';
reg.style.width='640px';
reg.style.height='400px';
position_frame(reg);
reg.style.border='solid 5px #d4d4d4';
return false;
}
You can change src of iframe to change a page display.
This is sample using Jquery :
$(document).ready(function () {
$("#btnMenu1").click(function () {
$("#myIframe").attr("src", "example.aspx");
});
});
I have an Iframe with formwhi fields wich sent data to php file through ajax. If it was successful I close iframe (it is working) and create new one with another information. So question is: how to close the old iframe and open another one?
so here is ajax function that works but doesn't open a new iframe
the function opening a new iframe work by it self but doesn't work in ajax. Where is a problem?
$.ajax({
type: "POST",
url: "sign.php",
data: {name : name,
data: canvasData
},
success: function () {
//frame_activation(); //if it will be here it will open iframe inside the old one iframe.
alert('done');
close_frame (); //closing frame with form
$(body).html(argument[0]);
//windows.top.frame_activation();
frame_activation(); // does't work, doesn't open a new iframe
}
});
So the result is - the old iframe sent information and close it, but doesn't open a new iframe.
frame activation :
function frame_activation() {
//document.getElementById('bg_frame').style.visibility = 'visible';
reg = document.createElement('iframe');
document.body.appendChild(reg);
reg.id = 'iframe';
reg.src = 'activate.html';
reg.style.width='600px';
reg.style.height='200px';
position_frame(reg);
reg.style.border='solid 5px #d4d4d4';
alert('here');
return false;
}
function to close iframe:
function close_frame () {
parent.document.getElementById('bg_frame').style.visibility = 'hidden';
var el = parent.document.getElementById('iframe');
el.style.display='none';
parent.document.body.removeChild(el);
return(false);
}
function for creating first iframe with fields
function frame_reg() {
document.getElementById('bg_frame').style.visibility = 'visible';
reg = document.createElement('iframe');
document.body.appendChild(reg);
reg.id = 'iframe';
reg.src = 'frame.html';
reg.style.width='640px';
reg.style.height='400px';
position_frame(reg);
reg.style.border='solid 5px #d4d4d4';
return false;
}