Accessing and modifing a variable in and out of functions - javascript

Hello i am trying to modify the variable popText but failing on the ajax function, i cant get the output on popText :(
What am i doing wrong?
function nariTooltip(){
var popTime;
var fading;
var popboxIsActive = false;
var mouseIsHoverPopbox = false;
var popText;
//Using Event Delegation to cover late AJAX inserted DOM elements
//no need to recall function after each AJAX run
//Mouseenter / Mouseout
$("body").on(
{
mouseenter: function(e){
$hoverElem = $(this);
//Define Variables
var popDelay = 250;
if ($hoverElem.attr("popdelay")){
var popDelay = $hoverElem.attr("popdelay");
}
popTime = setTimeout(function() {
popText = $hoverElem.attr("poptext");
if ($hoverElem.next().hasClass("poptext")) {
popText = $hoverElem.next(".poptext").html();
}
var popAjax = $hoverElem.attr("popajax");
if (popAjax){
var popAjax = popAjax.split(':');
popAjaxType = popAjax[0];
if (popAjaxType == 'general')
{
popAjaxUrl = 'tooltip_gen.php';
}
else if (popAjaxType == 'item')
{
popAjaxUrl = 'tooltip_items.php';
}
if (popAjaxUrl){
$.ajax({ url: 'ajax/'+popAjaxUrl,
data: {id: popAjax[1]},
type: 'get',
success: function(output)
{
popText = output;
},
error:function (xhr, ajaxOptions, thrownError){
popText = html(xhr.statusText);
},
});
}
//alert(outputs);
}
//Create Popup
$hoverElem.append('<div class="popbox">' + popText + '</div>');
popText always end up with the value assigned on popText = $hoverElem.next(".poptext").html();

It seems that you create the div with the text before ajax has returned. Make function that sets the popText and call it when you've got it from ajax
function setPopText( elem, txt ) {
$(elem).append('<div class="popbox">' + txt + '</div>')
}
And in your ajax
success: function ( output ) {
setPopText( $hoverElem, output );
}

Related

How to a output message in separate message boxes for a chatbot

So I'm trying to build a chatbot using python, flask, nlp, js. But I'm new to js and just started to learn about it.
Output
How should I output this prediction into separate message boxes for each section?
response_sentence = f"It looks to me like you have <b>" + disease + "</b>. <br><br> <i>Description: " + description + "</i>" + "<br><br><b>"+ precautions + "</b><br><br>" + f"Confidence level: {(confidence_level * 1000):.2f}% "
This is the python line which outputs the above image.
$(document).ready(function () {
symptoms = JSON.parse(symptoms);
let input = $("#message-text");
let sendBtn = $("#send");
let startOverBtn = $("#start-over");
let dataList = $("#symptoms-list");
let chat = $("#conversation");
// Handler for any input on the message input field
input.on("input", function () {
let insertedValue = $(this).val();
$("#symptoms-list").empty();
if (insertedValue.length > 1) {
ssymptoms = $.fn.getSuggestedSymptoms(insertedValue);
if (ssymptoms.length === 0) {
$(".symptoms-list-container ").slideUp();
} else {
for (let i = 0; i < ssymptoms.length; i++) {
var li = document.createElement("li");
li.textContent = ssymptoms[i];
dataList.append(li);
}
$(".symptoms-list-container ").slideDown();
}
} else {
$(".symptoms-list-container ").slideUp();
}
});
startOverBtn.on("click", function () {
$.fn.startOver();
});
sendBtn.on("click", function () {
$.fn.handleUserMessage();
});
// Handler for click on one of the suggested symptoms
dataList.on("click", "li", function () {
input.val($(this).text());
$(".symptoms-list-container ").slideUp();
});
//todo: blur on input - does not work with suggestion item clicks
input.on("blur", function () {
$(".symptoms-list-container ").slideUp();
});
input.on("keypress", function (e) {
if (e.which == 13) {
$.fn.handleUserMessage();
}
});
// Handler function for sending a message
$.fn.handleUserMessage = function () {
if (input.val()) {
$.fn.appendUserMessage();
$.fn.getPredictedSymptom();
input.val("");
chat.animate({
scrollTop: $("#conversation .message-body:last-child").position().top,
});
}
};
$.fn.startOver = function () {
$.fn.getPredictedSymptom(true);
$("#conversation").empty();
const text =
"Welcome!";
$("#conversation").append(
`<div class="row message-previous"><div class="col-sm-12 previous"></div></div><div class="row message-body"><div class="col-sm-12 message-main-receiver"><div class="receiver"><div class="message-text">${text}</div></div></div></div>`
);
input.val("");
};
// Creates the newly sent message element
$.fn.appendUserMessage = function () {
var text = input.val();
$("#conversation").append(
`<div class="row message-body"><div class="col-sm-12 message-main-sender"><div class="sender"><div class="message-text">${text}</div></div></div></div>`
);
};
$.fn.appendBotMessage = function (text) {
$("#conversation").append(
`<div class="row message-body"><div class="col-sm-12 message-main-receiver"><div class="receiver"><div class="message-text">${text}</div></div></div></div>`
);
};
// Retreives prediction to show as bot message
$.fn.getPredictedSymptom = function (again) {
var text = input.val();
if (again) text = "done";
$.ajax({
url: "http://127.0.0.1:5000/symptom",
data: JSON.stringify({ sentence: text }),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
success: function (response) {
console.log(response);
if (!again) $.fn.appendBotMessage(response);
},
error: function () {
console.log("Error");
},
});
};
$.fn.getSuggestedSymptoms = function (val) {
let suggestedSymptoms = [];
$.each(symptoms, function (i, v) {
if (v.includes(val)) {
suggestedSymptoms.push(v);
}
});
return suggestedSymptoms.slice(0, 3);
};
});
This is js file I'm using. I'm sorry if it feels like a silly doubt.

JavaScript Increment number every time (if statement) is true

In my code I am retrieved data from the data base every 30 seconds using AJAX. I want to use JavaScript to increment variable wht every time data is received from the database (every 30 seconds) and when if statement is true. Below code is working and incrementing to 1 but it doesn't go above 1. Does anyone has a solution for this problem?
<script>
$(document).ready(function () {
ajax_call = function() {
$.ajax({
type: "GET",
url: "test.php",
dataType: "html",
success: function (response) {
color = response;
console.log(color);
if (color == white){
var wht = (function(w) {
return function() {
w += 1;
return w;
}
}(0));
document.getElementById("memo").value = wht();
}else{
console.log("Color is not white");
}
var interval = 30000;
setInterval(ajax_call, interval);
});
</script>
<script>
const minusButtonFw = document.getElementById('memo-minus');
const plusButtonFw = document.getElementById('memo-plus');
var memo = document.getElementById('memo');
minusButtonFw.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(memo.value);
memo.value = currentValue - 1;
});
plusButtonFw.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(memo.value);
memo.value = currentValue + 1;
});
</script>
First of all your variable wht is a function. If you simply want to keep track of the number of time the if conditions is true you can do it by making the variable static (literaly). you can achive this by storing the variable in a global scope.
Also there are sytax errors in your code too where wht is defined.
try this
$(function () {
var memo = document.getElementById("memo");
memo.val = 0;
var ajax_call = function () {
$.ajax({
type: "GET",
url: "test.php",
dataType: "html",
success: function (response) {
color = response;
console.log(color);
if (color == white) {
memo.val++;
memo.value = memo.val;
} else {
console.log("Color is not white");
}
}
});
}
var interval = 30000;
setInterval(ajax_call, interval);
});
A Note:
If the response is managed by you, I would recomend sending the response as json rather than simply sending it as an html with just one value color.
You'll need to keep track of "w". Your current setup is using "w" as a parameter to a function. You'd need to keep it outside of the function and increment it from inside the function. You'll also need to wrap that function in an interval Something like the following:
var w = 0;
function setWhite(color) {
if (color == white) {
w++;
document.getElementById("memo").value = w;
} else {
console.log("Color is not white");
}
}
setInterval(function() {
setWhite(color);
}, 30000);
This should give you what you want. I didn't run the code so there are probably syntactical errors that you'll need to correct.
Try change the line
document.getElementById("memo").value = wht();
to
document.getElementById("memo").value = wht(document.getElementById("memo").value);
Your full code:
<script>
$(document).ready(function () {
ajax_call = function() {
$.ajax({
type: "GET",
url: "test.php",
dataType: "html",
success: function (response) {
color = response;
console.log(color);
if (color == white){
var wht = (function(w) {
return function() {
w += 1;
return w;
}
}(0));
document.getElementById("memo").value = wht(document.getElementById("memo").value);
}else{
console.log("Color is not white");
}
var interval = 30000;
setInterval(ajax_call, interval);
});
</script>
I made an example with setInterval. I made w global so it will work. Try this:
var w = 0;
var interval = setInterval(function() {
if (color == white) {
w++;
document.getElementById("memo").value = w;
} else {
console.log("Color is not white");
}
}, 30000);

Javascript nested dictionary null values

Below I have declared a 'class' in JS and am writing methods for it. The class represents a widget (more info class structure).
The problem I'm having is that when I print 'this' inside the setAttr ibutes method, the output is:
And when I print 'this.opts' in the very next line:
NOTE: The values of 'status' and 'power' are shown as 'null' in the second output before expanding it. This can be the only possible reason behind getting 'null' while trying to print 'this.opts.status'.
CODE
function PowerStatus(options) {
this.opts = {
meterName: '-',
displayName: null,
status: null,
power: null,
mainDiv: null,
};
this.opts = $.extend(this.opts, options);
this.opts.mainDiv = '#' + this.opts.mainDiv;
this.onClick = function () {
console.log('Clicked ' + this.opts.meterName);
};
// fill in missing attributes
this.getAttributes();
this.setHtml();
this.bindUIActions();
}
PowerStatus.prototype.getAttributes = function () {
var _this = this;
if (this.opts.displayName == null) {
getDisplayName(function (dName) {
_this.opts.displayName = dName;
}, _this.opts.meterName);
}
if (_this.opts.status == null || _this.opts.power == null) {
_this.getStatus(function (status, power) {
_this.opts.status = status;
_this.opts.power = power;
}, _this.opts.meterName)
}
};
PowerStatus.prototype.setHtml = function () {
var _this = this;
var divType = this.opts.mainDiv.split('-').slice(1).slice(0, -1).join('_');
var url = '/static/' + divType + '/html/' + divType + '.html';
$(this.opts.mainDiv).load(url, function () {
_this.setAttributes();
});
};
PowerStatus.prototype.setAttributes = function () {
var div = $(this.opts.mainDiv).find('.load-name');
var span = $('span:first', div);
span.text(this.opts.displayName);
div = $(this.opts.mainDiv).find('.load-value');
span = $('span:first', div);
span.text(this.opts.power);
};
PowerStatus.prototype.bindUIActions = function () {
var _this = this;
$(this.opts.mainDiv).on('click', function () {
_this.onClick();
});
};
PowerStatus.prototype.getStatus = function (callback) {
$.ajax({
method: "GET",
dataType: "json",
url: "/widget/power_status/status/",
data: {name: this.opts.meterName},
success: function (data) {
if (typeof callback === "function") callback(data.status, data.power);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
};
The value of this inside your click handler is not the same as the value outside that handler. You need to stash this in a local variable and use that instead.
var statusObj = this;
this.onClick = function () {
console.log('Clicked ' + statusObj.opts.meterName);
};
Alternatively, you could use .bind():
this.onClick = function () {
console.log('Clicked ' + this.opts.meterName);
}.bind(this);
The value of this is always set on every individual call to a function based on the circumstances of the call.

Jquery .load firing twice, but being called once

I have a problem here, my jquery .load function seems to be running twice even though Im only calling it once. Here is my code:
function updateRowItem(idIn){
if (ready) {
id = idIn
$("#controlPanelResult").css("background-color", "");
var query = {};
var tid = id.replace("#", "\\#");
tid = tid.replace(".", "\\.");
var value = $('#'+tid).text();
//var value = decodeURI(document.getElementById(id).innerHTML);
//if (value == "<br>"){
// value = "NULL"
//}
//value = value.replace(" "," ")
//value = value.replace("&","&")
var split = id.split('#');
var temp = split[0];
var uuid = split[1];
var temp2 = temp.split('.');
var tableName = temp2[0];
var item = temp2[1];
query['table_name'] = tableName;
query['uuid'] = uuid;
query[item] = value;
var tid = id.replace("#", "\\#");
tid = tid.replace(".", "\\.");
$.ajax({
async: false,
type: "POST",
//url: '/admin/updateRow?table_name=' + tableName + "&uuid=" + uuid +"&" + item + "=" + value,
url: '/admin/updateRow',
data: query,
success: function(data) {
if (data == "1"){
alert ("Hellooo!")//This alert only and always pops up once
$('#'+tid).empty().load(showRowsUrl + " #" + tid,function (status) {
alert (status) // This alert pops up first once, then twice, then four times, then eight etc....
$("#"+tid).animate({backgroundColor: '#70DB70'}, 'slow');
$('#controlPanelResult').html("Updated: " + id);
$("#controlPanelResult").animate({ backgroundColor: '#70DB70'}, 'slow');
$("#"+tid).animate({backgroundColor: 'white'}, 'slow');
});
} else {
$('#mainRows').load(showRowsUrl, function() {
$("#"+tid).animate({backgroundColor: 'red'}, 'fast');
$('#controlPanelResult').html(data);
$("#controlPanelResult").animate({backgroundColor: 'red'}, 'fast');
});
}
}
});
}
}
This causes my divs contents to be constantly repeated, I would appreciate any help in figuring this out
Replace the problematic .load() call with this:
$.get(showRowsUrl, function(data) {
$('#'+tid).replaceWith($('#'+tid,'<div>'+data+'</div>'));
$("#"+tid).animate({backgroundColor: '#70DB70'}, 'slow');
$('#controlPanelResult').html("Updated: " + id);
$("#controlPanelResult").animate({ backgroundColor: '#70DB70'}, 'slow');
$("#"+tid).animate({backgroundColor: 'white'}, 'slow');
});
Explanation: .load is loading the element into itself, so there are afterwards two elements with the same ID, nested. Then when you run .load again, it runs on both elements with that ID, and so on.

ajax() call in javascript function

i have a jquery .click() function that executes an .ajax() method call
$(".btn-play").live("click", function () {
//set globalSortNumber
globalSortNumber = $(this).parents("[sortnumber]").attr("sortnumber");//.attr("value") ; //change should be some type of input like mediaid //see if its possible to add the sortID to the handle span
// alert(globalSortNumber);
//set title
//set mediaID
var mediaID = $(this).parents("[mediaid]").attr("mediaid");
// alert(mediaID);
//ajax query to get link and excute code to launch music
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
})
when the .ajax() method executes succesfully it calls a javascript function
function playsong(sortNumber,url) {
if (soundManager.supported()) {
globalSortNumber = sortNumber;
var aSoundObject = soundManager.createSound({
id: 'mySound' + sortNumber,
url: url,//'/Music/mafiamusicpt2rickross.mp3',
whileplaying: function () {
if (count == 0) {
if (this.position > 1000) {
this.pause();
pos = this.position;
count++;
this.resume();
}
} else if (count == 1) {
soundManager._writeDebug('old position: ' + pos);
soundManager._writeDebug('new position: ' + this.position);
// See that this.position is less than pos!
count++;
}
},
onfinish: function () {
//find the next song in the list
//var nextSongPosition=
this.destruct();
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
})
playsong(sortNumber++,url)
}
});
aSoundObject.play();
}
}
as you can see i have an .ajax() method inside my javascript function, is this possible?
I am creating loop that starts on the finish listener of the soundmanager object. So when I need to make the ajax call to get he next url I need. If my way isnt correct can you please tell me what is the best way to accomplish what i am trying to do.
Think it's fine but i would make a separate function for the ajax call so you dont need to duplicate the code twice. Easier to maintain.
$(".btn-play").live("click", function () {
//set globalSortNumber
globalSortNumber = $(this).parents("[sortnumber]").attr("sortnumber");//.attr("value"); //change should be some type of input like mediaid //see if its possible to add the sortID to the handle span
//alert(globalSortNumber);
//set title
//set mediaID
var mediaID = $(this).parents("[mediaid]").attr("mediaid");
//alert(mediaID);
//ajax query to get link and excute code to launch music
getAudio(mediaID);
}
function playsong(sortNumber,url) {
if (soundManager.supported()) {
globalSortNumber = sortNumber;
var aSoundObject = soundManager.createSound({
id: 'mySound' + sortNumber,
url: url,//'/Music/mafiamusicpt2rickross.mp3',
whileplaying: function () {
if (count == 0) {
if (this.position > 1000) {
this.pause();
pos = this.position;
count++;
this.resume();
}
} else if (count == 1) {
soundManager._writeDebug('old position: ' + pos);
soundManager._writeDebug('new position: ' + this.position);
// See that this.position is less than pos!
count++;
}
},
onfinish: function () {
//find the next song in the list
//var nextSongPosition=
this.destruct();
getAudio(mediaId);
playsong(sortNumber++,url)
}
});
aSoundObject.play();
}
}
function getAudio(mediaID) {
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
});
}

Categories

Resources