javascript function not responding after ajax request ( xmlhttprequest) - javascript

I have the following functions:
$(function() { //add new language
var lg_select = $('#add_language');
var table = lg_select.parent();
var table_head = $('form[name=languageData] tr').has('th')
$('.cv_addLang').click(function(e) {
e.preventDefault();
if(table_head.is(':hidden')) {
$('.nolangauge').hide();
table_head.show();
}
var new_lang = lg_select.clone();
new_lang.find('select[disabled=disabled]').removeAttr('disabled');
new_lang.find('select[name=new_language]').attr('name', 'language[]');
new_lang.find('select[name=new_level]').attr('name', 'language_level[]');
new_lang.appendTo(table).show();
})
})
function getXMLHttpRequestObject() { //ajax
var ajax = false;
if(window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else if(window.ActiveXObject) {
try {
ajax = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
}
}
}
return ajax;
}
$(function() { //ajax
var ajax = getXMLHttpRequestObject();
if(ajax) {
$('div').delegate(".but_cv_w", "click", function(e){
e.preventDefault();
var div_content = $(this).parent().parent();
if(div_content) {
var x=$(div_content).attr('id');
//alert(x);
//alert(div_content);
var path = $(this).attr('href');
//alert(path);
ajax.open('get', path + '&ajax=true');
ajax.onreadystatechange=function() {
if(ajax.readyState == 4) {
if((ajax.status == 200) || (ajax.status == 304)) {
$(div_content).html(ajax.responseText);
} else {
$(this).click;
}
}
}
ajax.send(null);
return false;
}
})
}
})
The problem is that both new language and ajax are working fine but separated. If I delete the ajax function then new language function is working but if I keep the ajax function and make an ajax request then the other function (new language) isn't working anymore. It seams that after an ajax request the new language function dosen't work the seam as befor the ajax request.
The new language function is supposed to add new inputs for languages, the "cv_addLang" is the calss of an button which appears on the page after an normal server request or after a ajax request?
Hope someone could help me with this ??
Thanks for any help!

The Problem lies on the add new language function. Instead of an click event it is necesary to use delegate event and so the function should look like this in order for it to work.
$(function () { //add new language
$("body").delegate('.cv_addLang','click',function(e) {
e.preventDefault();
var lg_select = $('#add_language');
var table = lg_select.parent();
var table_head = $('form[name=languageData] tr').has('th');
if(table_head.is(':hidden')) {
$('.nolangauge').hide();
table_head.show();
}
var new_lang = lg_select.clone();
new_lang.find('select[disabled=disabled]').removeAttr('disabled');
new_lang.find('select[name=new_language]').attr('name', 'language[]');
new_lang.find('select[name=new_level]').attr('name', 'language_level[]');
new_lang.appendTo(table).show();
});
})

Related

Callback methods (a XMLHttpRequest) in a Javascript Class Object

I seem to get the following error: this.getPageHTML is not a function when executing my Modal class.
constructor(trigger) {
this.trigger = trigger;
}
/**
* Show Modal
* #param {Element} trigger The element that is triggering the Modal.
*/
showModal(trigger = this.trigger) {
switch (trigger.dataset.modaltype) {
case "media":
this.getPageHTML(trigger.dataset.url, (response) => {
const htmlContent = response.getElementById("content");
const modalContent = document
.getElementById("modal")
.querySelector(".modal-window__content");
// Inject response into Modal content
modalContent.insertAdjacentHTML("beforeend", htmlContent.innerHTML);
});
break;
default:
break;
}
}
getPageHTML(url, callback) {
if (!window.XMLHttpRequest) return;
const xhr = new XMLHttpRequest();
// Get the HTML
xhr.open("GET", url);
xhr.responseType = "document";
xhr.onloadstart = this.requestStarted;
xhr.onprogress = this.updateRequestProgress;
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
xhr.onload = function () {
if (callback && typeof callback === "function") {
callback(this.responseXML);
}
};
}
};
xhr.send();
}
Not sure why exactly my getPageHTML function is "not a function"?
In my main js file I call the class like this:
modalTriggers.forEach((trigger) => {
trigger.addEventListener("click", (e) => {
let modal = new Modal(trigger);
modal.showModal();
e.preventDefault();
});
});
Could be something super obvious I'm missing here. I have tried assigning the "this.getPageHTML" to an anonomous function like "this.getPageHTML = function(trigger.dataset.url, response) {...}" but it seems to loose what "trigger" is.

