So, this is a model of tree diagram. Click run on jsfiddel to see it (no right to more than 2 links)
And it is perfect, but my real diagram will be bigger, so I wrote a function that toggle the title and description on click, so I could have the information on something only if it interests me. My problem is that the links won't update too.
when hided
My code is looking like
Jsfiddle link
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equi="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="viewport" content="width=device-width">
<title>My Try</title>
<link rel="stylesheet" href="../treant-js-master/Treant.css">
<link rel="stylesheet" href="myTry.css">
</head>
<body>
<div class="chart Treant loaded" id="myTry"></div>
<script src="../treant-js-master/vendor/raphael.js"></script>
<script src="../treant-js-master/Treant.js"></script>
<script src="../treant-js-master/vendor/jquery.min.js"></script>
<script src="myTry.js"></script>
<script>
new Treant( chart_config );
</script>
<script>
$(".node1").click(function(e){
if (e.target.classList.value !== "collapse-switch"){
$(this).children(".node-title").toggle();
$(this).children(".node-desc").toggle();
}
})
</script>
</body>
</html>
Javascript
var config = {
container: "#myTry",
levelSeparation: 45,
rootOrientation: "WEST",
siblingSeparation: 10,
connectors: {
type: "curve",
style: {
fill: "#e6b8ff"
}
},
node: {
HTMLclass: 'node1',
collapsable: true,
collapsed: true
}
},
group = {
text: {
name: "Group",
title: "Group",
desc: "complicated group"
}
},
group1 = {
parent: group,
text: {
name: "Grou",
title: "Grou",
desc: "complicated grou"
}
},
group2 = {
parent: group,
text: {
name: "Gro",
title: "Gro",
desc: "complicated gro"
}
},
group11 = {
parent: group1,
text: {
name: "Gr",
title: "Gr",
desc: "complicated gr"
}
},
group12 = {
parent: group1,
text: {
name: "G",
title: "G",
desc: "complicated g"
}
},
chart_config = [
config,
group,
group1,
group2,
group11,
group12
];
CSS
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td
{ margin:0; padding:0; }
table { border-collapse:collapse; border-spacing:0; }
fieldset,img { border:0; }
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
caption,th { text-align:left; }
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
q:before,q:after { content:''; }
abbr,acronym { border:0; }
body { background: #fff; }
/* optional Container STYLES */
.chart { height: 600px; margin: 5px; width: 900px; }
.Treant > .node { }
.Treant > p { font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-weight: bold; font-size: 12px; }
.node-name { font-weight: bold;}
.node1 {
padding: 2px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
background-color: #ffe4e1;
border: 3px solid #ffc0cb;
width: 200px;
font-family: Arial;
font-size: 14px;
}
.collapse-switch {
width: 16px !important;
height: 16px !important;
}
Related
Does anyone know which is the most optimal free JS library for a dynamic organisational chart where you can add and delete nodes like this:
please check below html code
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://fperucic.github.io/treant-js/Treant.css">
<script src="https://fperucic.github.io/treant-js/vendor/raphael.js"></script>
<script src="https://fperucic.github.io/treant-js/Treant.js"></script>
<script>
var simple_chart_config = {
chart: {
container: "#OrganiseChart-simple"
},
nodeStructure: {
text: { name: "Parent node" },
children: [
{
text: { name: "First child" }
},
{
text: { name: "Second child" }
}
]
}
};
var config = {
container: "#OrganiseChart-simple"
};
var parent_node = {
text: { name: "Parent node" }
};
var first_child = {
parent: parent_node,
text: { name: "First child" }
};
var second_child = {
parent: parent_node,
text: { name: "Second child" }
};
var simple_chart_config = [
config, parent_node,
first_child, second_child
];
</script>
<style>
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { margin:0; padding:0; }
body { background: #fff; }
/* optional Container STYLES */
.chart { height: 159px; width: 332px; margin: 5px; margin: 5px auto; border: 3px solid #DDD; border-radius: 3px; }
.node { color: #9CB5ED; border: 2px solid #C8C8C8; border-radius: 3px; }
.node p { font-size: 20px; line-height: 20px; height: 20px; font-weight: bold; padding: 3px; margin: 0; }
</style>
<body>
<div class="chart" id="OrganiseChart-simple">
</body>
<script>
new Treant( simple_chart_config );
</script>
</html>
Reference URL : https://fperucic.github.io/treant-js/
you could try OrgChart
It is opensource and you can checkout a live demo
The issue that I am having is that once a user selects an answer and then clicks 'Submit Answer' and receives their feedback they are able to continue to click around and select other answers before progressing onto the next question. How can I prevent a user from being able to do that once they submit one answer?
let score = 0;
let currentQuestion = 0;
let questions = [{
title: "At what age was Harry Potter when he received his Hogwarts letter?",
answers: ['7', '10', '11', '13'],
correct: 1
},
{
title: "Which is not a Hogwarts house?",
answers: ['Dunder Mifflin', 'Ravenclaw', 'Slytherin', 'Gryffindor'],
correct: 0
},
{
title: "Who teaches Transfiguration at Hogwarts?",
answers: ['Rubeus Hagrid', 'Albus Dumbledore', 'Severus Snape', 'Minerva McGonnagle'],
correct: 3
},
{
title: "Where is Hogwarts School for Witchcraft and Wizardry located?",
answers: ['France', 'USA', 'UK', 'New Zealand'],
correct: 2
},
{
title: "What form does Harry Potter's patronus charm take?",
answers: ['Stag', 'Eagle', 'Bear', 'Dragon'],
correct: 0
},
{
title: "What type of animal is Harry's pet?",
answers: ['Dog', 'Owl', 'Cat', 'Snake'],
correct: 1
},
{
title: "Who is not a member of the Order of the Phoenix?",
answers: ['Remus Lupin', 'Siruis Black', 'Lucious Malfoy', 'Severus Snape'],
correct: 2
},
{
title: "What is not a piece of the Deathly Hallows?",
answers: ['Elder Wand', 'Cloak of Invisibility', 'Resurrection Stone', 'Sword of Gryffindor'],
correct: 3
},
{
title: "In which house is Harry sorted into after arriving at Hogwarts?",
answers: ['Slytherin', 'Ravenclaw', 'Gryffindor', 'Hufflepuff'],
correct: 2
},
{
title: "What prevented Voldemort from being able to kill Harry Potter when he was a baby?",
answers: ['Love', 'Anger', 'Friendship', 'Joy'],
correct: 0
},
];
$(document).ready(function() {
$('.start a').click(function(e) {
e.preventDefault();
$('.start').hide();
$('.quiz').show();
showQuestion();
});
$('.quiz').on('click', 'button', function() {
$('.selected').removeClass('selected');
$(this).addClass('selected');
});
$('.quiz a.submit').click(function(e) {
e.preventDefault();
if ($('button.selected').length) {
let guess = parseInt($('button.selected').attr('id'));
checkAnswer(guess);
} else {
alert('Please select an answer');
}
});
$('.summary a').click(function(e) {
e.preventDefault();
restartQuiz();
});
});
function showQuestion() {
let question = questions[currentQuestion];
$('.quiz h2').text(question.title);
$('.quiz div:nth-child(2)').html('');
for (var i = 0; i < question.answers.length; i++) {
$('.quiz div:nth-child(2)').append(`<button id="${i}">${question.answers[i]}</button>`);
}
showProgress();
}
function showIncorrectQuestion(guess) {
let question = questions[currentQuestion];
$('.quiz h2').text(question.title);
$('.quiz div:nth-child(2)').html('');
for (var i = 0; i < question.answers.length; i++) {
let cls = i === question.correct ? "selected" : guess === i ? "wrong" : ""
$('.quiz div:nth-child(2)').append(`<button id="${i}" class="${cls}">${question.answers[i]}</button>`);
}
showProgress();
}
function checkAnswer(guess) {
let question = questions[currentQuestion];
if (question.correct === guess) {
if (!question.alreadyAnswered) {
score++;
}
showIsCorrect(true);
} else {
showIsCorrect(false);
showIncorrectQuestion(guess);
}
question.alreadyAnswered = true;
}
function showSummary() {
$('.quiz').hide();
$('.summary').show();
$('.summary p').text("Thank you for taking the quiz! Here's how you scored. You answered " + score + " out of " + questions.length + " correctly! Care to try again?")
}
function restartQuiz() {
questions.forEach(q => q.alreadyAnswered = false);
$('.summary').hide();
$('.quiz').show();
score = 0;
currentQuestion = 0;
showQuestion();
}
function showProgress() {
$('#currentQuestion').html(currentQuestion + " out of " + questions.length);
}
function showIsCorrect(isCorrect) {
var result = "Wrong";
if (isCorrect) {
result = "Correct";
}
$('#isCorrect').html(result);
$('.navigate').show();
$('.submit').hide();
}
$('.navigate').click(function() {
currentQuestion++;
if (currentQuestion >= questions.length) {
showSummary();
} else {
showQuestion();
}
$('.navigate').hide();
$('.submit').show();
$('#isCorrect').html('');
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
text-decoration: none;
text-align: center;
background-color: #837F73;
}
h1 {
font-family: 'Poor Story', cursive;
background-color: #950002;
padding: 60px;
color: #FFAB0D;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
h2 {
font-family: 'Poor Story', cursive;
font-size: 30px;
padding: 60px;
background-color: #950002;
color: #FFAB0D;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
p {
font-family: 'Poor Story', cursive;
background-color: #FFAB0D;
font-size: 20px;
font-weight: bold;
}
a {
border: 1px solid #222F5B;
padding: 10px;
background-color: #222F5B;
color: silver;
border-radius: 5px;
margin-top: 50px;
display: inline-block;
}
a:hover {
border: 1px solid #000000;
background-color: #000000;
color: #FCBF2B;
}
.quiz button {
cursor: pointer;
border: 1px solid;
display: inline-block;
width: 200px;
margin: 10px;
font-family: 'Poor Story', cursive;
font-size: 26px;
}
#currentQuestion {
color: #000000;
font-size: 18px;
font-family: 'Poor Story', cursive;
margin-top: 10px;
}
#isCorrect {
color: white;
font-family: 'Poor Story', cursive;
font-weight: bold;
font-size: 18px;
}
.quiz,
.summary {
display: none;
}
.quiz ul {
margin-top: 20px;
list-style: none;
padding: 0;
}
.selected {
background-color: #398C3F;
}
.wrong {
background-color: red;
}
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Poor+Story" rel="stylesheet">
<link href="style.css" rel="stylesheet" type="text/css" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Harry Potter Quiz</title>
</head>
<body>
<header role="banner">
<div class="start">
<h1>How Well Do You Know Harry Potter?</h1>
Start Quiz
</div>
</header>
<main role="main">
<div class="quiz">
<h2>Question Title</h2>
<div>
<button>Choice</button>
<button>Choice</button>
<button>Choice</button>
<button>Choice</button>
</div>
<a class="submit" href="#">Submit Answer</a>
<a class="navigate" style="display:none;" href="#">Next Question</a>
<div id="currentQuestion"></div>
<footer role="contentinfo">
<div id="isCorrect"></div>
</footer>
</div>
</main>
<div class="summary">
<h2>Results</h2>
<p>Thank you for taking the quiz! Here's how you scored. You answered x out of y correctly! Care to try again?</p>
Retake Quiz
</div>
<script src="index.js"></script>
<!--jQuery script when using JSBin-->
<!--<script src="https://code.jquery.com/jquery-3.1.0.js"></script>-->
</body>
</html>
I have declared a variable called buttonClickable and used it as a flag on every button click. when the user submits the answer, buttonclickable turns false and when ever you are rendering a new question buttonclickable turns true.
let score = 0;
let currentQuestion = 0;
let buttonClickable = true;
let questions = [{
title: "At what age was Harry Potter when he received his Hogwarts letter?",
answers: ['7', '10', '11', '13'],
correct: 1
},
{
title: "Which is not a Hogwarts house?",
answers: ['Dunder Mifflin', 'Ravenclaw', 'Slytherin', 'Gryffindor'],
correct: 0
},
{
title: "Who teaches Transfiguration at Hogwarts?",
answers: ['Rubeus Hagrid', 'Albus Dumbledore', 'Severus Snape', 'Minerva McGonnagle'],
correct: 3
},
{
title: "Where is Hogwarts School for Witchcraft and Wizardry located?",
answers: ['France', 'USA', 'UK', 'New Zealand'],
correct: 2
},
{
title: "What form does Harry Potter's patronus charm take?",
answers: ['Stag', 'Eagle', 'Bear', 'Dragon'],
correct: 0
},
{
title: "What type of animal is Harry's pet?",
answers: ['Dog', 'Owl', 'Cat', 'Snake'],
correct: 1
},
{
title: "Who is not a member of the Order of the Phoenix?",
answers: ['Remus Lupin', 'Siruis Black', 'Lucious Malfoy', 'Severus Snape'],
correct: 2
},
{
title: "What is not a piece of the Deathly Hallows?",
answers: ['Elder Wand', 'Cloak of Invisibility', 'Resurrection Stone', 'Sword of Gryffindor'],
correct: 3
},
{
title: "In which house is Harry sorted into after arriving at Hogwarts?",
answers: ['Slytherin', 'Ravenclaw', 'Gryffindor', 'Hufflepuff'],
correct: 2
},
{
title: "What prevented Voldemort from being able to kill Harry Potter when he was a baby?",
answers: ['Love', 'Anger', 'Friendship', 'Joy'],
correct: 0
},
];
$(document).ready(function() {
$('.start a').click(function(e) {
e.preventDefault();
$('.start').hide();
$('.quiz').show();
showQuestion();
});
$('.quiz').on('click', 'button', function() {
if(!buttonClickable) return;
$('.selected').removeClass('selected');
$(this).addClass('selected');
});
$('.quiz a.submit').click(function(e) {
e.preventDefault();
if ($('button.selected').length) {
let guess = parseInt($('button.selected').attr('id'));
checkAnswer(guess);
} else {
alert('Please select an answer');
}
});
$('.summary a').click(function(e) {
e.preventDefault();
restartQuiz();
});
});
function showQuestion() {
buttonClickable = true;
let question = questions[currentQuestion];
$('.quiz h2').text(question.title);
$('.quiz div:nth-child(2)').html('');
for (var i = 0; i < question.answers.length; i++) {
$('.quiz div:nth-child(2)').append(`<button id="${i}">${question.answers[i]}</button>`);
}
showProgress();
}
function showIncorrectQuestion(guess) {
let question = questions[currentQuestion];
$('.quiz h2').text(question.title);
$('.quiz div:nth-child(2)').html('');
for (var i = 0; i < question.answers.length; i++) {
let cls = i === question.correct ? "selected" : guess === i ? "wrong" : ""
$('.quiz div:nth-child(2)').append(`<button id="${i}" class="${cls}">${question.answers[i]}</button>`);
}
showProgress();
}
function checkAnswer(guess) {
buttonClickable = false;
let question = questions[currentQuestion];
if (question.correct === guess) {
if (!question.alreadyAnswered) {
score++;
}
showIsCorrect(true);
} else {
showIsCorrect(false);
showIncorrectQuestion(guess);
}
question.alreadyAnswered = true;
}
function showSummary() {
$('.quiz').hide();
$('.summary').show();
$('.summary p').text("Thank you for taking the quiz! Here's how you scored. You answered " + score + " out of " + questions.length + " correctly! Care to try again?")
}
function restartQuiz() {
questions.forEach(q => q.alreadyAnswered = false);
$('.summary').hide();
$('.quiz').show();
score = 0;
currentQuestion = 0;
showQuestion();
}
function showProgress() {
$('#currentQuestion').html(currentQuestion + " out of " + questions.length);
}
function showIsCorrect(isCorrect) {
var result = "Wrong";
if (isCorrect) {
result = "Correct";
}
$('#isCorrect').html(result);
$('.navigate').show();
$('.submit').hide();
}
$('.navigate').click(function() {
currentQuestion++;
if (currentQuestion >= questions.length) {
showSummary();
} else {
showQuestion();
}
$('.navigate').hide();
$('.submit').show();
$('#isCorrect').html('');
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
text-decoration: none;
text-align: center;
background-color: #837F73;
}
h1 {
font-family: 'Poor Story', cursive;
background-color: #950002;
padding: 60px;
color: #FFAB0D;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
h2 {
font-family: 'Poor Story', cursive;
font-size: 30px;
padding: 60px;
background-color: #950002;
color: #FFAB0D;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
p {
font-family: 'Poor Story', cursive;
background-color: #FFAB0D;
font-size: 20px;
font-weight: bold;
}
a {
border: 1px solid #222F5B;
padding: 10px;
background-color: #222F5B;
color: silver;
border-radius: 5px;
margin-top: 50px;
display: inline-block;
}
a:hover {
border: 1px solid #000000;
background-color: #000000;
color: #FCBF2B;
}
.quiz button {
cursor: pointer;
border: 1px solid;
display: inline-block;
width: 200px;
margin: 10px;
font-family: 'Poor Story', cursive;
font-size: 26px;
}
#currentQuestion {
color: #000000;
font-size: 18px;
font-family: 'Poor Story', cursive;
margin-top: 10px;
}
#isCorrect {
color: white;
font-family: 'Poor Story', cursive;
font-weight: bold;
font-size: 18px;
}
.quiz,
.summary {
display: none;
}
.quiz ul {
margin-top: 20px;
list-style: none;
padding: 0;
}
.selected {
background-color: #398C3F;
}
.wrong {
background-color: red;
}
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Poor+Story" rel="stylesheet">
<link href="style.css" rel="stylesheet" type="text/css" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Harry Potter Quiz</title>
</head>
<body>
<header role="banner">
<div class="start">
<h1>How Well Do You Know Harry Potter?</h1>
Start Quiz
</div>
</header>
<main role="main">
<div class="quiz">
<h2>Question Title</h2>
<div>
<button>Choice</button>
<button>Choice</button>
<button>Choice</button>
<button>Choice</button>
</div>
<a class="submit" href="#">Submit Answer</a>
<a class="navigate" style="display:none;" href="#">Next Question</a>
<div id="currentQuestion"></div>
<footer role="contentinfo">
<div id="isCorrect"></div>
</footer>
</div>
</main>
<div class="summary">
<h2>Results</h2>
<p>Thank you for taking the quiz! Here's how you scored. You answered x out of y correctly! Care to try again?</p>
Retake Quiz
</div>
<script src="index.js"></script>
<!--jQuery script when using JSBin-->
<!--<script src="https://code.jquery.com/jquery-3.1.0.js"></script>-->
</body>
</html>
Having skimmed through your JS, I'm assuming that the feedback shows on the same page as the question, rather than a new page resulting from submitting it to a server.
When you display the feedback, add a disabled="disabled" property to the item in question, so that your user can't change it. Alternately, hide the selection and display an <output> element: <output>Your Answer: USA<br />Correct Answer: UK</output>
disable All button after checking answers.
$('button').prop('disabled', true);
I took an example of Paged grid from jsfiddle.net ( http://jsfiddle.net/rniemeyer/QSRBR/ ) and put it into one *.html file
But it does not work - I got an error in the browser console:
Uncaught TypeError: Cannot read property 'viewModel' of undefined
at new PagedGridModel (knockout pagination.html:72)
at knockout pagination.html:83
Here is the html file content:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<style>
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; }
.ko-grid { margin-bottom: 1em; width: 25em; border: 1px solid silver; background-color:White; }
.ko-grid th { text-align:left; background-color: Black; color:White; }
.ko-grid td, th { padding: 0.4em; }
.ko-grid tr:nth-child(odd) { background-color: #DDD; }
.ko-grid-pageLinks { margin-bottom: 1em; }
.ko-grid-pageLinks a { padding: 0.5em; }
.ko-grid-pageLinks a.selected { background-color: Black; color: White; }
.liveExample { height:20em; overflow:auto } /* Mobile Safari reflows pages slowly, so fix the height to avoid the need for reflows */
li { list-style-type: disc; margin-left: 20px; }
</style>
</head>
<body>
<div class='liveExample'>
<div data-bind='simpleGrid: gridViewModel'> </div>
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
</div>
<script type="text/javascript">
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var PagedGridModel = function(items) {
this.items = ko.observableArray(items);
this.addItem = function() {
this.items.push({ name: "New item", sales: 0, price: 100 });
};
this.sortByName = function() {
this.items.sort(function(a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function() {
this.gridViewModel.currentPageIndex(0);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});
};
ko.applyBindings(new PagedGridModel(initialData));
</script>
</body>
</html>
This code works fine at jsfiddle but why doesn't it work when I put it all together an a single file?
var cards = [
{
rank: "Queen",
suit: "Hearts",
cardImage: "images/queen-of-hearts.png",
id: 0,
},
{
rank: "Queen",
suit: "Diamonds",
cardImage: "images/queen-of-diamonds.png",
id: 1,
},
{
rank: "King",
suit: "Hearts",
cardImage: "images/king-of-hearts.png",
id: 2,
},
{
rank: "King",
suit: "Diamonds",
cardImage: "images/king-of-diamonds.png",
id: 3
}
];
//1
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var cardElement = document.createElement('img');
// console.log(cardElement);
cardElement.setAttribute('src', 'images/back.png');
cardElement.setAttribute('data-id', i);
document.getElementById('game-board').appendChild(cardElement);
cardElement.addEventListener('click', flipCard);
cardElement.style.width = '210px';
}
}
createBoard();
//2
function flipCard () {
var cardId = this.getAttribute('data-id');
cardsInPlay.push(cards[cardId].rank);
cardsInPlay.push(cards[cardId].id);
this.setAttribute('src', cards[cardId].cardImage);
// CHECK FOR MATCH HERE =>
if (cardsInPlay.length === 2) {
if (cardsInPlay[0] === cardsInPlay[1]) {
alert("You found a match!");
}
else {
alert("Sorry, try again.");
console.log(cardsInPlay);
cardsInPlay[0].setAttribute('src', 'images/back.png'); // this doesnt work
cardsInPlay[1].setAttribute('src', 'images/back.png'); // this doesnt work
}
}
}
var cardsInPlay = [];
body{
text-align: center;
margin: 0;
}
h1 {
font-family: "Raleway", sans-serif;
font-weight: 400;
color: #0d2c40;
font-size: 45px;
letter-spacing: 1px;
margin: 0;
color: white;
}
p {
font-family: "Droid Serif", serif;
line-height: 26px;
font-size: 18px;
}
a {
font-family: raleway;
text-decoration: none;
color: #F15B31;
letter-spacing: 1px;
font-weight: 600;
font-size: 18px;
}
h2 {
font-family: raleway;
font-size: 20px;
color: #0d2c40;
letter-spacing: 1px;
font-weight: 600;
}
header {
background-color: #F15B31;
padding: 30px 20px 30px 20px;
}
main {
width: 850px;
margin: 35px auto
}
a {
margin: 0 20px;
color: white;
}
nav a:hover {
border-bottom: 2px solid white;
}
nav {
background-color: #00A6B3;
padding: 20px 0;
}
img {
margin: 40px 8px 0 8px;
}
footer {
text-transform: uppercase;
padding: 0 20px;
background-color: #0D2C40;
color: white;
letter-spacing: .08em;
font-weight: 500;
}
.copyright {
float: left;
}
.message {
float: right;
}
.clearfix:after {
visibility: hidden;
display: block;
content: " ";
clear: both;
height: 0;
font-size: 0;
}
.name {
color: #F15B31;
font-weight: 700;
}
#game-board{
width: 1200px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="css/style.css" rel="stylesheet" type="text/css">
<title>Memory card game</title>
</head>
<body>
<header>
<h1>Memory Game</h1>
</header>
<nav>
<p>INSTRUCTIONS GAME</p>
</nav>
<main>
<h2>INSTRUCTIONS</h2>
<p>Concentration, also known as Match Match, Memory, Pelmanism, Shinkei-suijaku, Pexeso or simply Pairs, is a card game in which all of the cards are laid face down on a surface and two cards are flipped face up over each turn. The object of the game is to turn over pairs of matching cards.</p>
<div id="game-board" class="board clearfix"></div>
</main>
<footer>
<div class="clearfix">
<p class="copyright">Copyright 2017</p>
<p class="message">Created with ♥ by <span class="name">GA</span></p>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>
I want to know how I can turn back to its original position BOTH cards that didn't match. If there is a match, there is an alert saying congrats you win, OTHERWISE try again, but i want that two cards to return to its original position if didnt match. BUT ONLY ONE CARD TURN BACK TO ITS ORIGINAL POSITION(the one with the this , but I thought the this refers to both) The card images are not in here. Can someone help with this please?
var cards = [
{
rank: "Queen",
suit: "Hearts",
cardImage: "images/queen-of-hearts.png",
id: 0,
},
{
rank: "Queen",
suit: "Diamonds",
cardImage: "images/queen-of-diamonds.png",
id: 1,
},
{
rank: "King",
suit: "Hearts",
cardImage: "images/king-of-hearts.png",
id: 2,
},
{
rank: "King",
suit: "Diamonds",
cardImage: "images/king-of-diamonds.png",
id: 3
}
];
//1
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var cardElement = document.createElement('img');
// console.log(cardElement);
cardElement.setAttribute('src', 'images/back.png');
cardElement.setAttribute('data-id', i);
document.getElementById('game-board').appendChild(cardElement);
cardElement.addEventListener('click', flipCard);
cardElement.style.width = '210px';
}
}
createBoard();
//2
function flipCard () {
var cardId = this.getAttribute('data-id');
cardsInPlay.push(cards[cardId].rank);
cardsInPlay.push(cards[cardId].id);
this.setAttribute('src', cards[cardId].cardImage);
// CHECK FOR MATCH HERE =>
if (cardsInPlay.length === 2) {
if (cardsInPlay[0] === cardsInPlay[1]) {
alert("You found a match!");
}
else {
alert("Sorry, try again.");
console.log(cardsInPlay);
cardsInPlay[0].setAttribute('src', 'images/back.png'); // this doesnt work
cardsInPlay[1].setAttribute('src', 'images/back.png'); // this doesnt work
}
}
}
var cardsInPlay = [];
body{
text-align: center;
margin: 0;
}
h1 {
font-family: "Raleway", sans-serif;
font-weight: 400;
color: #0d2c40;
font-size: 45px;
letter-spacing: 1px;
margin: 0;
color: white;
}
p {
font-family: "Droid Serif", serif;
line-height: 26px;
font-size: 18px;
}
a {
font-family: raleway;
text-decoration: none;
color: #F15B31;
letter-spacing: 1px;
font-weight: 600;
font-size: 18px;
}
h2 {
font-family: raleway;
font-size: 20px;
color: #0d2c40;
letter-spacing: 1px;
font-weight: 600;
}
header {
background-color: #F15B31;
padding: 30px 20px 30px 20px;
}
main {
width: 850px;
margin: 35px auto
}
a {
margin: 0 20px;
color: white;
}
nav a:hover {
border-bottom: 2px solid white;
}
nav {
background-color: #00A6B3;
padding: 20px 0;
}
img {
margin: 40px 8px 0 8px;
}
footer {
text-transform: uppercase;
padding: 0 20px;
background-color: #0D2C40;
color: white;
letter-spacing: .08em;
font-weight: 500;
}
.copyright {
float: left;
}
.message {
float: right;
}
.clearfix:after {
visibility: hidden;
display: block;
content: " ";
clear: both;
height: 0;
font-size: 0;
}
.name {
color: #F15B31;
font-weight: 700;
}
#game-board{
width: 1200px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="css/style.css" rel="stylesheet" type="text/css">
<title>Memory card game</title>
</head>
<body>
<header>
<h1>Memory Game</h1>
</header>
<nav>
<p>INSTRUCTIONS GAME</p>
</nav>
<main>
<h2>INSTRUCTIONS</h2>
<p>Concentration, also known as Match Match, Memory, Pelmanism, Shinkei-suijaku, Pexeso or simply Pairs, is a card game in which all of the cards are laid face down on a surface and two cards are flipped face up over each turn. The object of the game is to turn over pairs of matching cards.</p>
<div id="game-board" class="board clearfix"></div>
</main>
<footer>
<div class="clearfix">
<p class="copyright">Copyright 2017</p>
<p class="message">Created with ♥ by <span class="name">GA</span></p>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>
If you are trying to flip both cards back, this code only flips the last card in play "cardsInPlay[1]":
this.setAttribute('src', 'images/back.png');
What you want is to flip both "cardsInPlay[0]" and "cardsInPlay[1]" so maybe somethign like this:
else {
alert("Sorry, try again.");
console.log(cardsInPlay);
cardsInPlay[0].setAttribute('src', 'images/back.png');
cardsInPlay[1].setAttribute('src', 'images/back.png');
}
EDIT: your problem with this is about closure in javascript. I recommend you use IIFE (for EcmaScript5) or let keyword (for EcmaScript6). Read more here.
Instead of doing this:
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var cardElement = document.createElement('img');
[..]
cardElement.addEventListener('click', flipCard); << 'this' will refer to last cardElement at the end of the loop
Do this:
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var cardElement = document.createElement('img');
[..]
cardElement.addEventListener('click', (function(x) {return function() {flipCard(x)}})(i)); // 'i' is immediately evaluated to the correct value
cards[i].element = cardElement; // Keep association with DOM here
Now you can flip cards back easily.
function flipCard (i) {
cardsInPlay.push(i);
// Flip played card
cards[i].element.setAttribute('src', cards[i].cardImage);
if (cardsInPlay.length === 1)
return; // First card: no game resolution yet
// Second card: give user 1s to see it flipped before flipping back
setTimeout(function(){
if (cards[cardsInPlay[0]].rank === cards[cardsInPlay[1]].rank)
alert("You found a match!");
else
alert("Sorry, try again.");
cardsInPlay.forEach(function(i) {
cards[i].element.setAttribute('src', 'images/back.png');
});
cardsInPlay.length = 0;
}, 1000);
}
The below snippet is modified to achieve the required functionality! can you please check?
var cards = [
{
rank: "Queen",
suit: "Hearts",
cardImage: "http://via.placeholder.com/350x150?text=QueenHeartsfront"
},
{
rank: "Queen",
suit: "Diamonds",
cardImage: "http://via.placeholder.com/350x150?text=QueenDiamondsfront"
},
{
rank: "King",
suit: "Hearts",
cardImage: "http://via.placeholder.com/350x150?text=KingHeartsfront"
},
{
rank: "King",
suit: "Diamonds",
cardImage: "http://via.placeholder.com/350x150?text=KingDiamondsfront"
}
];
//1 CREATE BOARD
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var cardElement = document.createElement('img');
// console.log(cardElement);
cardElement.setAttribute('src', 'http://via.placeholder.com/350x150?text=back');
cardElement.setAttribute('data-id', i);
document.getElementById('game-board').appendChild(cardElement);
cardElement.addEventListener('click', flipCard);
cardElement.style.width = '210px';
}
}
createBoard();
var prev = "";
//2 FLIPCARD
function flipCard () {
var cardId = this.getAttribute('data-id');
cardsInPlay.push(cards[cardId].rank);
this.setAttribute('src', cards[cardId].cardImage);
console.log(cardsInPlay[0]);
console.log(cardsInPlay[1]);
if (cardsInPlay.length === 2) {
if (cardsInPlay[0] === cardsInPlay[1]) {
alert("You found a match!");
cardsInPlay = [];
}
else {
alert("Sorry, try again.");
cardsInPlay = [];
// cardsInPlay.pop();
// cardsInPlay.pop();
// console.log(cardsInPlay);
try{
prev.setAttribute('src', 'http://via.placeholder.com/350x150?text=back');
}catch(e){}
this.setAttribute('src', 'http://via.placeholder.com/350x150?text=back');
}
}
prev = this;
}
var cardsInPlay = [];
body{
text-align: center;
margin: 0;
}
h1 {
font-family: "Raleway", sans-serif;
font-weight: 400;
color: #0d2c40;
font-size: 45px;
letter-spacing: 1px;
margin: 0;
color: white;
}
p {
font-family: "Droid Serif", serif;
line-height: 26px;
font-size: 18px;
}
a {
font-family: raleway;
text-decoration: none;
color: #F15B31;
letter-spacing: 1px;
font-weight: 600;
font-size: 18px;
}
h2 {
font-family: raleway;
font-size: 20px;
color: #0d2c40;
letter-spacing: 1px;
font-weight: 600;
}
header {
background-color: #F15B31;
padding: 30px 20px 30px 20px;
}
main {
width: 850px;
margin: 35px auto
}
a {
margin: 0 20px;
color: white;
}
nav a:hover {
border-bottom: 2px solid white;
}
nav {
background-color: #00A6B3;
padding: 20px 0;
}
img {
margin: 40px 8px 0 8px;
}
footer {
text-transform: uppercase;
padding: 0 20px;
background-color: #0D2C40;
color: white;
letter-spacing: .08em;
font-weight: 500;
}
.copyright {
float: left;
}
.message {
float: right;
}
.clearfix:after {
visibility: hidden;
display: block;
content: " ";
clear: both;
height: 0;
font-size: 0;
}
.name {
color: #F15B31;
font-weight: 700;
}
#game-board{
width: 1200px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="css/style.css" rel="stylesheet" type="text/css">
<title>Memory card game</title>
</head>
<body>
<header>
<h1>Memory Game</h1>
</header>
<nav>
<p>INSTRUCTIONS GAME</p>
</nav>
<main>
<h2>INSTRUCTIONS</h2>
<p>Concentration, also known as Match Match, Memory, Pelmanism, Shinkei-suijaku, Pexeso or simply Pairs, is a card game in which all of the cards are laid face down on a surface and two cards are flipped face up over each turn. The object of the game is to turn over pairs of matching cards.</p>
<div id="game-board" class="board clearfix"></div>
</main>
<footer>
<div class="clearfix">
<p class="copyright">Copyright 2017</p>
<p class="message">Created with ♥ by <span class="name">GA</span></p>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>
I am newbe in knowkout js and i am trying Paged grid example of knowkout from
http://knockoutjs.com/examples/gridEditor.html
Here is my code :
Its giving error TypeError: ko.simpleGrid is undefined
Please help me in this thanx in adv.
<html>
<head>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" type="text/javascript"></script>
<script src='http://knockoutjs.com/examples/resources/knockout.simpleGrid.js'></script>
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.debug.js" type="text/javascript"></script>
<script>
var initialData = [
{name: "Well-Travelled Kitten", sales: 352, price: 75.95},
{name: "Speedy Coyote", sales: 89, price: 190.00},
{name: "Furious Lizard", sales: 152, price: 25.00},
{name: "Indifferent Monkey", sales: 1, price: 99.95},
{name: "Brooding Dragon", sales: 0, price: 6350},
{name: "Ingenious Tadpole", sales: 39450, price: 0.35},
{name: "Optimistic Snail", sales: 420, price: 1.50}
];
var PagedGridModel = function (items) {
this.items = ko.observableArray(items);
this.addItem = function () {
this.items.push({name: "New item", sales: 0, price: 100});
};
this.sortByName = function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function () {
this.gridViewModel.currentPageIndex(0);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{headerText: "Item Name", rowText: "name"},
{headerText: "Sales Count", rowText: "sales"},
{headerText: "Price", rowText: function (item) {
return "$" + item.price.toFixed(2)
}}
],
pageSize: 4
});
};
ko.applyBindings(new PagedGridModel(initialData));
</script>
<style>
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; }
.ko-grid { margin-bottom: 1em; width: 25em; border: 1px solid silver; background-color:White; }
.ko-grid th { text-align:left; background-color: Black; color:White; }
.ko-grid td, th { padding: 0.4em; }
.ko-grid tr:nth-child(odd) { background-color: #DDD; }
.ko-grid-pageLinks { margin-bottom: 1em; }
.ko-grid-pageLinks a { padding: 0.5em; }
.ko-grid-pageLinks a.selected { background-color: Black; color: White; }
.liveExample { height:20em; overflow:auto } /* Mobile Safari reflows pages slowly, so fix the height to avoid the need for reflows */
li { list-style-type: disc; margin-left: 20px; }
</style>
</head>
<body>
<div data-bind='simpleGrid: gridViewModel'> </div>
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
</body>
</html>