javascript looping through 2d array - javascript

I am trying to work through how to publish items from multiple arrays while first searching through the separate array elements and then return only those items which match a certain criteria. The following code does not do this yet.
enter code here<div id="myDiv">
<script type="text/javascript">
var $ = function(id) {
return document.getElementBuId(id);
}
var title = new Array("Barbecuing in the Rain","Picnicing in the Arctic",
"How to Saute on a Radiator", "A Real Grasshopper: Bartending with Insects",
"Food with a Bullet: Cooking in Camden", "Mirepoix for Dummies");
var price = new Array(18.50, 23.95, 41.95, 5.95, 13.00, 99.00);
var binding = new Array("Hardcover", "Paperback", "Hardcover", "Paperback", "Paperback", "Hardcover");
var pubYear = new Array(2002, 1975, 2004, 2006, 2001, 1997);
var NYTBestSeller = new Array(true, true, false, false, true, true)
var seriesTitle = new Array("Food Network", "The Food Network",
"Culinary Shortcuts", "Sunset Libations",
"Food Network", "The Food Network");
var bargainBooks = ("Food Network Hot Selling Bargain Book");
for (i in title) {
if (((price[i] <= 25 && binding[i] == "Hardcover") ||
(price[i] <= 15 && binding[i] == "Softcover")) && (pubYear[i] >= 2000) &&
(NYTBestSeller[i] == true) && (seriesTitle[i] == "Food Network") || (seriesTitle[i] == "The Food Network"))
//document.write("<span color='red'>This line is red</span>");
document.write(title[i] + "<br />");
document.write(price[i] + "<br />");
document.write(binding[i] + "<br />");
document.write(pubYear[i] + "<br />");
document.write(NYTBestSeller[i] + "<br />");
document.write(seriesTitle[i] + "<br />" + "<hr/>");
}
</script>
I am searching for books that met a certain criteria and then trying to output where that book is on the page a message of Hot Selling Book in green. But I can't figure out how to make the document.write work. document.write().style.color="green" does not work.

document.write output text only, you have to write your own tags there (a div styled as green for example).
However I suggest you a different approach, what about an empty div with an id and then do the following:
document.getElementById('your-div-id').innerHTML = 'text <br /> <span style="color: green;">other text</span> and so on';
Will also reorganize code in a better way.
Document.write will only append code to the end of the output stream (the document in this case), so you can't specify where output will appear.
Edit 1:
Also, what about using objects in this case? As far as I can see, you are using arrays to emulate their behaviour:
var myObjArray = [
{
title: 'mytitle1',
price: '10$',
binding: 'dunno',
pubYear: 'dunno-again',
NYTBestSeller: true,
seriesTitle: 'Something'
},
{
...other object data...
}
]
document.getElementById('your-div-id').innerHTML += myObjArray[0].title + '<br />' + myObjArray[0].price;
Hope you can find it interesting

Related

uncaught TypeError: cannot set property "innerHTML" of null at populate (app.js:13) at app.js:55