How to implement different behavior for function in anonymous function javascript

I am new to JavaScript and I want to use send_request function twice, but with different behaviour. Element with name button1 should show response on the element, whereas button2 not.
function send_request(url) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.send('data=test');
xhr.onload = function () {document.getElementById('reply').innerHTML = xhr.responseText;};
}
document.getElementById('button1').addEventListener('click', function() { send_request("/data.php"); });
document.getElementById('button2').addEventListener('click', function() { send_request("/clear_data.php"); });
Is it possible?
There are a number of ways to accomplish this, but if we just start with your basic requirement, you could have send_request simply take an argument that determines if the element should show the response.
function send_request(url, showResponse) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.send('data=test');
xhr.onload = function () {
// If showResponse is true, log the response. If not, don't
showResponse ? document.getElementById('reply').innerHTML = xhr.responseText : null;
};
}
document.getElementById('button1').addEventListener('click', function() {
// Call the function and indicate that the response should be shown
send_request("/data.php", true);
});
document.getElementById('bitton2').addEventListener('click', function() {
// Call the function and indicate that the response should not be shown
send_request("/clear_data.php", false);
});
You could give send_request another parameter, a function that's called with the responseText, so you could pass one function that assigns to reply, and another function that does whatever you want instead:
function send_request(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.send('data=test');
xhr.onload = () => callback(xhr.responseText);
}
document.getElementById('button1').addEventListener('click', function() {
send_request("/data.php", (responseText) => {
document.getElementById('reply').innerHTML = responseText;
});
});
document.getElementById('bitton2').addEventListener('click', function() {
send_request("/clear_data.php", (responseText) => {
console.log('bitton 2 response: ' + responseText);
});
});

AJAX content change plus small change effect

im trying to change an AJAX Code to add a small change effect so users can see that something happend on screen, cause the change of the content is hidden and its hard to notice that only some numbers have changed
function changeBox(post) {
if (http != null) {
http.open("POST", 'ajaxchangebox.php', true);
http.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if (!http) {
return;
}
if (http.readyState == 4) {
document.getElementById("box").innerHTML = http.responseText;;
}
}
http.send(post);
}
}
I am not familiar with Javascript/AJAX. The kind of effect itself is not important. it should be something flashing, short change of colour or something like that.
Thanks for your help
Christian
Maybe this can help: Animate.css
usage:
document.getElementById("box").classList.add('bounce animated')
You need to add a listener to catch animation end event:
var onDone = (function(){
var elm = document.getElementById('box');
var animateEndName = function () {
var i,
el = document.createElement('div'),
mapping = {
'animation': 'animationend',
'OAnimation': 'oanimationend',
'MozAnimation': 'animationend',
'WebkitAnimation': 'webkitAnimationEnd'
}
for (i in mapping) {
if (el.style[i] !== undefined) {
return mapping[i];
}
}
}();
elm.addEventListener(animateEndName, function(){
elm.classList.remove('flash', 'animated');
});
return function(result){
elm.innerHTML = result;
elm.classList.add('flash', 'animated');
}
})();

click addEventListener is called without been clicked

