Accessing Newer Version of Variable from Different Scope (JavaScript / jQuery) - javascript

I want to populate the results div with the already loaded variable, data1, when the back button is clicked. With this code, when the back button is clicked, the results div gets set to "". How do I access the newer version of data1?
Javascript:
function finddata(def,id){
$("#doctitle").html($("#exp").val() + " - Writer's Dictionary");
$("#results").html('<span class="glyphicon glyphicon-cog glyphicon-spin" title="loading..."></span>').fadeIn();
if (def == 1) {
var word = id.innerHTML;
$.get( "processor.php?query=" + word + "&def=" + def, function(data2) {
$("#results").html(data2);
$("#back").click(function(){
$("#results").html(data1);
});
});
} else {
$.get( "processor.php?query=" + $("#exp").val(), function(data1) {
$("#results").html(data1);
});
}
}
HTML:
<div class="container">
<div class="col-md-6 col-md-offset-3" id="results">
<div id="back">Back</div>
</div>
</div>

Try
<div id="back" onclick="finddata(2)">Back</div>
to set def parameter to value other than 1 , which should call $.get() within else statement of finddata
Edit, Updated
var data;
function finddata(def) {
if (def === 1) {
// do stuff
} else {
// if `data` defined
if (data) {
// do not do stuff here
}
// else call `.get()`
else {
var word = id.innerHTML;
$.get( "processor.php?query=" + word + "&def=" + def, function(data2) {
$("#results").html(data2);
$("#back").click(function(){
$("#results").html(data1);
});
});
}
}
}
$("#back").click(function() {
finddata(2)
})
jsfiddle http://jsfiddle.net/229ad2b2/2/

Related

Using AJAX, JavaScript to call python flask function with return to JavaScript