uncaught TypeError: cannot set property "innerHTML" of null
at populate (app.js:13)
at app.js:55
I entered this code watching a video on youtube from beginning to end:
https://www.youtube.com/watch?v=jvk1pFNqXaw&t=293s
heres a link to my repo with everything you'll need to copy, paste, run to see what im facing right now:
function populate() {
if(quiz.isEnded()) {
//show scores//
} else {
// show question
var element = $("#question");
element.innerHTML = quiz.getQuestionIndex().text;
// show choices
var choices = quiz.getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var elementChoice = document.getElementById("choices" + i);
elementChoice.innerHTML = choices[i];
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populate();
};
}
function showProgress() {
var currentQuestionNumber = quiz.questionIndex + 1;
var elementProg = $("#progress");
elementProg.innerHTML = "Question " + currentQuestionNumber + "of " +
quiz.questions.length;
}
function showScores() {
var gameOverHtml = "<h1>Result</h1>";
gameOverHtml += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
var elementQuiz = $("#quiz");
elementQuiz.innerHTML = gameOverHtml;
}
var questions = [
new Question("What famous Mathematitian developed a sequential formula
for the Golden Ratio (Phi)?", ["Issac Newton","Albert Einstein","Leonardo
Bigollo","Copernicus"], "Leonardo Bigollo"),
new Question("Who saved Apple from going bankrupt in the '90s?",
["Michael Dell", "Bill Gates", "Mark Cuban", "Warren Buffet"], "Bill
Gates"),
new Question("Though PHP may appear to look simpler than javascript,
why is js the top scrtipting language?", ["Gives instant-feedback", "It's
less vulnerable to breach", "Much more control without interferring with
bandwith", "All reasons shown!"], "All reasons shown!"),
new Question("What is the Golden Ratio?", ["1.618", "5.1", "0.618",
"0.3218"], "1.618"),
new Question("People get shocked when they see PHI is in every great
picure they see, what's an easy way to tell where phi is?", ["Look for the
embeded Greek letter, phi.", "Look at the center of the image, youll notice
that key elements are just slightly off-center.", "console.log to find it",
"take out a ruler and measure for it."], "Look for the embedded Greek
letter, phi.")
];
var quiz = new Quiz(questions);
populate();
I'm hoping to get some clarity as to why the code wont work even after following a video start to end 3x just to double check....
I have until 5pm 7/25/2019 (today) to finish this!
please help!
also i never knew you can split js into multiple files instead of killing yourself all in one...so that was cool to find out tonight...woulda saved me the past 5 days of headaches but i love this and learning how to do it!
Change document.getElementById("choices" + i) to document.getElementById("choice" + i)
choices should be choice :)

add content to marquee every

how can i update content in marquee every 20 second using javascript?
i mean , in the first 20 seconds he reads the first object , on second 40 reads the second object and so on .. , without updating the page , mean update it automatically
this is the javascript function :
function read () {
$.getJSON("jsons/jobs.json", function(json) {
Thejobs = json;
for(var k in Thejobs.Studies){
$('#boxContent').append('<br>'+"position: "+Thejobs.Studies[k].position+
'<br>'+"Academy: "+Thejobs.Studies[k].academy+'<br>'+"address: "
+Thejobs.Studies[k].address+'<br>'+"Description: "+Thejobs.Studies[k].jobDescription)
$('#boxContent').append("<br>_____________________");
}}); }
this is my json file :
{"Studies": {
"jobID1": {
"position": "student position",
"academy": "Haifa University",
"address": "haifa,isreal",
"jobDescription": "Big data"
},
"jobID2": {
"position": "Research 1",
"academy": "saarland University",
"address": "saarbrucken , germany",
"jobDescription": "Electronic engineer"
},
"jobID3": {
"position": "Studie 1",
"academy": "Technion",
"address": "haifa,isreal",
"jobDescription": "Speed of internet"
},
"jobID4": {
"position": "Studie 2",
"academy": "Technion",
"address": "USA ,los angeles",
"jobDescription": "analysis data "
}
}
}
html file :
<marquee direction="up" scrollamount="2">
<p id="boxContent"></p>
</marquee>
i've tried this but didn't work:
<script>
var myVar = setInterval(joobs(), 20000);
var ii=0;
function joobs(){
$.getJSON("jsons/jobs.json", function(json) {
Thejobs = json;
$('#boxContent').append('<br>'+"position:
"+Thejobs.Studies[ii].position+
'<br>'+"Academy: "+Thejobs.Studies[ii].academy+'<br>'+"address: "
+Thejobs.Studies[ii].address+'<br>'+"Description:
"+Thejobs.Studies[ii].jobDescription)
$('#boxContent').append("<br>_____________________");
});
ii=ii+1;
</script>
I couldn't resist making this abomination.
If you need to do something at a regular interval, use setInterval. Which has the signature setInterval(callback_function, interval_in_milliseconds); Just put your function to change the value of the marquee as the callback and set the interval to 20000 to delay for 20 seconds. Your function will be called every 20 seconds like in my following example.
var values = ["Marquees", "shall", "never", "die.", "Long", "live", "the", "marquee!"];
var iterator = 1;
var colorator = 0;
function updateMarquee() {
document.getElementById('boxContent').innerHTML = values[iterator];
iterator = (iterator + 1) % values.length;
console.log("updateMarquee() has been called");
return function() {
console.log("updateMarquee() return value was called instead of the function");
};
}
setInterval(updateMarquee, 1000);
setInterval(updateMarquee(), 10000);
<marquee direction="right" scrollamount="10" behavior="alternate">
<p id="boxContent">Marquees</p>
</marquee>
Update: In regard to user78403's answer, I've updated my code snippet to show the difference between calling the function itself in a setInterval and calling a functions return value. In the example you will see updateMarquee() has been called logged every second because of the line setInterval(updateMarquee, 1000);. But you will also see updateMarquee() return value was called instead of the function logged every 10 seconds because of the line setInterval(updateMarquee(), 10000);
P.S. Don't use a marquee. Having anything automatically moving, playing, changing on a website might have been mind-blowing 20 years ago, but now its just annoying and users will look down on your site for it. You should just have a static list of your job offerings that users can read through at their own pace.
I corrected a few syntax errors in your code. I'll explain the most important things I've done:
setInterval(joobs(), 20000) -> setInterval(joobs, 20000): You have to
pass the method itself as argument. Else the method will be called
and its return value will be executed every 20 seconds.
Thejobs.Studies[ii] -> Thejobs.Studies["jobID" + ii]: Give the property name as index. Passing a number doesn't work. It is also necessary to initialize ii with 1 instead of 0 because of the JSON file's property names.
I also added some missing brackets.
HTML and JSON aren't changed.
So it all looks like this:
var myVar = setInterval(joobs, 20000);
var ii=1;
function joobs() {
$.getJSON("jsons/jobs.json", function (json) {
var Thejobs = json;
$('#boxContent').append('<br>' + "position:" +
Thejobs.Studies["jobID" + ii].position +
'<br>' +
"Academy: " +
Thejobs.Studies["jobID" + ii].academy +
'<br>' +
"address: " +
Thejobs.Studies["jobID" + ii].address +
'<br>' +
"Description:" +
Thejobs.Studies["jobID" + ii].jobDescription);
$('#boxContent').append("<br>_____________________");
});
ii = ii + 1;
}

Alternate code for "if else" in my code

Below given was my javaScript code.
Condition is, If I give a word like hello. the image for a hello should be displayed or if I give facebook, the image for that has to be displayed likewise for many words, the mentioned image has to be displayed.. But here in my code condition gets failed after first time and image is not displaying for the second word.
Help me with the alternate code for the above mentioned problem
var anu = document.getElementById("display");
var a= document.getElementById("final_span").textContent;
console.log(linebreak(interim_transcript));
if(a.search("hello") || a.search("facebook")){
if(linebreak(interim_transcript) == "hello"){
anu.innerHTML="<img src=hello.jpg>";
}
else if(linebreak(interim_transcript) == "facebook"){
anu.innerHTML="<img src=facebook.jpg>";
}
else if(linebreak(interim_transcript) == "hi"){
anu.innerHTML="<img src=hi.jpg>";
}
else if(linebreak(interim_transcript) == "doll"){
anu.innerHTML="<img src=doll.jpg>";
}
If the value returned by linebreak and image name are same you can use
anu.innerHTML = '<img src="' + linebreak(interim_transcript) + '">';
Otherwise you can use a object where you can specify the image name
var obj = {
hello: "hello.jpg",
facebook: 'facebook.jpg',
hi: 'hi.jpg'
}
var anu = document.getElementById("display");
var a = document.getElementById("final_span").textContent;
if (a.search("hello") || a.search("facebook")) {
var lb = linebreak(interim_transcript);
if (obj[lb]) {
anu.innerHTML = '<img src="' + obj[lb] + '">';
}
}

How can I increment and decrement a counter for the amount of cards in a deck with a certain card name?

Good day;
I'm continuing my attempt to create a deck building application for Cardfight!! Vanguard
There is a rule you can't have more than 4 of the same card in a deck, and no more than 50 cards in a deck.
I'm trying to make it so that I have a counter that increases when a card is added to a deck and decreases when a card is taken out of the deck. But this counter must be for each individual card which starts off at 0 and increases by 1 every time a card with a specific name is added to the deck.
I have a vanguard object and database array where I can create new Vanguard objects easily. I have a variable within the Vanguard object (this.cardLimit = 0) which will set the card limit initially to 0 for each new card.
Then when a new card [addToDeck] is added to the deck, it will increment a counter for that specific card within the database: database[addToDeck].cardLimit++, until the maximum of 4 is reached, after which point this if statement will not work:
if (deck.length < 51 && database[addToDeck].cardLimit < 5)
My problem is - as you will see in the code below - I can't figure out a way to decrement this value when I remove a card using jquery. What I do is dynamically add card names to a div, and when a card name in that div is clicked on, it will remove not only the card from the div but the card from the deck array as well by splicing.
I can't just do database[addToDeck].cardLimit-- as you will see in my code because I use jQuery and "this" to specifically refer to the part of the div being clicked on.
My question is then.... how can I decrease the counter based on the specifications of the code I have provided so far? When my Jquery (last jQuery instance in the code) for removing the part of the deck runs, I need to decrease the counter for the specific card that was removed.
Let me know if you need any further clarification... It's not easy for me to explain my problem in simple terms. Thanks so much for reading.
JavaScript / Jquery:
function Vanguard(name,grade,skill,power,shield,critical, type, trigger, nation, clan, race, flavor, effect, imageURL){
this.name = name;
this.grade = grade;
this.skill = skill;
this.power = power;
this.shield = shield;
this.critical = critical;
this.type = type;
this.trigger = trigger;
this.nation = nation;
this.clan = clan;
this.race = race;
this.flavor = flavor;
this.effect = effect;
this.imageURL = imageURL;
this.cardLimit = 0;
};
var database = {};
database['asura kaiser'] = new Vanguard("Asura Kaiser", 3, "Twin Drive!!", 11000, "", 1, "Normal Unit", "None", "Star Gate", "Nova Grappler", "Battleroid", "The death blow! Kaiser Buster!", "<br/>[CONT](VC/RC):If you do not have another «Nova Grappler» vanguard or rear-guard, this unit gets [Power] -2000. <br/> [AUTO](VC):When this unit's drive check reveals a grade 3 «Nova Grappler», choose one of your rear-guards, and [Stand] it.", "http://images4.wikia.nocookie.net/__cb20120428001646/cardfight/images/thumb/a/a6/VGE_BT01-008EN.jpg/300px-VGE_BT01-008EN.jpg");
database['king of knights, alfred'] = new Vanguard("King of Knights, Alfred", 3, "Twin Drive!!", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Royal Paladin", "Human", "I command you under the name of the King of Knights! Warriors, heed my call!", "<br/>[CONT](VC):Your units cannot boost this unit. <br/> [CONT](VC):During your turn, this unit gets [Power]+2000 for each of your «Royal Paladin» rear-guards. <br/> [ACT](VC/RC):[Counter Blast (3)] Search your deck for up to one grade 2 or less «Royal Paladin», call it to (RC), and shuffle your deck.", "http://images2.wikia.nocookie.net/__cb20121009013434/cardfight/images/thumb/9/95/BT01-001EN_RRR.jpg/300px-BT01-001EN_RRR.jpg");
database['dragonic overlord'] = new Vanguard("Dragonic Overlord", 3, "Twin Drive!!", 11000, "", 1, "Normal Unit", "None", "Dragon Sanctuary", "Kagerou", "Dragon", "<br/>(TD02):Reduce all to ashes, flame of the apocalypse! Eternal Flame! <br/> (BT01):Burn, flame of despair! Eternal Flame!", "<br/>[CONT](VC/RC):If you do not have another «Kagero» vanguard or rear-guard, this unit gets [Power]-2000. <br/> [ACT](VC/RC):[Counter Blast (3)] Until end of turn, this unit gets [Power]+5000, gets '[AUTO](VC/RC):When this unit's attack hits an opponent's rear-guard, [Stand] this unit', and loses 'Twin Drive!!'.", "http://images1.wikia.nocookie.net/__cb20120131161306/cardfight/images/thumb/3/33/TD02-001EN.jpg/300px-TD02-001EN.jpg");
database['ceo amaterasu'] = new Vanguard("CEO Amaterasu", 3, "Twin Drive", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Oracle Think Tank", "Human", "<br/>(BT01):Shape my desire. Project it before me, Yata no Kagami! <br/>(EB05):Feel the flow of time. You will create the future.", "<br/>[CONT](VC):During your turn, if the number of cards in your hand is four or greater, this unit gets [Power] +4000. <br/> [AUTO](VC):At the beginning of your main phase, Soul Charge (1), look at the top card of your deck, and put that card on the top or the bottom of your deck. <br/> [AUTO](VC/RC):[Soul Blast (8) & Counter Blast (5)] When this unit's attack hits, you may pay the cost. If you do, draw up to five cards.)", "http://images2.wikia.nocookie.net/__cb20120831173054/cardfight/images/thumb/3/30/BT01-S05EN_SP.jpg/300px-BT01-S05EN_SP.jpg");
database['alfred early'] = new Vanguard("Alfred Early", 3, "Twin Drive!!", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Royal Paladin", "Human", "To preserve the smiles of his people, the young King leads knights to battle.", "AUTO: When this unit is placed on Vanguard Circle, choose up to one card named 'Blaster Blade' from your soul, and call it to Rear-guard Circle.", "http://images1.wikia.nocookie.net/__cb20120926194218/cardfight/images/thumb/5/5e/PR-0005EN.jpg/300px-PR-0005EN.jpg");
function printVanguard(p, name){
for (var p in database[name]){
if (p !== 'imageURL'){
document.getElementById('output').innerHTML +=('<b>' + p.charAt(0).toUpperCase() + p.slice(1) + '</b>: ' + database[name][p] + '<br />');
}}
};
$(document).ready(function() {
$('#button').click(function(){
$('#output').html(""); //clear old search
$('#image').html(""); // clear old image
var userInput = $('input[name=searchItem]').val();
userInput = userInput.toLowerCase();
$('#output').append(printVanguard(userInput, userInput));
var image = $('<img>').attr('src', database[userInput].imageURL);
$('#image').append(image);
});
var deck = [];
$('#add').click(function(){
var addToDeck = $('input[name=searchItem]').val();
addToDeck = addToDeck.toLowerCase();
database[addToDeck].cardLimit++;
if (deck.length < 51 && database[addToDeck].cardLimit < 5){
deck.push(addToDeck);
$('#quantity').html("");
$('#save').prepend('<div id="quantity">' + 'Total: ' + deck.length + '</div>');
$('#save').append('<div id="cardList">' + database[deck[deck.length-1]].name + '</div>');
}
});
$(document).on('click','[id^=cardList]', function(){
$(this).remove();
deck.splice(deck[this], 1);
$('#quantity').html("");
$('#save').prepend('<div id="quantity">' + 'Total: ' + deck.length + '</div>');
});
});
HTML code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type = "text/javascript" src='script.js'>
</script>
<title></title>
</head>
<body>
<form name="searchForm">
<input type="text" id="search" placeholder="Enter Card Name" name="searchItem"/>
</form>
<div id="button">Search!</div>
<div id="add">Add to Deck</div>
<br/>
<div id="output"></div>
<div id="image"></div>
<div id="save"></div>
</body>
</html>
Fiddle: jsfiddle.net/8QR7q
Provided by Malik
Test Inputs: "Alfred Early", "CEO Amaterasu", "Dragonic Overlord", "Asura Kaiser", or "King of Knights, Alfred"

Using jQuery/JS, can I "tie" together a JS object's property directly to the value of a form input element?

I'm building out an online reservation system for a pet-boarding business in my city and I've hit a wall as to how to efficiently carry out this specific functionality.
Quick gist of the user process...
Some preliminary info is given (client info, pet info, etc etc).
User chooses 2 dates; the check-in and check-out days.
The program calculates the number of days the client is staying and each day is thrown into a constructor for class "Day". A ... block is generated for each day and displayed to the user. It also might be worth noting that all of the Day objects are stored in an array which is then contained in the mama class "ReservationData"...which besides the Day-array also holds some meta-data pertaining to the reservation itself.
Anyway, my problem is that once the 'dayBlocks' are listed & displayed to the user, the user must then be able to go and check individual "extras" that they want for their pet on that specific day.
So I've broken it down so that {ReservationData} <--(has an array of)-- {Days} <--(has an array of)-- {Extras}. There are 14 extra services to choose from, so for each day displayed there is a simple list of checkboxes and labels.
Ideally, I want it setup so that when a checkbox is checked by the user, it directly & immediately alters its corresponding variable within the reservationDataDaysExtraDeepArray accordingly. The C-programmer in me wants to tie a pointer to each checkbox, but I'm (at least I think) pretty sure that's not doable with jQuery.
Although I think I explained it pretty clearly, here's some of the code:
//Day Object/Class
function day(_date, _daynum) {
this.date = new Date(_date);
this.dayNum = _daynum;
this.dayExtras = {
'YH': false, //<--- How can I directly manipulate
'PP': false, //<--- all of these guys via user-control
'EE': false, //<--- of corresponding/assigned
'ST': false, //<--- checkboxes?
'PT': false,
'TT15': false,
'TT30': false,
'TT45': false,
'DC': false //--- Or can I? :/
};
console.log("Day object created with date of " + day.date + " and day-number of " + day.dayNum + ".");
this.getDayNum = function() { return this.dayNum; }
this.getDayDate = function() { return this.date; }
}
This is my first question on this site, but I did a lot of searching and am still lost...thanks guys!
Assuming the name of your checkboxes correspond to the keys in your dayExtras object something like this would do..
//Day Object/Class
function day(_date, _daynum) {
this.date = new Date(_date);
this.dayNum = _daynum;
this.dayExtras = {
'YH': false, //<--- How can I directly manipulate
'PP': false, //<--- all of these guys via user-control
'EE': false, //<--- of corresponding/assigned
'ST': false, //<--- checkboxes?
'PT': false,
'TT15': false,
'TT30': false,
'TT45': false,
'DC': false //--- Or can I? :/
};
console.log("Day object created with date of " + day.date + " and day-number of "+day.dayNum+".");
this.getDayNum = function() { return this.dayNum; }
this.getDayDate = function() { return this.date; }
this.setDayExtras = function (key,val) {
if(key in this.dayExtras){
this.dayExtras[key] = val;
}
}
}
var myDay = new day(null,null);
$(document).on('change','#myForm input[type="checkbox"]', function () {
myDay.setDayExtras(this.name,this.checked);
});
Got it working, thanks for pointing me in the right direction guys!
function saveExtra(me) {
var extraName = me.attr('name');
var extraVal = me.val();
(reservationData[extraName]).dayExtras[extraVal] = me.prop('checked');
for (key in reservationData) {
(reservationData[key]).dump(); //Day data-dump method.
}
}
this.generateExtrasGrid = function() {
var fieldName = "day" + this.dayNum + "";
var exGrid = "";
exGrid += "<form class='extrasGrid' id='" + this.dayNum + "'>";
exGrid += "<input type='checkbox' class='extra' name='" + fieldName + "' value='YH' onclick='saveExtra($(this))' />";............
exGrid += "</form>";
return exGrid;
}​

Categories