I'm trying to add a function Fvote to all elements with class vote-up and vote-down.
var voteup = document.getElementsByClassName("vote-up");
var votedown = document.getElementsByClassName("vote-down");
function Fvote(upordown,postid) {
var x=this;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {console.log(xmlhttp.responseText);
if(xmlhttp.responseText=="error")
;
else{
/*some JS actions*/;}
}
xmlhttp.open("GET", "ajax/vote.php?q=" + postid + "q2="+upordown, true);
xmlhttp.send();
}
for(var i=0;i<voteup.length;i++)
voteup[i].addEventListener('click', Fvote("up",voteup[i].getAttribute("data-vote")), false);
for(var i=0;i<votedown.length;i++)
votedown[i].addEventListener('click', Fvote("down",votedown[i].getAttribute("data-vote")), false);
But when I load the page, it runs the function Fvote many times as the count of elements number, without clicking on any item. and if I clicked on items with class of vote-up or vote-down the function is not called. What I'm doing wrong?
You can get the parameters from within the function:
var voteup = document.getElementsByClassName("vote-up");
var votedown = document.getElementsByClassName("vote-down");
function Fvote(e) {
var x = e.target,
upordown = x.className.indexOf('vote-up') > -1 ? 'up' : 'down',
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
postid = x.getAttribute('data-vote');
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
console.log(xmlhttp.responseText);
if(xmlhttp.responseText=="error") {
/*some JS actions*/
} else {
/*some JS actions*/
}
}
xmlhttp.open("GET", "ajax/vote.php?q=" + postid + "q2="+upordown, true);
xmlhttp.send();
}
for(var i=0;i<voteup.length;i++)
voteup[i].addEventListener('click', Fvote, false);
for(var i=0;i<votedown.length;i++)
votedown[i].addEventListener('click', Fvote, false);
You got the wrong idea of how addEventListener works.
Basically it registers an event handler, which is an "address" of a function to execute when the event occurs. What you're doing is CALLING the function and EXECUTING it inside the loop.
Here's how it's normally used:
function handle() {
alert('An event!');
}
myElement.addEventHandler('click', handle);
Note that in this fragment, handle is passed without parenthesis thus "passing in the address", not invoking a call.

How to play a sound effect in ajax post way on jQuery and javascript?

I'm trying to play a sound effect when write a data of post method to mysql server which works with php and receive a xml.
so I wrote a code like following.
When I write a data (#post_send button click), sound works well,
but receive a data, sound doesn't work.
I doubt that sound doesn't work when play sound snippet is in a ajax or similar function..
How to play a sound in ajax post methos?
// Start Main code Area //
$(document).ready(function () {
// Global variable define area
curr_date = null;
last_date = "0000-00-00 00:00:00";
readAjax_timer = null;
audioElement = null;
// End of Global variable define area
audioElement = document.createElement('audio');
audioElement.setAttribute('src', './sound/bubble.mp3');
$("#post_send").click(function () {
audioElement.play();
curr_date = getTodayAndTime();
last_date = curr_date;
var str_postMsg = $("textarea").val();
if (str_postMsg == "") {
return;
}
appendShowBubble();
writeMsgToDB();
});
readAjax_timer = setInterval(function() {
readMsgByAjax();
}, 2000);
readMsgByAjax();
});
// End Main code Area //
Here is a function of receiving a data.
function readMsgByAjax() {
// receive a data from mysql by specified school name with ajax.
var sch_name = "wonderful_element_school";
var send_data = "sch_name=" + sch_name +
"&last_date=" + last_date;
// call ajax post method
$.post(
"PHP_readMsg_sql.php",
send_data,
function (data) {
$(data).find('tr').each(function () {
var db_record = $(this); //<= <tr>
// if "$(this)" is a table head, continue to next tr.
if (db_record.attr("id") == "head") {
return;
}
//////////////////////////////////////////////////
audioElement.play(); //<== This code doesn't work.
//////////////////////////////////////////////////
// process contents of tr.
var str_message;
var str_date;
var div_leftframe = $("#left_frame").clone();
div_leftframe.css("display", "block");
var p_message = div_leftframe.children('p');
str_message = db_record.find('td[id=post_message]').text();
str_message = str_message.replace(/\u000a/g, "</br>");
p_message.html(str_message);
var small_message = div_leftframe.children('small');
str_date = db_record.find('td[id=post_time]').text();
last_date = str_date;
str_date = str_date.replace(" ", " at ");
small_message.text(str_date);
$("#chat_list").append(div_leftframe);
});
}
);
$("#chat_list").append(div_leftframe);
var $target = $('html,body');
$target.animate({scrollTop: $target.height()}, 1000);
}
You would have to pass the audioElement in the function since it's out of scope of your function as #scrowler mentioned. So you can either add the function in your document.ready() scope, or you can change your function to:
function readMsgByAjax(audioElement){}
And when you call it in your document.ready() code, just do this:
readMsgByAjax(audioElement);

Categories

Resources