I know that you can have javascript to call a python flask function and be able to return data to a designated id. Like this:
HTML
<div id = "update"> </div>
<script type="text/javascript">
var counter = 0;
window.setInterval(function(){
$("#update").load("/game?counter=" + counter);
counter++;
}, 5000)
views.py
from flask import request
#app.route("/game")
def live_game():
textlist = ['a','b','c','d']
counter = request.args.get('counter')
return "<p> " + textlist[counter] + " </p>"
I found this in a previous post. What I would like to do is update utilize this method in updating some cool justgage that I found online to show the most up to date temperature and humidity readings from my database. Here is the script that I was wanting to use:
HTML
<div class="container">
<div class="jumbotron">
<h1>Historical Environmental Readings</h1>
<div class="container-fluid" id="dht-container">
<div id="g1" style="width: 200px; height: 150px;"></div>
<div id="g2" style="width: 200px; height: 150px;"></div>
</div>
</div>
</div>
.....
<script>
function ajaxd(NodeID) {
//reload result into element with id "dht-container"
$(??????).load("/tempnodeDHT", function() { alert( "Temp Load was performed." ); });
document.addEventListener("DOMContentLoaded", function (event) {
var g1 = new JustGage({
id: "g1",
value: 50,
min: -20,
max: 150,
title: "DHT Temp",
label: "temperature",
pointer: true,
textRenderer: function (val) {
if (val < NODE_EnvCP.low_temp) {
return 'Cold';
} else if (val > NODE_EnvCP.hot) {
return 'Hot';
} else if (val === NODE_EnvCP.optimum_temp) {
return 'OK';
}
},
});
var g2 = new JustGage({
id: "g2",
value: 50,
min: 0,
max: 100,
title: "Target",
label: "Humidity",
pointer: true,
textRenderer: function (val) {
if (val < NODE_EnvCP.low_hum) {
return 'LOW';
} else if (val > NODE_EnvCP.high_hum) {
return 'HIGH';
} else if (val === NODE_EnvCP.optimum_hum) {
return 'OK';
}
},
});
setInterval(function () {
(currentTemp, currentHumidity)=ajaxd();
g1.refresh(currentTemp);
g2.refresh(currentHumidity);
return false;
}, 2500);
});
</script>
This is my python flask function:
run.py
#app.route('/nodeDHT')
def getLatestDHT():
NodeID = request.args.get('NodeID')
df = DAO.Pull_CURRENT_DHT_Node_Data(self, NodeID)
currentTemp = df.Temperature[0]
currentHumidity = df.Humidity[0]
return (currentTemp, currentHumidity)
I was hoping that I could change the ?????? inside
$(??????).load("/nodeDHT", function() { alert( "Temp Load was performed." ); });
so that the two variables (currentTemp, currentHumidity) would end up back into the javascript portion so that the gages would update every 2.5 seconds. Also, am I passing the variable back to the python flask? there is a variable already pushed to the html when it was rendered.
EDIT:
could I do something like this:
#app.route('/nodeDHT')
def getLatestDHT():
NodeID = request.args.get('NodeID')
df = DAO.Pull_CURRENT_DHT_Node_Data(self, NodeID)
currentTemp = df.Temperature[0]
currentHumidity = df.Humidity[0]
return json.dumps(currentTemp, currentHumidity)
and in the javascript side do something like this?
function ajaxd(NodeID) {
//reload result into javascript
$.get("/nodeDHT",function( currentTemp, currentHumidity ){ console.log($.parseJSON(currentTemp, currentHumidity)});
What I'm really asking is. How can I pass single/multiple variables to the python flask function from the javascript function and then get back a dataframe where I can use column values to update a chart or multiple variables back to the javascript function to be used in a setinterval to be used for multiple functions such as updating justgage
setInterval(function () {
(currentTemp, currentHumidity)=ajaxd();
g1.refresh(currentTemp);
g2.refresh(currentHumidity);
return false;
}, 2500);
---------------------DOUBLE EDIT -----------------------
COULD I DO SOMETHING LIKE THIS:
function UPDATEGAGES(NodeID) {
$.get('/nodeDHT?NodeID='+NodeID+'&startdatetime='+startdatetime,
function(data){ const parsed = JSON.parse(data)};
g1.refresh(currentTemp);
g2.refresh(currentHumidity);
});
setInterval(function () {
UPDATEGAGES(NodeID);
return false;
}, 2500);
If you want to send variables to server in get method, use variables in url
'/tempnodeDHT?NodeID='+your_nod_id+'&anotherVar='+value+'&anotherVar2='+value2
You can access them in your flask server as below
NodeID = request.args['NodeID']
anotherVar = request.args['anotherVar']
anotherVar2 = request.args['anotherVar2']
If you want to send multiple variables from flask server to your front end, send it as JSON
return jsonify({'currentTemp': currentTemp, 'currentHumidity': currentHumidity })
When you handle it the response from the server, again parses it to JSON.
$.get( '/nodeDHT/tempnodeDHT?NodeID='+your_nod_id+'&anotherVar='+value+'&anotherVar2='+value2, function( data ) {
const parsed = JSON.parse(data)
// here you can access your 'currentTemp' variable from parsed.currentTemp
});
EDIT
For your final desired output
function UPDATEGAGES(NodeID, startdatetime) {
$.get('/nodeDHT?NodeID='+NodeID+'&startdatetime='+startdatetime,
function(data){
const parsed = JSON.parse(data)
g1.refresh(parsed.currentTemp);
g2.refresh(parsed.currentHumidity);
};
)
};
setInterval(function () {
UPDATEGAGES(NodeID, startdatetime);
return false;
}, 2500);

onClick - Call Function from Another File

I have a functionality.js file which is linked to the front-end, within here I want to click on a div(item1wrapper) and call a function from my index.js file.
Within this functionality.js file I append the div:
socket.on('response', function (data) {
if (msg.includes('totalPrice')) {
if (parsed.itemPrice.length === 1) {
$('#messages').append($('<li id="messageclient">').append($(`
<div id="message-cont" class="message-cont">
<div class="orderDetailsWrapper">
<div class="detailsHeaderWrapper">
<div class="orderNum"></div>
<div class="customerName"></div>
</div>
<div class="textToCustomer">
<p> Please click on the item you want to return</p>
</div>
<div class="itemBoxWrapper">
<div id ="item1Wrapper" class="item1Wrapper" onclick="">
<div class="item1Title"></div>
<div class="item1Price"></div>
</div>`
)).append($('<div id="client-imgorder">')));
$("#messages").animate({ scrollTop: $("#messages")[0].scrollHeight }, 1000);
$('.customerName').text('Customer name: ' + customerName);
$('.orderNum').text('Order number: ' + orderNum);
$('.item1Title').text('Item: ' + item1Title);
$('.item1Price').text('Price: ' + item1Price);
}
Module exports isnt working because it's linked to the front-end?
Here is my function within my index.js file:
function oneCall() {
itemId = itemIdArray[0];
// matching API get
// getRefundCalc API post.
console.log('ngrokurl' + ngrokUrl)
console.log('domain' + domain)
console.log('orderId' + orderId)
console.log('itemId' + itemId)
/*
The Purchase date must be in the future
*/
rp(optionsPOST1)
.then(function (parsedBody) {
Match = parsedBody.Match;
if (Match) {
console.log('Match is true');
httpRequest.post(
`${ngrokUrl}/${domain}/${orderId}`,
{
json:
{
"line_items": [
{
"line_item_id": itemId, "quantity": 1
}
]
}
},
function (error, resp, body) {
if (!error && resp.statusCode == 200) {
console.log(body)
response = responseToFrontEnd
data = [details.chatuser, response]
io.of('/main').to(socket.id).emit('response', data);
}
else {
console.log('error' + error)
}
}
)
// include getRefundCalc within here
} else {
console.log('Match is false');
response = `I'm sorry but your item fell out of the refund policy. Please check the purchase date of your item or if it falls under the minimum price.`
}
});
}
Currently the "onclick" is empty because it wasnt working, when I click on that div in this functionality.js file I want to call that function! and it has to be outside of the functionality file as it requires node modules and needs to be within the socket function!

Ajax request not aborting

I have a basic live search built with jQuery ajax which searches through a JSON file from the server and outputs a list of events.
My script is set so that if the search text box has less than 2 characters, it should display the list of the events which were already displayed on the page prior to the user using the ajax search.
var currentEvents = $(".event-list-container").contents();
if(searchField.length < 2)
{
if(currentRequest != null) {
currentRequest.abort();
}
$('.event-list-container').empty();
$('.event-list-container').append(currentEvents);
}
The issue I am having is that if the user were to quickly empty the textbox (e.g. by doing CTRL + A & backspace), the currentEvents would display and then the ajax request after that and therefore remove the currentEvents and display the results for what was in the search textbox before the user had emptied it.
Below is the full script for this:
$(document).ready(function () {
var currentEvents = $(".event-list-container").contents();
var currentRequest = null;
var searchField;
var expression;
$.ajaxSetup({
cache: false
});
$('#refine-event-txtbox').keyup(function () {
searchField = $('#refine-event-txtbox').val();
expression = new RegExp(searchField, "i");
if(searchField.length < 2)
{
if(currentRequest != null) {
currentRequest.abort();
}
$('.event-list-container').empty();
$('.event-list-container').append(currentEvents);
}
else
{
searchEvents(currentRequest, searchField, expression);
}
});
function searchEvents(currentRequest, searchField, expression)
{
currentRequest = jQuery.ajax({
type: 'GET',
url: 'http://127.0.0.1:8000/api/events',
success: function(data) {
$('.event-list-container').empty();
$.each(data, function (key, value) {
if (value.title.search(expression) != -1 ||
value.location.search(expression) !=
-1) {
var startDate = value.startDate;
var startDateDay = moment.utc(startDate).format('D');
var startDateMonth = moment.utc(startDate).format('MMM');
var fullDate = moment.utc(startDate).format('D MMM YYYY');
var eventURL = "/events/" + value.id + "/" + value.title;
eventURL = eventURL.replace(/\s+/g, '-').toLowerCase();
$('.event-list-container').append(
`<div class="event-box">
<div class="row">
<div class="col-xs-12 col-sm-2 col-md-2 col-lg-1">
<div class="date">
<p class="day">${startDateDay}</p>
<p class="month">${startDateMonth}</p>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3">
<div class="event-image">
<a href="${eventURL}">
<img class="img-responsive" src="${value.image}">
</a>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-7 col-lg-7">
<div class="event-details">
<h2 class="title">
${value.title}
</h2>
<p class="when"><span class="inline-title">When: </span>${fullDate} | ${value.startTime}-${value.finishTime}</p>
<p class="where"><span class="inline-title">Where:</span>${value.location}</p>
</div>
</div>
</div>
</div>
`);
}
});
},
error:function(e){
// Error
}
});
}});
As you can see inside the $('#refine-event-txtbox').keyup function if the search field length is set to less than 2, it should check to see if there is an ajax request and if so then abort it but the script is not doing this.
You can remove the reference of currentRequest from the function searchEvents.
Function Call:
searchEvents(searchField, expression);
And function:
function searchEvents(searchField, expression) {
.......
}
Try now..!
Figured it out. Adding the below to my ajax function as well as doing Shitole's answer seemed to do the trick.
beforeSend : function() {
if(currentRequest != null) {
currentRequest.abort();
}
},

div sort not working when div generated dynamically

I'm trying to sort a list of divs with the properties shown by particular attributes (gender, level, name etc) using the following script:
html:
<div id="sortThis" class="col-xs-12 alert-container">
<div id="1" class="container-element sortable box box-blue" data-gender="1" data-level="4" data-name="AAA"> <h3>AAA</h3><div class="panel-body">AAA is resp</div>
</div>
<div id="2" class="container-element sortable box box-pink" data-gender="2" data-level="3" data-name="DDD"><h3>DDD</h3><div class="panel-body">DDD is a s</div>
</div>
<div id="3" class="container-element sortable box box-blue" data-gender="1" data-level="2" data-name="FFF"><h3>FFF</h3><div class="panel-body">FFF has mad</div>
</div>
<div id="4" class="container-element sortable box box-pink" data-gender="2" data-level="4" data-name="CCC"><h3>CCC</h3><div class="panel-body">CCC has ma</div>
</div>
<div id="5" class="container-element sortable box box-pink" data-gender="2" data-level="2" data-name=EEE><h3>EEE</h3><div class="panel-body">EEE is a f</div>
</div>
<div id="6" class="container-element sortable box box-blue" data-gender="1" data-level="3" data-name="BBB"><h3>BBB</h3><div class="panel-body">BBB is an ou</div>
</div>
</div>
<button id="sLevel" class="LbtnSort">Sort by Level</button><br/>
<button id="sGender" class="GbtnSort">Sort by Gender</button><br/>
js:
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList);
});
when the .sortable divs are static, the sort works fine, as this jfiddle shows, however if the contents of the #sortable div (i.e. .sortable divs) are dynamically generated (in this case as the result of a form submit), when the sort button is pressed, the entire contents of the #sortable div disappears, and I can't seem to get it to work.
Any help or suggestions would be appreciated.
edit: The code for dynamic generation of the list is as follows - effectively it's an AXAX form submit that pulls data from a sorted list of items and outputs them.
$('#formStep2').submit(function(event) {
// get the form data
var studentArray = [];
$(".listbox li").each(function() {
studentArray.push({
'name': ($(this).text()),
'gender': ($(this).closest('ol').attr('id')).substr(0, 1),
'level': ($(this).closest('ol').attr('id')).substr(2, 3),
'topic': ($('input[name=topic]').val())
})
});
var studentString = JSON.stringify(studentArray);
console.log(studentString);
var formData = {
'students': studentString,
};
// process the form
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: 'process_step2.php', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true
})
// using the done promise callback
.done(function(data) {
if (!data.success) {
// error handling to go here.....
} else {
$('.alert-container').empty();
var obj = JSON.parse(data.message);
//sort the array alphabetically by name (default status)
var test = obj.sort(function(a,b){
var lccomp = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
return lccomp ? lccomp : a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
});
console.log(test);
var i=0;
test.forEach(function(st) {
console.log(st['name']);
var gen = (st['gender'] == 1) ? "blue" : (st['gender'] == 2) ? "pink" : NULL;
$('.alert-container').append('<div id="' + (i+1) + '" class="container-element sortable box box-' + gen + '" data-gender="' + st['gender'] + '" data-level="' + st['level'] + '" data-name="' + st['name'] + '"><h3>' + st['name'] + '</h3><div class="panel-body"><div class="col-xs-9"><i class="fa fa-quote-left fa-3x fa-pull-left fa-' + gen + '" aria-hidden=:true"></i>' + st['comment'] + '</div></div></div>');
i++;
});
// jump to the next tab
var $active = $('.wizard .nav-tabs li.active');
$active.next().removeClass('disabled');
nextTab($active);
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
// best to remove for production
console.log(data);
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
You are defining LdivList and GdivList inline with your code so they are defined on DOM ready. You have to wrap the definition of those inside a function and call it on click:
$(document).ready(function(){
$("button.LbtnSort").click(function() {
$("#sortThis").html(GenerateLdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GenerateGdivList());
});
});
function GenerateLdivList(){
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
}
function GenerateGdivList(){
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
}
As #theduke said, the lists are probably empty at the time you sort them. Here's a simple change that will read and sort the lists when you click the buttons instead. (Not tested.)
var LdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
};
var GdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
};
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList());
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList());
});

