I am having 20 records
I want to order the records in terms of Priority field.
Priority field is having 3 values( High, Medium, Low )
I want to display the records in High, Medium, Low records in sequence respectively.
Below is C# version ---> I need this to do in javascript
`var groupedRecords = records.OrderByDescending(x => x.Priority == "High").ThenByDescending(x > x.Priority == "Medium").ThenByDescending(x > x.Priority == "Low")`
In Javascript,
var csvRecords = priorities.split(','); // Now I am getting the csv with mixed orders. I need in sequence.
That is I want to get first all High records, then Medium records and atlast Low records.
You can take look at below simple code:
var points = [{Name: "House",Priority :"High"}, {Name: "Travel",Priority :"Medium"}, {Name: "Children",Priority :"High"}, {Name: "Personal Loan",Priority :"Low"}, {Name: "Car",Priority :"Medium"}, {Name: "Shopping",Priority :"Low"}];
document.getElementById("demo").innerHTML = JSON.stringify(points);
function myFunction() {
var priorityArray = ["High", "Medium","Low"]
points.sort(function(a, b){
var firstPrio = priorityArray.indexOf( a.Priority) ;
var secPrio = priorityArray.indexOf(b.Priority)
return firstPrio -secPrio
});
document.getElementById("sortedArray").innerHTML = JSON.stringify(points);
}
<p>Click the button to sort the array.</p>
<button onclick="myFunction()">Sort it</button>
<br/><br/>
Original Array:
<p id="demo"></p>
Sorted Array:
<p id="sortedArray"></p>
I hope it will help you a bit.
Condensed version using constants for sort order:
Data:
var data = [
{
name: 'Andy',
priority: 'High'
},
{
name: 'John',
priority: 'Low'
},
{
name: 'Tim',
priority: 'Medium'
},
{
name: 'Bob',
priority: 'Medium'
},
{
name: 'Lucas',
priority: 'Medium'
},
{
name: 'Mark',
priority: 'High'
},
{
name: 'Fred',
priority: 'Low'
}
];
Code:
var SORT_ASC = -1;
var SORT_DESC = 1;
function sort_by_priority ( order ) {
var prs = ['High', 'Medium', 'Low'];
data.sort(function ( a, b ) {
var x = prs.indexOf(a.priority);
var y = prs.indexOf(b.priority);
if ( x < y ) return -1 * order;
if ( x > y ) return 1 * order;
return 0;
});
}
Test:
sort_by_priority(SORT_DESC);
console.log(data);
Try this:
Fiddle
Code
var data = [];
var priority = ["low", "medium", "high"];
function createData() {
for (var i = 0; i < 10; i++) {
var index = Math.floor((Math.random() * 10) % 3);
var p = priority[index];
data.push({
"index": i,
"Priority": p
});
}
}
function createLI() {
var ul = document.getElementsByTagName("ul")[0];
var li = "";
data.forEach(function(row) {
li += "<li> " + row.index + " : " + row.Priority + " </li>";
});
ul.innerHTML = li;
}
function sortList(sortOrder) {
var order = (sortOrder == 'desc') ? -1 : 1;
data.sort(function(a, b) {
var p1, p2;
priority.forEach(function(row, index) {
if (a.Priority == row)
p1 = index;
if (b.Priority == row)
p2 = index;
})
if (p1 < p2) return -1 * order;
if (p1 > p2) return 1 * order;
return 0;
});
createLI();
}
(function() {
createData();
createLI();
})()
li {
list-style-type: none;
padding: 5px;
border-bottom: 1px solid #ddd;
margin-left: -20px;
width: 100px;
}
<ul></ul>
<button onclick="sortList('asc')">Asc Sort</button>
<button onclick="sortList('desc')">Desc Sort</button>
Try using String.prototype.match() with RegExp val + "\.\\w+(?=.*,)", "g" to match val followed by any character followed by any alphanumeric character ; where val is "High" , "Medium" , or "Low" stored in an array iterated within Array.prototype.forEach() , utilize Array.prototype.concat() to flatten resulting array res containing input text sorted from "High" to "Medium" to "Low" . Use res.push() to return three arrays sorted from "High" to "Medium" to "Low"
var priorities = "High:1,Medium:2,Low:3,Low:4,Medium:5,High:6,Medium:7,"
+ "High:8,Low:9,Low:10,Medium:11,High:12,Low:13,Medium:14,"
+ "High:15,High:16,Low:17,Medium:18,Low:19,High:20";
var keys = ["High", "Medium", "Low"], res = [];
keys.forEach(function(val) {
res = res.concat(priorities.match(new RegExp(val + "\.\\w+(?=.*,)", "g")))
});
document.body.innerHTML = JSON.stringify(res)
Related
I'm trying to highlight only the number between the brackets in regular js. Colors are based on value (type of fruit in this scenario).
HTML
<a class="temple" href="something # URL">LARGE FRUIT (215)</a>
<a class="temple" href="something # URL">PINEAPPLE (38)</a>
<a class="temple" href="something # URL">RED APPLE (76)</a>
My Dict
var my_dict = {'BLUE':['ORANGE'], ['GRAPE']
'YELLOW':['PINEAPPLE'], ['KIWI']}
I could do them independently using but it's messy and may break the code if a tag is removed:
let Pineapple = document.querySelector('.temple')
PINEAPPLE.innerHTML = PINEAPPLE.innerHTML.replace(/\([^\)]*\)/, '<span class="red">$&</span>')
This is what I have so far:
function color(){
let fruits = document.querySelector('.temple')
for (let i = 0; i<fruits.length; i++) {
let str = fruits.innerHTML //this gives me the text I need.
My goal is to use the results (value) to find the key and ultimately color just the number.
that ?
const my_dict =
{ BLUE: [ 'ORANGE', 'GRAPE' ]
, YELLOW: [ 'PINEAPPLE', 'KIWI' ]
, RED: [ 'APPLE' ]
};
// ES5 code
const my_dict_reverse =
Object
.keys( my_dict)
.reduce( function(r,k)
{
my_dict[k].forEach( function(fruit) { r[fruit] = k } );
return r;
},{});
// my_dict_reverse = { ORANGE: 'BLUE', GRAPE: 'BLUE', PINEAPPLE: 'YELLOW', KIWI: 'YELLOW', APPLE: 'RED' }
document
.querySelectorAll('.temple')
.forEach( function(el)
{
let pos = el.textContent.search(/\([^\)]*\)/)
, fruit = el.textContent.slice(0,pos)
, val = el.textContent.slice(pos)
, colorClass = my_dict_reverse[ fruit.replace(/^\s+|\s+$/g,'')] || ''
;
el.innerHTML = fruit
+ '<span class="' + colorClass + '">'
+ val +'</span>';
});
/* ES10 code ...
const my_dict_reverse = Object.keys( my_dict).reduce((r,k)=>
{
my_dict[k].forEach(fruit=>r[fruit]=k)
return r
},{})
document.querySelectorAll('.temple').forEach(el=>
{
let [fruit, val] = el.textContent.split(/(?=\()|(?<=\))/)
, colorClass = my_dict_reverse[ fruit.trim()] ?? ''
;
el.innerHTML = `${fruit}<span class="${colorClass}">${val}</span>`
})
*/
body { background: steelblue; }
a.temple {
color : black;
float : left;
clear : both;
text-decoration : none;
}
span.RED { color : red; }
span.BLUE { color : blue; }
span.YELLOW { color : yellow; }
<a class="temple" href="something # URL">LARGE FRUIT (215)</a>
<a class="temple" href="something # URL">PINEAPPLE (38)</a>
<a class="temple" href="something # URL">APPLE (76)</a>
Here I am making a word conversion tool which changes a certain word X into Y, or X to Y to Z by using javascript.
Progress: HERE
Here is the entire javascript:
var conversion = {
"one":"two",
};
var conversion2 = {
"two":"three",
};
var maxLength = Object.keys(conversion)
.reduce((a, b) => a.length > b.length ? a : b)
.length;
function convert (text) {
var converted = "";
var cur = 0;
while (cur < text.length) {
var testedPhoneme;
var symbol = undefined;
for (var length = maxLength; length > 0; length --) {
testedPhoneme = text.substr(cur, length);
if (conversion[testedPhoneme]) {
symbol = conversion[testedPhoneme];
break; // stop the loop
}
}
if (symbol) {
converted += symbol;
cur += testedPhoneme.length;
}
else {
converted += text[cur]
cur++;
}
}
return converted
}
var maxLength2 = Object.keys(conversion2)
.reduce((a, b) => a.length > b.length ? a : b)
.length;
function convert2 (text) {
var converted2 = "";
var cur2 = 0;
while (cur2 < text.length) {
var testedPhoneme2;
var symbol2 = undefined;
for (var length = maxLength2; length > 0; length --) {
testedPhoneme2 = text.substr(cur2, length);
if (conversion2[testedPhoneme2]) {
symbol2 = conversion2[testedPhoneme2];
break; // stop the loop
}
}
if (symbol2) {
converted2 += symbol2;
cur2 += testedPhoneme2.length;
}
else {
converted2 += text[cur2]
cur2++;
}
}
return converted2
}
function onInputTextChange(txt) {
var outputTextareaElem = document.getElementById("output_textarea");
var div = document.createElement("div");
var outputHtmlEntities = convert(txt);
div.innerHTML = outputHtmlEntities;
outputTextareaElem.value = div.innerText;
}
function onOutputTextChange(txt) {
var outputTextareaElem2 = document.getElementById("output_textarea2");
var div = document.createElement("div");
var outputHtmlEntities2 = convert2(txt);
div.innerHTML = outputHtmlEntities2;
outputTextareaElem2.value = div.innerText;
}
In the page that I made so far, there are three <textarea>s; Input, Output and Output2.
Currently, thanks to this piece of code;
var conversion = {
"one":"two",
};
var conversion2 = {
"two":"three",
};
If one is typed into Input, Output renders two. If two is manually typed into Output, three gets rendered in Output2.
Here is the problem, I want to render three in Output2 only through typing one into Input, but a direct two-step conversion seems unavailable yet. In other words, Input > Output (one > two) and Output > Output2 (two > three) conversion is available, but Input > Output > Output2 (one > two > three) is unavailable.
What needs to be done to solve this? Any help would be appreciated.
Ok, not exactly what you asked, but I could do something that works
Here is the example : https://jsfiddle.net/alias_gui3/8knw57u0/94/
how to use it :
to add new characters OR new languages/scripts
just complete the dictionnary :
var dictionnary = [
{
latin: "u",
japanese: "う",
emoji: "👋"
// add any script for every characters
},{
latin: "ku",
japanese: "く",
emoji: "👀"
},{
latin: "tsu",
japanese: "つ",
emoji: "🤖"
}
// add any character with the same format
]
to add new textareas :
give your textarea a recognizable id (eg. id="cyrillic")
then connect your textarea with this method:
// connect your textareas below !!
addTextArea(
document.querySelector("#latin"),
"latin"
);
addTextArea(
document.querySelector("#japanese"),
"japanese"
);
addTextArea(
document.querySelector("#emoji"),
"emoji"
);
// add new textarea with a new language here
then all the connections are done, you can edit all your textareas, if they recognise a character they will translate it in all the other textareas
full code
var dictionnary = [
{
latin: "u",
japanese: "う",
emoji: "👋"
// add any script for every characters
},{
latin: "ku",
japanese: "く",
emoji: "👀"
},{
latin: "tsu",
japanese: "つ",
emoji: "🤖"
}
// add any character with the same format
]
// calculate the max length for each language :
var max = {}
dictionnary.forEach(
char => {
Object.keys(char).forEach(script => {
max[script] = max[script]
? char[script].length > max[script]
? char[script].length
: max[script]
: char[script].length
})
}
)// now max contains the maximum length of sequence
// for each language
function findSymbol (
originSymbol,
originScript,
destinationScript
) {
for (var i = 0; i < dictionnary.length; i++) {
var char = dictionnary[i];
if (char[originScript] === originSymbol) {
return char[destinationScript]
}
}
return false // if not found
}
function translate (
text,
originScript,
destinationScript
) {
var cur = 0;
var translated = "";
var maxLength = max[originScript]
while (cur < text.length) {
var testedPhoneme;
var symbol = false;
for (var length=maxLength; length > 0; length--) {
testedPhoneme = text.substr(cur, length);
symbol = findSymbol(
testedPhoneme,
originScript,
destinationScript
)
if (symbol) {
break; // stop the loop
}
}
if (symbol) {
translated += symbol;
cur += testedPhoneme.length;
}
else {
translated += text[cur];
cur++;
}
}
return translated
}
var textareas = []; // the list of your textareas
function addTextArea(element, originScript) {
textareas.push({
element: element,
script: originScript
})
element.addEventListener("input", function (e) {
signalTextChanged(element, originScript)
});
}
function signalTextChanged (
originElement,
originScript
) {
var originText = originElement.value;
textareas.forEach(function (textarea) {
if (textarea.element !== originElement) {
var translated = translate(
originText,
originScript,
textarea.script
)
textarea.element.value = translated;
}
})
}
// connect your textareas below !!
addTextArea(
document.querySelector("#latin"),
"latin"
);
addTextArea(
document.querySelector("#japanese"),
"japanese"
);
addTextArea(
document.querySelector("#emoji"),
"emoji"
);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
</script>
</head>
<body>
<center>
<h1>Latin to foreign script converter 3</h1>
<p>type in u, ku, tsu in the FIRST panel</p>
<textarea
id="latin"
autofocus=""
placeholder="type text in latin ! (u ku or tsu)"
rows="10"
style="width:300px"></textarea>
<textarea
id="japanese"
rows="10"
placeholder="type text in japanese !"
style="width:300px"></textarea>
<textarea
id="emoji"
rows="10"
placeholder="type text in emojis !!"
style="width:300px"></textarea>
</center>
</center>
</body>
</html>
I'm not sure if I fully understand what you're trying to achieve here
There are some duplications in your code, what if you'll have 10 fields for output, will you create a special function for each of them?
Try to simplify things.
One way would be to loop through all of your lists as follows:
Put all your conversation in a list
var lists = [conversion, conversion2];
Add isInNextList function to check if your text is a key in the next list
function isInNextList(index, key) {
if (lists.length < index) {
return false;
}
return Object.keys(lists[index]).includes(key);
}
change your onInputTextChange function as follow:
function onInputTextChange(txt) {
var index = 0;
var text = txt;
while (isInNextList(index, text)) {
var outputTextareaElem = document.getElementById(
'output_textarea_' + index
);
var div = document.createElement('div');
text = lists[index][text]; //next key
index++;
div.innerHTML = text;
outputTextareaElem.value = div.innerText;
}
}
change your output textarea's ids to contain the index
id="output_textarea_0"
id="output_textarea_1"
There are other improvements that can be made like:
Creating the output fields dynamically,
Clear output fields etc.
I'm trying to create an object with an array of multiple objects inside it, each inner-object representing a card.
I initialise all three outside of a forEach() loop, push each item into the array and then assign that array to a key in my outer-object:
const cart = {};
const cartItems = [];
const cartItem = {}
cart['cart-items'] = cartItems;
cartItems.push(cartItem);
Inside the forEach() I take the card data, every time that cards button is clicked, and assign it to the inner-object:
///forEach() with 'click' event-handler for the buttons...
if (cartItem.id !== currentCardId) {
cartItem['id'] = currentCardId;
cartItem['name'] = currentCardName;
cartItem['price'] = this.dataset.cardPrice;
cartItem['quantity'] = 1;
} else {
cartItem.quantity = cartItem.quantity + 1;
}
///...end of forEach()
This increments the 'quantity' of the 'card' if I click the same button multiple times, but when I click on a separate button it overwrites the existing card and it's 'quantity' value.
I understand if I initialise cartItem and cartItems inside the loop it prevents this overwriting, but then the cards 'quantity' doesn't increment, it just creates a separate object with a 'quantity' of '1'.
Any idea how I can work around this?
Edit
Complete code:
addCartBtn.forEach(i => {
i.addEventListener('click', function(e) {
let currentCardId = this.dataset.cardId;
let currentCardName = this.dataset.cardName;
let currentCardQuantity = 0;
let currentCardPrice;
let removeCartItem = document.getElementsByClassName('remove-cart-item');
if (cartItem.id !== currentCardId) {
cartItem['id'] = currentCardId;
cartItem['name'] = currentCardName;
cartItem['price'] = this.dataset.cardPrice;
cartItem['quantity'] = 1;
} else {
cartItem.quantity = cartItem.quantity + 1;
}
if (this.dataset.cardPrice >= 1) {
currentCardPrice = '£' + this.dataset.cardPrice;
} else {
currentCardPrice = this.dataset.cardPrice + 'p';
}
if (currentCardName.length > 10) {
currentCardName = currentCardName.substring(0, 9) + '...';
}
if (document.getElementById(`${currentCardId}`)) {
cartItems.forEach(i => {
if (currentCardId === i) {
currentCardQuantity += 1;
document.getElementById(
`${currentCardId}`
).innerHTML = `x${currentCardQuantity}`;
} else {
document.getElementById(`${currentCardId}`).innerHTML = 'x1';
}
});
} else {
dropdownCheckoutContainer.innerHTML += `<div class="dropdown-card" id="remove-${currentCardId}"><div class="dropdown-card-display"><p class="remove-${currentCardId}"><i class="fa fa-minus-square remove-cart-item" data-remove-id="${currentCardId}"></i>${currentCardName}</p></div><div class="dropdown-quantity"><p class="remove-${currentCardId}" id="${currentCardId}">x1</p></div><div class="dropdown-price"><p class="remove-${currentCardId}">${currentCardPrice}</p></div><div class="dropdown-hidden-id"><input class="remove-${currentCardId}" type="hidden" name="${currentCardId}" data-remove-id="${currentCardId}"></div></div>`;
}
if (dropdownCheckoutContainer.childElementCount >= 7) {
dropdownCheckoutContainer.style.overflow = 'scroll';
dropdownCheckoutContainer.style.borderBottom =
'1px solid rgba(255, 98, 0, 0.5)';
}
if (dropdownCheckoutContainer.childElementCount > 1) {
notificationIconContainer.style.display = 'flex';
notificationIcon.innerHTML =
dropdownCheckoutContainer.childElementCount - 1;
}
for (const i of removeCartItem) {
i.addEventListener('click', function(e) {
let btnId = this.dataset.removeId;
let currentRow = document.getElementById(`remove-${btnId}`);
let idIndexes = [];
if (dropdownCheckoutContainer.childElementCount > 1) {
dropdownCheckoutContainer.removeChild(currentRow);
}
notificationIcon.innerHTML = notificationIcon.innerText - 1;
if (!(dropdownCheckoutContainer.childElementCount >= 7)) {
dropdownCheckoutContainer.style.borderBottom = 'none';
if (checkoutFull.childElementCount === 1) {
checkoutFull.innerHTML = '';
}
}
cartItems.forEach(i => {
if (i === btnId) {
idIndexes.push(cartItems.indexOf(i));
}
});
for (let i = idIndexes.length - 1; i >= 0; i--) {
cartItems.splice(idIndexes[i], 1);
}
});
i.addEventListener('mouseup', () => {
if (dropdownCheckoutContainer.childElementCount <= 2) {
document.getElementById('empty-cart').style.display = 'block';
checkoutLink.classList.add('checkout-link-disabled');
}
if (dropdownCheckoutContainer.childElementCount <= 2) {
notificationIconContainer.style.display = 'none';
}
});
}
console.log(cart);
});
i.addEventListener('mouseup', () => {
document.getElementById('empty-cart').style.display = 'none';
checkoutLink.removeAttribute('class', 'checkout-link-disabled');
});
});
suppose, You have a data like that
let cart = { 'cart-items': [{id: 1, name: 'test 1', price: 30.9, quantity: 1}] }
When You are going to click on button then currentCardId = 1
Then you need to the following at click event.
const existsIndex = cart['cart-items'].findIndex((item) => item.id === currentCardId )
if (existsIndex !== -1) {
cart['cart-items'][existsIndex].quantity++
} else {
cart['cart-items'].push({id: currentCardId, name: 'sadsad', quantity: 1})
}
var data = [{
id: "Calligraphy",
category: "artsAndCrafts",
categoryName: "Arts & Crafts",
place: "indoor",
activity: "light",
difficulty: "medium",
link:"tennis.html",
description:"Knitting is great"
}, {
id: "Cross-stitching",
category: "artsAndCrafts",
categoryName: "Arts & Crafts",
place: "indoor",
activity: "light",
difficulty: "easy",
link:"knitting.html",
description:"Knitting is great"
}, {
id: "Gardening",
category: "artsAndCrafts",
categoryName: "Arts & Crafts",
place: "outdoor",
activity: "light",
difficulty: "easy",
link:"knitting.html",
description:"Knitting is great"
}];
var myHobbies = [
];
//Alphabetical Order
function compareStrings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
data.sort(function(a, b) {
return compareStrings(a.id, b.id);
})
var myHobbies = new Array();
//Show hobbies on explore
function loadHobbies(){
myHobbies = JSON.parse(localStorage.getItem("savedHobbies"));
$("#indvSports").empty();
$("#subheader").html("<h2>Explore</h2><div id='searchMenu'><form method='get' action='input' id='searchbox' action=''><input id='formInput' type='text' placeholder='search'></form><input type='image' id='submit' onclick='search()' src='img/search.png' alt='Submit'/><img id='menuButton' src='img/menu.png'></div>");
for (i = 0; i < data.length; i++) {
$("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
}
}
window.onload = loadHobbies();
//Show and Hide Menu
var menu = $('#menu'), but = $('#menuButton');
menu.hide();
$(document).on('click', '*', function(evt) {
evt.stopPropagation(); //<-- stop the event propagating to ancestral elements
if ($(this).is(but)) //<-- on button click, toggle visibility of menu
menu.toggle();
else if (!$(this).closest(menu).length) //<-- on click outside, hide menu
menu.hide();
});
//Sift and display categories
function categorySift(id) {
menu.hide();
$('#buttons').empty();
var categoryId = id;
for (i = 0; i < data.length; i++) {
if (data[i].category == categoryId) {
$("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
}
}
}
//Sift and display categories for indoor/outdoor
function categorySiftPlace(id) {
menu.hide();
var categoryId = id;
$('#buttons').empty();
for (i = 0; i < data.length; i++) {
if (data[i].place == categoryId) {
$("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
}
}
}
//Search
function search(){
var formInput = document.getElementById("formInput").value.toLowerCase();
var count = 0;
for (i = 0; i < data.length; i++) {
if (data[i].id.toLowerCase() == formInput) {
count = count + 1;
$("#buttons").html("<p id='results'>"+count+" results found for '" + formInput + "' <a href=''> X</a></p><a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
break;
}
else{
$('#buttons').html("<p id='noResults'>No results found for '" + formInput + "' <a href=''> X</a></p>");
}
}
document.getElementById("formInput").value='';
}
//Individual pages
function loadPage(which) {
currentI = which;
$('#buttons').empty();
$("#myHobbiesSection").empty();
$("#subheader").html("<style>#subheader{height:60px;}</style><h2><b>"+data[which].id+"</b><br>"+ data[which].categoryName +"</h2><a href='index.html'><img src='img/back.png' id='backButton'/></a><img src='img/add.png' onclick='addHobby("+currentI+")' id='addButton'/>");
$("#indvSports").html("<p>"+data[which].description+"</p>");
}
//Individual pages(from My Hobbies page)
function loadPageMyHobby(which) {
currentI = which;
$('#buttons').empty();
$("#myHobbiesSection").empty();
$("#subheader").html("<style>#subheader{height:60px;}</style><h2><b>"+myHobbies[which].id+"</b><br>"+ myHobbies[which].categoryName +"</h2><a href='index.html'><img src='img/back.png' id='backButton'/></a><img src='img/add.png' onclick='addHobby("+currentI+")' id='addButton'/>");
$("#indvSports").html("<p>"+myHobbies[which].description+"</p>");
}
//Add hobby
function addHobby(which) {
alert("Would you like to add "+ data[which].id.toLowerCase() +" to your hobbies?");
myHobbies.push({id: data[which].id, categoryName: data[which].categoryName, description: data[which].description});
localStorage.setItem("savedHobbies", JSON.stringify(myHobbies));
alert("done");
}
//<a href='#' onclick='editMyHobby' id='editButton'>Edit</a>
//My Hobbies Page
function myHobbiesPage(){
$("#myHobbiesSection").empty();
myHobbies = JSON.parse(localStorage.getItem("savedHobbies"));
$("#subheader").html("<style>#subheader{height:30px;}</style><h2>My Hobbies</h2>");
$('#buttons').empty();
$("#indvSports").empty();
for (i = 0; i < myHobbies.length; i++) {
$("#myHobbiesSection").append("<a href='#' class='blockMyHobbies' id='myHobbies[i].id' onclick='loadPageMyHobby("+i+")'>" + myHobbies[i].id + "</a><a href='#' id='deleteButton' onclick='deleteHobby("+i+")'>X</a>");
}
}
//Lets you edit on My Hobby
// function deleteHobby(i){
// alert(myHobbies[i].id);
// delete myHobbies[i];
//
// localStorage.setItem("savedHobbies", JSON.stringify(myHobbies));
// }
Hello,
I'm making an app that contains a multi-dimensional array that must be stored into local storage. I'm trying to get it to take elements from the main array data and store them in myHobbies.
I can see in the last function that when I replace the myHobbies[i].id snippet with data[i].id, it shows the elements (with the wrong information because it's the wrong array), but this shows that the array myHobbies is storing new elements when you tell it to.
I think the problem is that it's not parsing them correctly or something along those lines. It could also be the variables where the parsed array is stored (I'm a little confused in that area). If anyone knows what I could be doing wrong, that would be great.
I am having trouble trying to alert the winner, among other things. I also am trying to alert when the user trys to click on a button that has already been pressed, but have no idea what I am doing in that regard either. All help is appreciated. Thank you guys.
<table>
<tr>
<td id="00" onclick="makeMove(0,0)">00</td>
<td id ="01" onclick="makeMove(0,1)">01</td>
<td id ="02" onclick="makeMove(0,2)">02</td>
</tr>
<tr>
<td id ="10" onclick="makeMove(1,0)">10</td>
<td id ="11" onclick="makeMove(1,1)">11</td>
<td id ="12" onclick="makeMove(1,2)">12</td>
</tr>
<tr>
<td id ="20" onclick="makeMove(2,0)">20</td>
<td id ="21" onclick="makeMove(2,1)">21</td>
<td id ="22" onclick="makeMove(2,2)">22</td>
</tr>
</table>
<hr>
<input id="myMoveButton" type="submit">
<script src="java.js"></script>
Javascript:
// -1 means 0's turn
// 1 means X's turn
// AFTER EVERY MOVE
// UNTIL GAME OVER
// THIS NEEDS TO BE FLIPPED
// IF IT WAS 1, now it will be -1 and vice versa
var turn = 1;
// 0 means no move has been made yet
// on that particular square
var grid = [
[0, 0 ,0],
[0, 0 ,0],
[0, 0, 0]
];
function makeMove(row, column) {
if (grid [row][column] == 0) {
grid[row][column] = turn;
var idOfSquareToChange = row +"" + column;
if (turn == 1) {
$("#"+idOfSquareToChange).html('X');
}else {
$("#"+idOfSquareToChange).html('O');
}
// CHECK IF GAME IS OVER
// IF GAME ISN'T OVER
if (turn == 1) {
turn = -1;
}else {
turn = 1;
}
printGrid();
}else {
alert('That square has been chosen');
}
}
function printGrid(){
var board = grid[0][0] + " " + grid [0][1] + " " + grid[0][2];
board += "\n";
board += grid[1][0] + " " + grid [1][1] + " " + grid[1][2];
board += "\n";
board += grid[2][0] + " " + grid [2][1] + " " + grid[2][2];
alert(board);
}
function isGameOver() {
// HERE IS WHERE OUR LOGIC WOULD GO
// TO SEE IF SOMEONE won
}
This is what i came up with:
function isGameOver() {
for (var i = 0; i < grid.length; i++) {
if(grid[i][0] == grid[i][1] && grid[i][0]==grid[i][2] && grid[i][0]!=0){
alert(grid[i][0]+" Wins");
_win=1;
return;
}
}
for (var i = 0; i < grid.length; i++) {
if(grid[0][i] == grid[1][i] && grid[0][i]==grid[2][i] && grid[0][i]!=0){
alert(grid[0][i]+" Wins");
_win=1;
return;
}
}
if(grid[0][0]==grid[1][1] && grid[0][0] == grid[2][2] && grid[0][0]!=0){
alert(grid[0][0]+" Wins");
_win=1;
return;
}
if(grid[0][2]==grid[1][1] && grid[0][2] == grid[2][0] && grid[2][0]!=0){
alert(grid[1][1]+" Wins");
_win=1;
return;
}
}
Working fiddle
This will check whether data in a single column or in a single row or in diagonals should be same. And if a user wins then he can not click on anything else.
By using lodash, you can abstract a bunch of the pieces of this. I went ahead and re-coded it to show you how I'd do it. This will allow you to make the board whatever size you want and allow for up to 4 players.
Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/gqqse6cw/18/
Here's all the HTML you need:
<div class="gameboard"></div>
Here's the script:
var game = function( options ){
options = options || [];
var target = options.target || '.gameboard',
size = options.size || [ 3, 3 ],
players = options.players || 2,
toWin = options.toWin || 3,
symbols = [ 'o', 'x', '+', '!' ],
current,
grid,
setup = function ( ) {
$(target).empty();
current = 0;
grid = [];
_.each(_.range(size[0]), function(r) {
var row = $('<div>')
.addClass('row');
grid.push([]),
_.each(_.range(size[1]), function(c) {
grid[r].push(undefined),
row.append(
$('<button>')
.addClass('square open')
.attr('data-pos',r + ',' + c)
.html(' ')
);
})
$(target).append(row );
});
$(target).append(
$('<div>')
.addClass('player')
.append(
$('<span>')
.html('Player')
)
.append(
$('<span>')
.addClass('symbol')
.html(symbols[0])
)
);
$('.square').click( function(){
if (!($(this).hasClass('disabled'))) makeMove(this)
});
},
makeMove = function (btn) {
var btn = $(btn)
.addClass('disabled')
.html(symbols[current]),
pos = btn.attr('data-pos').split(',');
grid[pos[0]][pos[1]] = current;
checkBoard();
},
checkBoard = function () {
var winners = [];
checkArray()
winners = checkArray(grid,winners); // check rows
winners = checkArray(_.zip.apply(_, grid) ,winners,'vert'); // check columns
var diag = [],
diagReverse = [],
i = 0,
di = 0,
map = [],
mapR = [];
_.each(grid, function(g, gk){
_.each(g, function(cell, ck){
di = ck + i;
diag[di] = diag[di] || [];
diagReverse[di] = diagReverse[di] || [];
map[di] = map[di] || [];
mapR[di] = mapR[di] || [];
diag[di].push(grid[gk][ck]);
diagReverse[di].push( grid[ grid.length - gk - 1 ][ ck ]
);
map[di].push([gk,ck]);
mapR[di].push([(grid.length - gk - 1), ck]);
});
i++;
});
winners = checkArray(diag ,winners, map); // check diagonal
winners = checkArray(diagReverse ,winners, mapR); // check reverse diagonal
if ( winners.length > 0 ) playerWin(winners);
current++;
current = current % players;
$(target + ' .symbol')
.html(symbols[current]);
},
checkArray = function (arr,winners,map) {
map = map || 0;
var winner = [],
setRow = [],
count = 0,
cur = -1;
_.each(arr, function(g, key){
count = 0;
_.each(g, function(cell, ckey){
if (cell===undefined || cell !== cur) {
count = 0;
setRow = [];
}
cur = cell;
count++;
if (map) {
if ( map === 'vert'){
setRow.push([ckey,key]);
} else if ( _.isArray(map)) {
setRow.push([map[key][ckey]]);
}
} else {
setRow.push([key,ckey]);
}
if (count >= toWin) winner = winner.concat(setRow);
});
});
if ( winner.length > 0 ) winners = winners.concat(winner);
return winners;
},
playerWin = function (winners) {
$('.gameboard button')
.addClass('disabled');
_.each(winners, function(w){
$('.gameboard button[data-pos="' + w.join() + '"]')
.addClass('win');
});
$(target).append(
$('<div>')
.addClass('winner')
.append(
$('<h1>')
.html('Congratulations, player ' + symbols[current] + '!')
)
.append(
$('<button>')
.addClass('replay')
.html('Play Again?')
)
);
$('.replay').click ( function(){
setup();
});
};
setup();
}
game();