In the code below, I have a function counter which counts element. I use the counter function in order to count the elements that I have in the JSON file. My question is how can I get the value of the counter after the $getJSON, and why when I console log the counter outside of the brackets I keep on getting undefined, why it does not remember the last value, while if I console log the counter inside the brackets I get the number of elements in the JSON file. I want to get the number of elements so afterwards I can use that number in the for loop below.
// global variables
var c = 0;
var a;
var b;
// counter function
function counter() {
return c++;
}
// document ready function
$(document).ready(function () {
$.getJSON("https://graph.facebook.com/v3.2/...", function (data) {
var items = [];
$.each(data.data, function (i, obj) {
//$('#target').append($('<div/>', { id: 'dummy' + i }))
var text = '<p class="review_text">' + obj.review_text + '</p>'
var date = '<p class="date">' + obj.created_time + '</p>'
a = counter();
$("#carousel").find("[data-index='" + i + "']").append(text, date)
console.log(a) //here I get the number of elements inside the JSON file
});
});
console.log(a) //but if I put the console log here, I get undefined instead of the number
var wrapper = document.getElementById("carousel");
var myHTML = '';
for (b = 0; b <= a; b++) { //here I want to use what the function returns, so if I have 10 elements in the JSON file I can create 10 div elements in the HTML, it works only if I put number instead of 'a' but I want to use 'a' so I do not have to count the elements as well, the elements will increase.
myHTML += '<div id="review" data-index=' + (b) + '></div>';
}
wrapper.innerHTML = myHTML
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Move the code inside the ajax call so that it executes AFTER the data is returned/processed:
$(document).ready(function () {
$.getJSON("https://graph.facebook.com/v3.2/...", function (data) {
var items = [];
$.each(data.data, function (i, obj) {
//$('#target').append($('<div/>', { id: 'dummy' + i }))
var text = '<p class="review_text">' + obj.review_text + '</p>'
var date = '<p class="date">' + obj.created_time + '</p>'
a = counter();
$("#carousel").find("[data-index='" + i + "']").append(text, date)
console.log(a) //here I get the number of elements inside the JSON file
});
console.log(a) //but if I put the console log here, I get undefined instead of the number
var wrapper = document.getElementById("carousel");
var myHTML = '';
for (b = 0; b <= a; b++) { //here I want to use what the function returns, so if I have 10 elements in the JSON file I can create 10 div elements in the HTML, it works only if I put number instead of 'a' but I want to use 'a' so I do not have to count the elements as well, the elements will increase.
myHTML += '<div id="review" data-index=' + (b) + '></div>';
}
wrapper.innerHTML = myHTML;
});
});
Related
I have the following function on a .JS file (that I later call on an HTML file):
function writeDiv(){
x = 1
myArray.forEach(item => {
htmlText += '<div class="divsArray">';
htmlText += '<h5> Value of X: </h5>' + x;
htmlText += '</div>';
x++;
});
$('body').append(htmlText);
}
This writes me one div, with the said value of X, per entry on my array (in this case 14). What I want to do is, everytime I click on a div it shows me, through a window alert, the value of X that has been assigned to it. I tried some things but I couldn't get it to work, thanks for the help in advance!
function writeDiv() {
var temp = [100,150,200,300,400,500];
var innerHtml = "";
temp.forEach((item, index)=> {
innerHtml += `<div class="divsArray">`;
innerHtml += '<h5> Value of X: </h5><span>' + item +'</span>';
innerHtml += '</div>';
});
document.getElementsByTagName('body')[0].innerHTML = innerHtml;
}
writeDiv();
$(function() {
$('.divsArray').click(function() {
let addMoreRoomClone = $(this).find('span').html();
alert(addMoreRoomClone);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
As you're seem to use jQuery ($), I would recommend to register a live event handler.
$(document)
.on('click', '.divsArray', (event)=>{
console.log(event);
console.log(event.currentTarget.getAttribute('id'));
// do further stuff here
});
I don't know is it what you what, but here is it.
If you use some variable instead of index, it won't work, cuz when function of setTimeout works, the value of x will be same for every iteration. If you have some other questions type.
function writeDiv() {
const myArray = [15,5,5];
let htmlText = "";
myArray.forEach((item, index)=> {
htmlText += `<div id="${index}" class="divsArray">`;
htmlText += '<h5> Value of X: </h5>' + x;
htmlText += '</div>';
setTimeout(()=>{
document
.getElementById(index)
.addEventListener("click",()=>{
alert(index + 1);
})},0)
});
document.getElementsByTagName('body')[0].innerHTML = htmlText;
}
writeDiv();
i have been tasked by my senior to print values of line items using higher order functions (.filter/.map/.reject/.reduce). I m confused how to write the higher order function instead of a for loop(for printing the line values in Invoice Printout). I need to print the line only when the qty is more than 3. I m an intern and i dont know how it will work, kindly help.
Link to The code snippet: https://drive.google.com/file/d/1uVQQb0dsg_bo53fT3vk9f0G8WwZomgQg/view?usp=sharing
I always used if condition for printing the row only when the quantity field has value more than 3. I even know how to .filter but i dont know how to call it and where to call it. Please help
I don't believe Array.from works in server side code. If it does then use that. What I have been using are the following functions. They don't conform to the higher order functions specified but they work with Netsuite syntax and go a long way towards simplifying sublist handling and encapsulating code:
//SS2.x
//I have this as a snippet that can be included in server side scripts
function iter(rec, listName, cb){
var lim = rec.getLineCount({sublistId:listName});
var i = 0;
var getV = function (fld){
return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
};
for(; i< lim; i++){
cb(i, getV);
}
}
// to use it:
iter(ctx.newRecord, 'item', function(idx, getV){
if(parseInt(getV('quantity')) >3){
...
}
});
or for SS1 scripts I have the following which allows code to be shared between UserEvent and Scheduled scripts or Suitelets
function forRecordLines(rec, machName, op, doReverse) {
var i, pred, incr;
var getVal = rec ? function(fld) {
return rec.getLineItemValue(machName, fld, i);
} : function(fld) {
return nlapiGetLineItemValue(machName, fld, i);
};
var getText = rec ? function(fld) {
return rec.getLineItemText(machName, fld, i);
} : function(fld) {
return nlapiGetLineItemText(machName, fld, i);
};
var setVal = rec ? function(fld, val) {
rec.setLineItemValue(machName, fld, i, val);
} : function(fld, val) {
nlapiSetLineItemValue(machName, fld, i, val);
};
var machCount = rec ? rec.getLineItemCount(machName) : nlapiGetLineItemCount(machName);
if(!doReverse){
i = 1;
pred = function(){ return i<= machCount;};
incr = function(){ i++;};
}else{
i = machCount;
pred = function(){ return i>0;};
incr = function(){ i--;};
}
while(pred()){
var ret = op(i, getVal, getText, setVal);
incr();
if (typeof ret != 'undefined' && !ret) break;
}
}
// User Event Script:
forRecordLines(null, 'item', function(idx, getV, getT, setV){
if(parseInt(getV('quantity')) >3){
...
}
});
// in a Scheduled Script:
forRecordLines(nlapiLoadRecord('salesorder', id), 'item', function(idx, getV, getT, setV){
if(parseInt(getV('quantity')) >3){
...
}
});
Usually its a straight forward task, but since you are getting length and based on that you are iterating, you can use Array.from. Its signature is:
Array.from(ArrayLikeObject, mapFunction);
var tableData = Array.from({ length: countItem}, function(index) {
vendorBillRec.selectLineItem('item', index);
var item = vendorBillRec.getCurrentLineItemText('item', 'item');
var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
var quantity = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
return { item, description, quantity}
});
var htmlData = tableData.filter(...).map(getRowMarkup).join('');
function getRowMarkup(data) {
const { itemName, descript, quantity } = data;
return '<tr>' +
'<td colspan="6">' +
'<p>' + itemName + ' ' + descript + '</p>'+
'</td>' +
'<td colspan="2" align="right">' + quantity + '</td>' +
'</tr>';
}
Or if you like to use more functional approach:
Create a function that reads and give you all data in Array format. You can use this data for any task.
Create a function that will accept an object of specified properties and returns a markup.
Pass the data to this markup after any filter condition.
Idea is to isolate both the task:
- Getting data that needs to be processed
- Presentation logic and style related code
var htmlString = Array.from({ length: countItem}, function(index) {
vendorBillRec.selectLineItem('item', index);
var item = vendorBillRec.getCurrentLineItemText('item', 'item');
var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
var qty = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
return getRowMarkup(item, description, qty)
}).join('');
function getRowMarkup(itemName, descript, quantity) {
return '<tr>' +
'<td colspan="6">' +
'<p>' + itemName + ' ' + descript + '</p>'+
'</td>' +
'<td colspan="2" align="right">' + quantity + '</td>' +
'</tr>';
}
I am unsure why my getCereal variable id using the find("td:first").html() is not working. I have been able to create my table, however my click event will not work. I am stumped. Any input will be greatly appreciated.
<div id="cer"></div>
<script type="text/javascript">
// jQuery onClick event
// the click function MUST BE USED CANNOT BE ALTERED OR REMOVED
$(function () {
$("table tr").click(function (event) {
function getCereal(id) {
for (var cerId = 0; cerId < cereals.length; cerId++){
if(cereals[cerId].id == id){
alert(cereals[cerId].id +" " + cereals[cerId].name + " " +
cereals[cerId].like);
break;
}
}
}
var id = $(this).find("td:first").html();
getCereal(id)
// This creates an cereal constructor object
function cereal(id, name, like) {
this.id = id;
this.name = name;
this.like = like;
}
// This creates 5 new objects with cereal information.
const cereals = [
new cereal(1, 'Captain Crunch', 'Yes'),
new cereal(2, 'Frosted Wheats ', 'Yes'),
new cereal(3, 'Shredded Wheat', 'No'),
new cereal(4, 'Trix', 'No'),
new cereal(5, 'Count Chocula', 'No'),
];
var output = "<h1>Cereal Listing</h1><table><thead>"+"<tr>"+"<th>"+"Id"+"</th>"+"<th>"+"Cereal Name"+"</th>"+"<th>"+"Like?"+"</th>"+"</tr>"+"</thead>"
for (var x = 0; x < cereals.length; x++) {
output +='<tr>' + "<td>" + cereals[x].id + "</td>" +"<td>" + cereals[x].name + "</td>" + "<td>" + cereals[x].like +"</td>" + '</a>' + "</tr>";
}
output += "</table>";
document.getElementById('cer').innerHTML = output;
})
});
</script>
It's really unclear what the goal is here. Maybe this will help, consider the following code.
$(function() {
function cereal(id, name, like) {
this.id = id;
this.name = name;
this.like = like;
}
const cereals = [
new cereal(1, 'Captain Crunch', 'Yes'),
new cereal(2, 'Frosted Wheats ', 'Yes'),
new cereal(3, 'Shredded Wheat', 'No'),
new cereal(4, 'Trix', 'No'),
new cereal(5, 'Count Chocula', 'No'),
];
var output = "<h1>Cereal Listing</h1>";
output += "<table class='cereal-table'><thead>";
output += "<tr><th>Id</th><th>Cereal Name</th><th>Like?</th></tr>";
output += "</thead><tbody>";
$.each(cereals, function(k, c) {
var row = $("<tr>", {
"data-c-id": k
});
$("<td>").html(c.id).appendTo(row);
$("<td>").html(c.name).appendTo(row);
$("<td>").html(c.like).appendTo(row);
output += row.prop("outerHTML");
});
output += "</tbody></table>";
$("#cer").html(output);
$(".cereal-table").on("click", "tr", function(e) {
var cId = parseInt($(this).data("c-id"));
console.log("Row C-ID: " + cId);
var data = "";
data += "ID: " + cereals[cId].id;
data += ", Name: " + cereals[cId].name;
data += ", Like: " + cereals[cId].like
alert(data);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cer"></div>
Since jQuery is a JavaScript Framework, you can mix and match both, yet I try to remain in one or the other. This is all in jQuery.
The function creates an Object. You have 5 objects in an Array and we're going to iterate the Array using $.each(). This is a functioned designed for this. See:
jQuery.each()
Each Object has parameters we can call and insert into the Table Cell elements <td>. jQuery give us the ability to quickly create elements as jQuery Objects: $("<td>").
Since the goal appears to be to create an output string of HTML text, we can convert all the jQuery Objects we've create into HTML by asking for the outerHTML property.
The result of running the code is:
<h1>Cereal Listing</h1><table><thead><tr><th>Id</th><th>Cereal Name</th><th>Like?</th></tr></thead><tbody><tr><td>1</td><td>Captain Crunch</td><td>Yes</td></tr><tr><td>2</td><td>Frosted Wheats </td><td>Yes</td></tr><tr><td>3</td><td>Shredded Wheat</td><td>No</td></tr><tr><td>4</td><td>Trix</td><td>No</td></tr><tr><td>5</td><td>Count Chocula</td><td>No</td></tr></tbody></table>
Once the table is constructed and outputted, you can bind a click event to the Row with .on() or .click(). I advise the .on() since it more tolerate of dynamic content.
We bind the click event to each row and then collect the data from the row and create an alert.
Hope this helps.
I'm very new to this, and I was hoping to get some clarity in this:
Whenever I run this code (PS: boardGames, is an array in a separate doc) It seems to work, but the first answer is always "undefined". Why is that? and how can I fix it?
Thanks!
var message;
var games;
var search;
var i;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function gamestoPlay( games ) {
var topGames = '<h3> Game: ' + boardGames[i].name +'</h3>';
topGames += '<p> Minimum Players: ' + boardGames[i].idealMinPlayers + '</p>';
topGames += '<p> Maximum Players: ' + boardGames[i].idealMaxPlayers + '</p>';
return topGames
}
search = parseInt(prompt('How many people are coming?'));
for (i = 0; i < boardGames.length; i += 1) {
games = i;
if ( search >= boardGames[i].idealMinPlayers && search <= boardGames[i].idealMaxPlayers) {
message += gamestoPlay();
print(message);
}
}
Because you didn't initialize message.
When you do
message += gamesToPlay();
it first has to convert message to a string so it can concatenate to it. Since you didn't initialize message, its value is undefined, and when this is converted to a string it becomes "undefined", and then the result of gamesToPlay() is concatenated to that.
Change the initialization to:
var message = "";
I have a problem when trying to store the results of a select query into an array with java script .
the problem is that inside the function the array is containing the right values but outside it's empty , even when i used a global var it's still empty !!!
db.transaction(function (transaction) {
var sql = "SELECT * FROM Question where idEnq=" + idEn;
transaction.executeSql(sql, undefined, function (transaction, result) {
var res = document.getElementById('results');
res.innerHTML = "<ul>";
if (result.rows.length) {
for (var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
ch[i] = new qu(row.id, row.text, row.type);
res.innerHTML += '<li>' + row.id + ' ' + ch[i].text + ' ' + ch[i].type + '</li>';
}
tablo = ch;
} else {
alert("No choices");
res.innerHTML += "<li> No choices </li>";
}
res.innerHTML += "</ul>";
}, onError);
}); // here the ch and the tablo array are empty
You are using asynchronous functions. Anything that wants to use the data "returned" by those functions need to be in the callback. Of course you can assign this data e.g. to a global variable, but that variable will only have the value after the callback has run (asynchronously).
you're new so have look here http://pietschsoft.com/post/2008/02/JavaScript-Function-Tips-and-Tricks.aspx
there's a part talking about calling JavaScript Function asynchronously