Show alert when I get null record using if/else statement

If record has null value then it must show alert message, code not working. Please consider the following code:
function DiseasesByName() {
var dsName = $('#dsName').val();
$.getJSON('http://54.148.253.123/edoctor/HHS_Service/HealthService.svc/DiseasesByName', {
diseaseName: dsName
}, function(data) {
var tasks = $.parseJSON(data.d);
$("#DiseasesList").empty();
$.each(tasks, function(key, value) {
if (data.d != 'null') {
$('<div data-role="collapsible" data-content-theme="a" data-collapsed="true"><h3>' + value.diseaseName +
'</h3><ul data-role="listview" id="diseaseListView" data-inset="true" data-theme="a"><li><strong>Detail:</strong><span>' + value.description + '</span></li></ul></div>').appendTo('#DiseasesList');
// refreshing collapsible created dynamically "its necessary to refresh for a jQuery look and feel"
$('div[data-role=collapsible]').collapsible({
theme: 'b',
refresh: true
});
} else {
alert('No record Found');
}
$("#clear").click(function() {
$("#DiseasesList").empty();
$("#dsName").val('');
});
});
});
}
You need to compare to null itself, not the string "null":
if(data.d!=null)
There are multiple problems
null is not a string value, so your comparison should be data.d != null
The comparison should be done out of the each loop because if data.d is not there, then there is nothing to loop through
The clear click handler should be added outside of the method as that element is not created dynamically
So
function DiseasesByName() {
var dsName = $('#dsName').val();
$.getJSON('http://54.148.253.123/edoctor/HHS_Service/HealthService.svc/DiseasesByName', {
diseaseName: dsName
}, function(data) {
//do it before the loop
var array = data.d ? JSON.parse(data.d) : [];
if (array && array.length) {
$("#DiseasesList").empty();
$.each(JSON.parse(data.d), function(key, value) {
$('<div data-role="collapsible" data-content-theme="a" data-collapsed="true"><h3>' + value.diseaseName +
'</h3><ul data-role="listview" id="diseaseListView" data-inset="true" data-theme="a"><li><strong>Detail:</strong><span>' + value.description + '</span></li></ul></div>').appendTo('#DiseasesList');
// refreshing collapsible created dynamically "its necessary to refresh for a jQuery look and feel"
$('div[data-role=collapsible]').collapsible({
theme: 'b',
refresh: true
});
});
} else {
alert('No record Found');
}
});
}
jQuery(function() {
//it should be out of the `DiseasesByName` method
$("#clear").click(function() {
$("#DiseasesList").empty();
$("#dsName").val('');
});
$('#get').click(DiseasesByName)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="dsName" />
<input id="get" type="button" value="get" />
<input id="clear" type="button" value="clear" />
<div id="DiseasesList"></div>

Categories