I've been trying to make an RSS reader with JQuery and javascript, but it turns out that javascript doesn't wait for jquery to end before continuing, causing the some registrations to fail.
The console.logs of the example show that the logs of the jquery function are showing up after the logs of the common javascript. This causes the result of the function to change, because it depends on the jquery function.
I'd like to know how to make javascript wait for jquery to end before continuing. The idea is that all of the process marked with ** occur before the "after the calling" log
Here are the logs and the code. Thank you for your help
----Before the calling
**Calling a check_feed
**was there activity: false
----After the calling
----variable result: noact
**judging item0
**hora vs ult_act: 1480805684 > 1480798209 = true
**New message from coyoteazul
**judging item1
**hora vs ult_act: 1480766258 > 1480798209 = false
**judging item2
**hora vs ult_act: 1480743686 > 1480798209 = false
** SHOWS A NOTIFICATION
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
function caller(){
console.log("----Before the calling")
var result = check_Feed("https://www.neobux.com/rss/?/601750/", 1480798309)
console.log("----After the calling")
console.log("----variable result: " + result)
}
function check_Feed (FEED_URL, ult_act){
ult_act = parseInt(ult_act)
console.log("**Calling a check_feed")
var titul;
var contador = 0;
var actividad = false;
$.get(FEED_URL, function (data) {
titul = $(data).find("title").first().text();
if (titul == "") {return "F"} //el titulo solo puede estar vacio si el feed esta cerrado
$(data).find("item").each(function () {
console.log("**judging item" + contador)
if (contador < 7){
var el = $(this);
var hora = el.find("pubDate").text()
hora = new Date(hora).getTime()/1000;
console.log("**hora vs ult_act: " + hora + " > " + (ult_act-100) + " = " + (hora > (ult_act-100)))
if (hora > (ult_act-100)){ //solo notifica si la hora supera a la ultima activdad.
var cuerpol = el.children().last().text();
cuerpol = "New message from " + cuerpol;
var linkl = el.find("link").text();
console.log("**"+cuerpol)
setTimeout(function(){ //en firefox si no se muestran a traves de un timeout solo mostrara la 1er notificacion
console.log("** SHOWS A NOTIFICATION");}, 500 * (contador+1))
actividad = true;
}
contador ++;
}
});
});
console.log("**was there activity: " + actividad);
if (actividad)
return "act";
else
return "noact";
}
caller()
A few things before you try out the code below:
jQuery get/post are simple ajax calls that run asynchronously. To
understand them you may start
here
setTimeout also works out in a similar fashion , in essence it executes a function once the time specified elapses.
Try running this code to see the results in the order you are expecting
function caller() {
console.log("----Before the calling")
check_Feed("https://www.neobux.com/rss/?/601750/", 1480798309);
thisGetsPrintedRightAfter();
}
thisGetsCalledAfterEverything = function(result) {
console.log("----After the calling")
console.log("----variable result: " + result)
}
thisGetsPrintedRightAfter = function() {
console.log("This gets printed right after Calling a check_feed");
}
function check_Feed(FEED_URL, ult_act) {
ult_act = parseInt(ult_act)
console.log("**Calling a check_feed")
var titul;
var contador = 0;
var actividad = false;
$.get(FEED_URL, function(data) {
titul = $(data).find("title").first().text();
if (titul == "") {
return "F"
} //el titulo solo puede estar vacio si el feed esta cerrado
$(data).find("item").each(function() {
console.log("**judging item" + contador)
if (contador < 7) {
var el = $(this);
var hora = el.find("pubDate").text()
hora = new Date(hora).getTime() / 1000;
console.log("**hora vs ult_act: " + hora + " > " + (ult_act - 100) + " = " + (hora > (ult_act - 100)))
if (hora > (ult_act - 100)) { //solo notifica si la hora supera a la ultima activdad.
var cuerpol = el.children().last().text();
cuerpol = "New message from " + cuerpol;
var linkl = el.find("link").text();
console.log("**" + cuerpol);
setTimeout(function() { //en firefox si no se muestran a traves de un timeout solo mostrara la 1er notificacion
console.log("** SHOWS A NOTIFICATION");
console.log("**was there activity: " + actividad);
if (actividad)
thisGetsCalledAfterEverything("act");
else
thisGetsCalledAfterEverything("noact");;
}, 500 * (contador + 1));
actividad = true;
}
contador++;
}
});
});
}
caller()
Related
the code below must display a table as represented the top the buttons must be present and once I click on the button an underlying text is displayed, the problem is that if you click on the last button the buttons at the top remain fixed, if I click on another button the buttons at the top are shown at the bottom, I assume it is a jquery problem I see to report the screens below to better explain the problem.
React Code:
private AppendButtonsPeoplePicker() {
// Email
let inputEmail: JQuery<HTMLInputElement> =
this.Fields.TxT_RichiedenteEmail.find("input");
const labelEmail =
this.Fields.TxT_RichiedenteEmail.closest("tr").find("nobr")[0].innerText;
this.BuildButtonForPeoplePicker(
inputEmail,
TicketConstants.RichiedenteEmail,
labelEmail
);
// CC
let inputCC: JQuery<HTMLInputElement> = this.Fields.TxT_CC.find("input");
const labelCC = this.Fields.TxT_CC.closest("tr").find("nobr")[0].innerText;
this.BuildButtonForPeoplePicker(inputCC, TicketConstants.CC, labelCC);
// CCN
let inputCCN: JQuery<HTMLInputElement> = this.Fields.TxT_CCN.find("input");
const labelCCN =
this.Fields.TxT_CCN.closest("tr").find("nobr")[0].innerText;
this.BuildButtonForPeoplePicker(inputCCN, TicketConstants.CCN, labelCCN);
//Recupero la lista delle risposte
try {
// Recupero l'id del ticket
let idTicket: string = localStorage.getItem("IdTicket");
// Ricava da SharePoint le risposte relative al ticket.
// Non prende in considerazione la risposta con il flag Bozza attivo.
let context: SP.ClientContext = SP.ClientContext.get_current();
let web: SP.Web = context.get_web();
let list: SP.List = web
.get_lists()
.getByTitle(RisposteConstants.ListTitle);
let query: SP.CamlQuery = new SP.CamlQuery();
query.set_viewXml(`
<View>
<Query>
<Where>
<And>
<Eq>
<FieldRef Name="${RisposteConstants.Ticket}" LookupId="TRUE" />
<Value Type="Lookup">${idTicket}</Value>
</Eq>
<Or>
<IsNull>
<FieldRef Name="${RisposteConstants.Bozza}" />
</IsNull>
<Eq>
<FieldRef Name="${RisposteConstants.Bozza}" />
<Value Type="Boolean">0</Value>
</Eq>
</Or>
</And>
</Where>
<OrderBy>
<FieldRef Name="ID" Ascending='True'></FieldRef>
</OrderBy>
</Query>
</View>`);
let itemsColl: SP.ListItemCollection<RisposteListItem> =
list.getItems(query);
context.load(itemsColl);
context.load(web);
$(".ms-formtable").append("<br> </br><div class='tabcontents'> <table>");
// Recupero la url del sito per configurare il download dei file allegati
var site = context.get_site();
context.load(site, "Url");
context.executeQueryAsync(
async function () {
var oListItemEnumerators = itemsColl.getEnumerator();
var i = 1;
while (oListItemEnumerators.moveNext()) {
let item = oListItemEnumerators.get_current();
var value = item.get_item("Risposta");
var ValueID = item.get_item("ID");
// Recupero l'autore del file
var Authorstring = item.get_item("Author");
var created = item.get_item("Created");
var Author =
Authorstring.get_lookupValue() + " " + created.toLocaleString();
let button = $(
"<td> <button class='call-btn'>Risposta " + i + "</button> "
);
$(".tabcontents").append(button);
var id = "container-ticket" + i;
// Aggiungo la risposta in append nascondendola di default
let risposta = $(
"<div id=" +
id +
" class='container-ticket' name='review' rows='4' cols='100'>" +
Author +
"\n\n" +
value +
"</div> </td>"
);
// Nascondo la risposta
risposta.hide();
// Append container allegati
var attachmentFiles = item.get_attachmentFiles();
context.load(attachmentFiles);
// Esecuzione della query
await new Promise((resolve, reject) => {
context.executeQueryAsync(
() => {
if (attachmentFiles.get_count() > 0) {
var attachmentsItemsEnumerator =
attachmentFiles.getEnumerator();
while (attachmentsItemsEnumerator.moveNext()) {
var attachitem = attachmentsItemsEnumerator.get_current();
var fileName = attachitem.get_fileName();
//Costruisco la url per il download dei file url server di test https://webapptest.regione.emilia-romagna.it/app/erri
var urlfile =
site.get_url() +
"/gestione/Lists/Risposte/Attachments/" +
ValueID +
"/" +
fileName;
//Ora inserisco la url del file in append per scaricare il file
risposta.append(
"<br> <a href=" +
urlfile +
">" +
fileName +
"</a> </br>"
);
}
} else {
console.log("Nessun allegato");
}
resolve(null);
},
(sender: any, args: SP.ClientRequestFailedEventArgs) => {
console.log(
`Fallita la query su SharePoint per la ricerca degli allegati della risposta (id ticket: ${idTicket} - id risposta: ${ValueID})`,
sender,
args.get_message(),
args.get_stackTrace()
);
reject();
}
);
});
$(".tabcontents").append(risposta);
button.click(function (evt) {
evt.stopPropagation();
evt.preventDefault();
$(".container-desc").hide();
$(".container-ticket").hide();
$(".tab button.selected").removeClass("selected");
button.addClass("selected");
risposta.show();
return false;
});
i++;
}
},
function (sender: any, args: SP.ClientRequestFailedEventArgs) {
console.log(
`Fallita la query su SharePoint per la ricerca delle risposte del ticket (id ticket: ${idTicket})`,
sender,
args.get_message(),
args.get_stackTrace()
);
}
);
$(".tabcontents").append("</table></div>");
} catch (err) {
console.log("Errore: " + err);
}
}
I have this program that as soon as it starts up, it asks you to enter the number of books that you want to register in the program and the number of authors that each book will have.
The program will ask you to register a name for each author, surname, age and nationality.
Once this is done, there is a button that shows all the books registered with their authors and the data of the books, and I have the problem that I am not able to show the data of the authors since only [object Object] appears.
Edit:
I have managed to print the element.autores by console.log, without the error obejct object appearing but I am not able to get it out through a document.write or something similar, here I leave a screenshot of how it should appear:
And if I try to put elements.autores.nombre to print only the name, it appears undefined both in the console.log and in the document.write
Here my code:
javascript:
var biblioteca = new Array();
function libro(titulo, autores, anyo, editorial) {
this.titulo = titulo;
this.autores = autores;
this.anyo = anyo;
this.editorial = editorial;
}
function autor(nombre, apellidos, edad, nacionalidad) {
this.nombre = nombre;
this.aepellidos = apellidos;
this.edad = edad;
this.nacionalidad = nacionalidad;
}
window.onload = function () {
document.getElementById("mostrar").onclick = Mostrar;
document.getElementById("insertar").onclick = insertarlibro;
document.getElementById("insertar").onclick = insertarautor;
}
function insertarlibro() {
var autores = new Array();
var titulo = prompt("Insertar el nombre del titulo del libro");
var anyo = parseInt(prompt("Año"));
var editorial = prompt("Inserta su editorial");
var numautores = parseInt(prompt("Cuantos autores vas a insertar"));
for (let i = 0; i < numautores; i++) {
let autor = insertarautor();
autores.push(autor);
}
var registrohecho = new libro(titulo, autores, anyo, editorial);
return registrohecho;
}
console.log(insertarlibro);
function insertarautor() {
var nombre = prompt("Insertar el nombre del autor").toUpperCase();
var apellidos = prompt("Insertar el apellidos del autor").toUpperCase();
var edad = parseInt(prompt("Edad"));
var nacionalidad = prompt("¿De que pais es el autor?");
var registrohecho = new autor(nombre, apellidos, edad, nacionalidad);
return registrohecho;
}
console.log(insertarautor);
var numlibros = parseInt(prompt("Cuantos libros vas a insertar"));
for (let i = 0; i < numlibros; i++) {
var insertalibro = insertarlibro();
biblioteca.push(insertalibro);
}
function Mostrar() {
biblioteca.forEach(element => {
console.log("Error" + JSON.stringify(element.autores));
var muestra = "Nombre del libro:" + element.titulo + " autores: " + element.autores + " Año en el que se publico: " + element.anyo + " Editorial: " + element.editorial;
document.write(muestra);
});
}
And the html part:
<div id="insertar">
<input type="button" value="Insertar">
</div>
<div id="mostrar">
<input type="button" value="Mostrar">
</div>
You are trying to get element.autores, which is an array. To get e.g. get the nombre, you wold have to acces it with element.autores[0].nombre.
So your code to output all books (with authors) would be something like this:
biblioteca.forEach(element => {
var muestra = "Nombre del libro:" + element.titulo + " autores: ";
element.autores.forEach(author => {
muestra += `nombre: ${author.nombre}, aepellidos: ${author.aepellidos}, edad: ${author.edad}, nacionalidad: ${author.nacionalidad} `;
})
muestra += "Año en el que se publico: " + element.anyo + " Editorial: " + element.editorial;
document.write(muestra);
});
I take the opportunity to ask two things, the first I want to alphabetically order a phrase that the user previously writes but for some reason it does not finish printing the result, the second is to read the phrase and indicate if there is any repeated word and how many times it is repeated and show it On the screen of course, I wanted to do it with a function but I don't know how to put one function inside another:
Here I attach code:
var Miventana;
function AbrirVen() {
//ventana secundaria
/* pondra la ventana en el centro de la pantalla; sin importar la resolución que esté utilizando el equipo cliente.
Las variables A y H darán el tamaño a la ventana.*/
var Ancho = screen.width;
var Alto = screen.height;
var A = Ancho*50/100;
var H = Alto*50/100;
var difA = Ancho - A;
var difH = Alto - H;
var tope = difH/2;
var lado = difA/2;
var Opciones="status=no, menubar=no, directories=no, location=no, toolbar=no, scrollbars=yes, resizable=no, width="+A+", height="+H+", top="+tope+", left="+lado+"";
Miventana = open("página que vas a abrir","_blank",Opciones);
var frase = document.getElementById("frase").value;
var palabras = frase.split(" ");
var primerapalabra = palabras[0];
var ultimapalabra = palabras[palabras.length-1];
var ordenLongitud = frase.slice();
Miventana.document.write(`Primera palabra: ${primerapalabra}`,"<br>");
Miventana.document.write(`Última palabra: ${ultimapalabra}`);
var numNom = frase.length;
Miventana.document.write("</br> Tu frase tiene " + numNom + " palabras </br>");
frase.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
ordenLongitud.sort(function(a, b) {
return a.length - b.length
});
Miventana.document.getElementById("letras").innerHTML = 'Alfabetico: ' + frase + '<br>Longitud: ' + ordenLongitud;
function checkString(text,index){
if((text.length - index)==0 ){ //stop condition
return false;
}else{
return checkString(text,index + 1)
|| text.substr(0, index).indexOf(text[index])!=-1;
}
}
for(var frase in texts){
var text = texts[frase].split("");
Miventana.document.write(text + " -> " + text.some(function(v,i,a){return a.lastIndexOf(v)!=i;}) +"<br/>");
}
}
I want to alphabetically order a phrase that the user previously writes but for some reason it does not finish printing the result
You're sorting the wrong variable. You should sort the palabras variable, which is an array containing the splitted words rather than frase, which is the string.
var Miventana;
function AbrirVen() {
// [...]
var frase = document.getElementById("frase").value;
var palabras = frase.split(" ");
var primerapalabra = palabras[0];
var ultimapalabra = palabras[palabras.length-1];
var ordenLongitud = frase.slice();
Miventana.document.write(`Primera palabra: ${primerapalabra}`,"<br>");
Miventana.document.write(`Última palabra: ${ultimapalabra}`);
var numNom = frase.length; // <<< this should be palabras.length (not `frase`)
Miventana.document.write("</br> Tu frase tiene " + numNom + " palabras </br>");
frase.sort(function (a, b) { // <<< again you should sort palabras
return a.toLowerCase().localeCompare(b.toLowerCase());
});
// [...]
}
the second is to read the phrase and indicate if there is any repeated word and how many times it is repeated and show it
You could do that by using an object which holds the counts for each word (I took that approach from How to count duplicate value in an array in javascript):
var counts = {};
palabras.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
for (k in counts) {
if (counts[k] > 1) {
// Show the output however you like
console.log(`Word '${k}' appears ${counts[k]} times`)
}
}
Finally:
I wanted to do it with a function but I don't know how to put one function inside another
There's no problem at all with defining a function inside another function. We could take the counting lines above, abstract them into a function and just call it from AbrirVen():
var Miventana;
function AbrirVen() {
// [...]
var frase = document.getElementById("frase").value;
var palabras = frase.split(" ");
// [...]
function displayCounts(words_to_be_counted) {
var counts = {};
words_to_be_counted.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
for (k in counts) {
if (counts[k] > 1) {
// Show the output however you like
console.log(`Word '${k}' appears ${counts[k]} times`)
}
}
}
displayCounts(palabras)
// [...]
}
this code is from a cart of a music store I have made. The problem is that I need to check if the quantity I choose in the cart is in available in the stock. It works but if the user changes the quantity in the input number, the button pagar(pay) doesnt work. If I reaload the page it works but I need to do it without reload. The code:
$("#pagar").click(function() {
var tt_precio = $("#t_compra").text();
//solo cojo el precio tt y le quito el €;
var tt_precio = tt_precio.split(" ")[4];
var tt_precio = tt_precio.slice(0, -1);
var precios = [];
var fecha = new Date();
var date =
fecha.getFullYear() +
"/" +
Number(fecha.getMonth() + 1) +
"/" +
fecha.getDate();
$("[id*=precios]").each(function() {
var p = $(this)
.text()
.slice(0, -1);
precios.push(p);
});
var cantidades = [];
$("[type = number]").each(function() {
cantidades.push(Number($(this).val()));
});
var referencias = [];
$("[id*=referencias]").each(function() {
referencias.push($(this).text());
});
var nombres = [];
$("[id*=nombres]").each(function() {
nombres.push($(this).text());
});
var datos = {
precios: JSON.stringify(precios),
cantidades: JSON.stringify(cantidades),
referencias: JSON.stringify(referencias),
nombres: JSON.stringify(nombres),
tt_precio: tt_precio,
fecha: date
};
$.ajax({
type: "post",
data: datos,
url: "compra.php",
success: function(vuelta) {
alert(vuelta);
window.location.href = "/AccesoDatos/index.php";
}
});
});
$("seguir")
//cambiar precios
$("input").change(function() {
var valor = $(this).val();
var id = $(this).attr("id");
//para eliminar el simbolo del €
var precio = $("#precios" + id)
.text()
.slice(0, -1);
var datos = {
cantidad: valor,
referencia: id,
precio: precio
};
$.ajax({
type: "post",
data: datos,
url: "modificarCantidades.php",
success: function(datos) {
if (datos == -1) {
$("#span" + id).html("No hay suficientes unidades");
} else {
if (datos == 0) {
$("#fila" + id).remove();
$("#t_compra").html("0€");
$("#precio").html("0");
} else {
$("#span" + id).html("");
var precio = $("#precios" + id)
.text()
.slice(0, -1);
var cantidad = datos;
var total = precio * cantidad;
$("#total" + id).text(total + "€");
//alert(total);
var total_precio = 0;
var total_Cantidad = 0;
// coge todos los elementos que contienen en el id la palabra total y suma su valor
$("[id*=total]").each(function() {
var p = Number(
$(this)
.text()
.slice(0, -1)
);
total_precio += p;
});
//coge los inputs number para sumarlos
$("[type = number]").each(function() {
var c = Number($(this).val());
total_Cantidad += c;
});
//meto los valores nuevos en su sitio; --> en ajax hay que modificar el array de sesiones.
$("#unidades").html(total_Cantidad);
$("#precio").html(total_precio);
$("#t_productos").html(
"<strong>Total productos:</strong>" + total_Cantidad + "UDS"
);
$("#t_compra").html(
"<strong>Total de la compra:</strong>" + total_precio + "€"
);
}
}
}
});
});
It work clicking a button the first one and changing some input type="number", the problem is that if I use the onChange function, then I need to pay the updated cart but it is not posible because the button pay function doesn't work, I dont know why, I've tested whit an alert() at the top of the function, just below the call and it works but doesnt happend from there.
Change the below function:
$("input").change(function() {
For input field types change trigger function should not be used, try changing it with keyup function with 5 sec delay.
That might can help you out.
I have done something similar to this while you can use after doing some changes into it according to your need:-
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 2000; //time in ms, 5 second for example
var $input = $('#user_name');
//on keyup, start the countdown
$input.on('keyup', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$input.on('keydown', function () {
clearTimeout(typingTimer);
});
I've solved it, the problem was that the variable tt_precio was not set, when I click the button it does nothing because I dont update that value
im using JSON to parse some data from MYSQL, but in order to bring all the information in just one call i´m tring to stored everything in JAVASCRIPT OBJECTS(works fine), the problem is i don`t know how can i use with JQUERY to fill in some divs and integrated the info of the objects with different functions. this is how i worked:
// SE DEFINE CADA OBJETO QUE RECIBE INFO DE CADA CAMPO DE BD
//PLATO
function PlatoBD(nombreplato , descripcion, caloriasTortilla, precio, ingredientes)
{
this.nombreplato = nombreplato;
this.descripcion = descripcion;
this.caloriasTortilla = caloriasTortilla;
this.precio = precio;
this.ingredientes = function(adiciones , NomPlato){
peticionBD(adiciones , NomPlato);
}
}
//ADICION
function AdicionBD(nombreAdicion , calXplato, tipoAdicion)
{
this.nombreAdicion = nombreAdicion;
this.calXplato = calXplato;
this.tipoAdicion = tipoAdicion;
}
//SE DEFINE LA FUNCION PARA LLAMAR CUALQUIER BASE DE DATOS
function peticionBD(peticionBDJSON,NomPlato){
$.post('php/consulta-actualizar-info.php',
{"peticionBD" :peticionBDJSON }
,
function(data) {
var infophpData = $.parseJSON(data);
if (peticionBDJSON == "menuElpaso") {
ingred = new Array();
for (var i = 0; i < infophpData.length; i++) {
window["plato_"+infophpData[i]["plato"].replace(' ','_')] = new PlatoBD(infophpData[i]["plato"] , infophpData[i]["descripcion"] , infophpData[i]["caloriasTortilla"] , infophpData[i]["precio"]);
window["plato_"+infophpData[i]["plato"].replace(' ','_')].ingredientes("adiciones",infophpData[i]["plato"].replace(' ',''))
};
};
if (peticionBDJSON == "adiciones") {
else if (NomPlato =="Burritoveggy")
{
for (var i = 0; i < infophpData.length; i++) {
window["adicionesPara"+NomPlato+"De"+infophpData[i]["adicion"].replace(" ","_")] = new AdicionBD(infophpData[i]["adicion"] , infophpData[i][NomPlato], infophpData[i]["tipoAdicion"]);
};
}
else if (NomPlato =="Quesadilla")
{
for (var i = 0; i < infophpData.length; i++) {
window["adicionesPara"+NomPlato+"De"+infophpData[i]["adicion"].replace(" ","_")] = new AdicionBD(infophpData[i]["adicion"] , infophpData[i][NomPlato], infophpData[i]["tipoAdicion"]);
};
}
...
};
}).error(
function(){
alert('Error al ejecutar la petición');
},
'json'
)
}
$(document).ready(function($){
peticionBD("menuElpaso","")
});
the response result is(http://wedesign-medellin.com/restaurante-elPaso/objeto-bd-domicilios.html):
PlatoBD {nombreplato: "Almuerzo", descripcion: "Sopa + elecciones + gaseosa", caloriasTortilla: "250", precio: "14.000", ingredientes: function}
Use jQuery.parseJSON(string_object)