I have problem while calling jquery functions it generates double output while when we do highlight questions and crossout on html content sometimes highlight and crossout also not working with selecting using Ctrl+A or select all.
highlight and crossout values i am storing to database so, we can remain next time in questions.
I am trying and just needs to works it well.
Click Here For Output
HTML Code
<style>
.highlight{background:yellow;}
.crossout{text-decoration: line-through;}
</style>
<input type="button" onClick="return false;" id="btn_highlight" unselectable="on" value="highlight" class="unselectable" alt="highlight" width="36" height="38">
<input type="button" onClick="return false;" id="btn_crossout" unselectable="on" value="crossout" class="unselectable" alt="crossout" width="36" height="38" />
<input name="highlight" id="highlight" type="text" value=""/>
<input name="crossout" id="crossout" type="text" value=""/>
<div class="highlight_area">
<div id="high" class="question_area">
<div class="question_stem">
<p>A 47-year-old male with chronic kidney disease and peptic ulcer disease presents to the emergency room with chest pain. The patient states the pain increases with breathing and radiates to his back but improves with leaning forward. He states that he recently had a viral upper respiratory infection that left him with a cough for the past 3 weeks. An echocardiogram is ordered which appears normal. EKG shows diffuse ST segment elevations with PR depression. What is the most appropriate treatment at this time?</p>
</div>
<br>
</div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer11" value="1"><label for="answer11">A. NSAID only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer22" value="2"><label for="answer22">B. Colchicine only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer33" value="3"><label for="answer33">C. NSAIDS and colchicine</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer44" value="4"><label for="answer44">D. Corticosteroids</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer55" value="5"><label for="answer55">E. Dialysis</label></div>
<input type="hidden" name="data[Answer][correct]" value="2" id="AnswerCorrect">
</div>
jQuery Code
$(document).on('click', '#btn_highlight', function() {
select('#highlight');
apply('highlight');
});
$(document).on('click', '#btn_crossout', function() {
select('#crossout');
apply('crossout');
});
function select(id) {
function append(id, begin, end) {
// console.log('Add: ' + begin + ' to ' + end);
var highlights = $(id).val().trim().split(',');
var start = -1;
var done = -1;
var duplicate = -1;
var inside = -1;
var out = [];
var previous = 99999999;
var on = false;
for (x in highlights) {
var mark = highlights[x];
if (!mark) continue;
// console.log('Check: ' + mark + ' Start: ' + start + ' End: ' + done);
if (duplicate == mark) {
// console.log('Repeated mark');
out.push(mark);
}
if (done >= 0) {
out.push(mark);
continue;
} else if (start < 0) {
if (end < mark) {
// console.log('Prepend new');
out.push(begin);
out.push(end);
out.push(mark);
start = mark;
done = end;
} else if (end == mark || begin < mark) {
if (!on && end <= mark) {
// console.log('Prepend consecutive');
out.push(begin);
out.push(end);
out.push(mark);
done = mark;
} else if (on) {
// console.log('Start inside');
inside = begin
} else {
// console.log('Start new');
out.push(begin);
}
start = begin;
} else if (begin == mark) {
// console.log('Start overlapped');
duplicate = mark;
start = mark;
} else {
// console.log('Skip one');
out.push(mark);
}
}
if (done < 0 && start >= 0) {
if (end == mark) {
if (inside >= 0) {
// console.log('End overlapped from inside');
out.push(inside);
on = !on;
} else if (duplicate < 0) {
// console.log('End overlapped from outside');
out.push(end);
}
done = mark;
} else if (end > previous && end < mark) {
if (!on || duplicate >= 0) {
// console.log('End new');
out.push(end);
}
out.push(mark);
done = mark;
}
}
on = !on;
// console.log(out);
previous = mark;
}
if (done < 0) {
if (duplicate >= 0 && begin == mark) {
out.push(begin);
out.push(begin);
out.push(end);
} else {
if (start < 0) {
out.push(begin);
} else if (duplicate >= 0) {
// console.log('End from duplicate');
out.push(duplicate);
}
out.push(end);
}
}
$(id).val(out.toString().trim(','));
// console.log(id + ': ' + $(id).val());
if (out.length % 2 != 0) {
console.log('Error!');
}
}
var temp = '#temp';
function getIndex(elem, offset) {
var parent = $(elem).parents('.highlight_area');
elem.nodeValue = temp + elem.nodeValue;
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.nodeValue = elem.nodeValue.substr(temp.length);
return offset;
}
function getIndex2(elem, offset) {
var parent = elem.parents('.highlight_area');
elem.text(temp + elem.text());
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.text(elem.text().substr(temp.length));
return offset;
}
function getElem(node) {
if (node.is('.highlight,.crossout')) {
node = node.parent();
}
return node;
}
var highlight = window.getSelection();
// console.log(highlight);
var base = highlight.focusNode;
var anchor = highlight.anchorNode;
var baseOffset = highlight.focusOffset;
var anchorOffset = highlight.anchorOffset;
if (!highlight.rangeCount || !$(base).parents('.highlight_area').length || !$(anchor).parents('.highlight_area').length) {
// console.log(highlight.rangeCount + ' ; ' + $(base).parents('.highlight_area').length + ' ; ' + $(anchor).parents('.highlight_area').length);
return;
}
baseOffset = getIndex(base, baseOffset);
anchorOffset = getIndex(anchor, anchorOffset);
var stem = $('.highlight_area');
var baseIndex = getElem($(base.parentElement)).index();
var anchorIndex = getElem($(anchor.parentElement)).index();
var start = Math.min(baseOffset, anchorOffset);
var end = Math.max(baseOffset, anchorOffset);
// console.log('Offset: ' + start + ' to ' + end);
// console.log('Indexes: ' + baseIndex + ' v ' + anchorIndex);
if (baseIndex == anchorIndex) {
append(id, start, end);
} else {
var children = stem.find(':not(.highlight,.crossout)');
var startIndex = Math.min(baseIndex, anchorIndex);
var endIndex = Math.max(baseIndex, anchorIndex);
var child = $(children[startIndex]);
var text = child.text();
var textStart = getIndex2(child, text.length);
append(id, start, textStart);
for (var i = startIndex + 1; i < endIndex; i++) {
child = $(children[i]);
text = child.text();
if (!text.trim().length) continue;
append(id, textStart, textStart + text.length);
textStart = textStart + text.length;
}
var child = $(children[endIndex]);
var textStart = getIndex2(child, 0);
append(id, textStart, end);
}
}
function apply() {
var highlights = $('#highlight').val().split(',');
var crossouts = $('#crossout').val().split(',');
var marks = {};
for (x in highlights) {
if (typeof marks[highlights[x]] != 'undefined') {
// 2 consecutive highlights
marks[highlights[x]] = 4;
} else {
marks[highlights[x]] = 1;
}
}
for (x in crossouts) {
if (typeof marks[crossouts[x]] == 'undefined') {
marks[crossouts[x]] = 2;
} else {
if (marks[crossouts[x]] == 4) {
// 2 highlights and a crossout
marks[crossouts[x]] = 6;
} else if (marks[crossouts[x]] == 2) {
// 2 consecutive crossouts
marks[crossouts[x]] = 5;
} else if (marks[crossouts[x]] == 6) {
// 2 consecutive highlights and crossouts
marks[crossouts[x]] = 7;
} else if (marks[crossouts[x]] == 3) {
// 2 consecutive crossouts and highlight
marks[crossouts[x]] = 8;
} else {
// highlight and crossout
marks[crossouts[x]] = 3;
}
}
}
var stem = $('.highlight_area');
var children = stem.find(':not(.highlight,.crossout)');
var childIndex = 0;
var child = $(children[childIndex]);
var text = child.text().replace(/(<([^>]+)>)/ig, "");
var high = false;
var cross = false;
var previousMark = 0;
var passedChars = 0;
var mode = 0;
var string = '';
var nextEdge = 0;
stem.empty();
child.empty();
var first = true;
var maxLoop = 10;
for (x in marks) {
if (x == '') continue;
// console.log('Mark: ' + x);
nextEdge = 1 * passedChars + 1 * text.length;
// console.log('Next edge: ' + nextEdge);
var loopCount = 0;
while (x > nextEdge && loopCount++ < maxLoop) {
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
passedChars = 1 * passedChars + 1 * text.length;
previousMark = passedChars;
// move on to next
childIndex = childIndex + 1;
child = $(children[childIndex]);
text = child.text();
child.empty();
nextEdge = 1 * text.length + 1 * passedChars;
// console.log('Next edge : ' + nextEdge);
}
// console.log('Select: ' + previousMark + ' to ' + x);
string = text.substr(previousMark - passedChars, x - previousMark);
// console.log(string);
var type = '';
if (high) {
type = type + ' highlight';
}
if (cross) {
type = type + ' crossout';
}
if (type) {
var span = $('<span></span>').addClass(type);
span.text(string);
child.append(span);
} else {
child.append(string);
}
previousMark = x;
if (marks[x] == 1) {
high = !high;
} else if (marks[x] == 2) {
cross = !cross;
} else if (marks[x] == 3) {
high = !high;
cross = !cross;
} else if (marks[x] == 4) {
high = true;
} else if (marks[x] == 5) {
cross = true;
} else if (marks[x] == 6) {
high = true;
cross = !cross;
} else if (marks[x] == 7) {
high = true;
cross = true;
} else if (marks[x] == 8) {
high = !high;
cross = true;
}
}
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
childIndex = childIndex + 1;
while (childIndex < children.length) {
child = $(children[childIndex]);
child.find('.highlight,.crossout').each(function(i, e) {
child.html(child.html().replace($(e).outerHtml(), $(e).text()));
});
stem.append(child);
childIndex = childIndex + 1;
}
}
apply();
Related
--SOLVED--
I was just forgetting to reset the number of flags after each game.
I'm having issues with the number of flags in my minesweeper game. For some reason, sometimes when I flag a tile the number of flags increases by more than 1. Sometimes it increases by 3, sometimes 4, sometimes 7. I can't find the issue in my logic, so I was hoping to get another set of eyes on it.
The only sort of pattern I can see when it adds more flags than it should, i.e. the flags variable is incremented more than once, is when I flag a tile that is mostly surrounded by revealed tiles.
Javascript:
var flags = 0;
var trueFlags = 0;
function newGame() {
var cols = $("#width").val();
var rows = $("#height").val();
if (cols < 8 || rows < 8) {
return;
}else if (cols > 40 || rows > 30) {
return;
}
boardClear();
possibleBombs = (rows * cols) - 1;
numBombs = 0;
for (var i = 1; i <= rows; i++) {
for (var j = 1; j <= cols; j++) {
if (numBombs < possibleBombs) {
var q = Math.floor(Math.random() * 50);
if (0 <= q && q <= 2) {
numBombs += 1;
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 0 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
}
else {
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + 'data-flagged = ' + false + '></button>').prop("revealed", false);
}
}
else {
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
}
}
$("#board").append("<br/>");
}
$(".controls h2").text("Bombs to go: " + numBombs);
$(".tile").css("background-color", "white");
$(".tile").width(15);
$(".tile").height(15);
console.log("bombs: " + numBombs, "possible: " + possibleBombs);
$(".tile").click(function(e) {
if (e.shiftKey) {
flagKey($(this));
$(".controls h2").text("Bombs to go: " + (numBombs - flags));
}
else if ($(this).data("contains") == 0) {
console.log("you lose");
boardClear();
newGame();
return;
}
else {
revealNeighbors($(this));
// if (gameWon() == true) {
// alert("You have won!");
// newGame();
// }
return;
}
});
}
function boardClear() {
$("#board").empty();
}
function revealNeighbors(tile) {
var cordsx = tile.data("row");
var cordsy = tile.data("col");
// tile has bomb
if(tile.data("contains") == 0) {return;}
// tile is flagged
else if(tile.data("flagged") == true){return;}
// tile has been revealead already
else if(tile.prop("revealed") == true) {return;}
// reveal the tile
var tileBombs = nearbyBombCount(tile);
tile.prop("revealed", true);
tile.text(tileBombs);
tile.css("background-color", "grey");
if (tileBombs == 0){tile.text("");}
else if(tileBombs != 0) {return;}
for (var i = -1; i <= 1; i++) {
for (var j = -1; j <= 1; j++) {
if (cordsx + i < 1 || cordsy + j < 1) {continue;}
else if (cordsx + i > $("#width").val() || cordsy + j > $("#height").val()) {continue;}
else if (i == 0 && j == 0) {continue;}
var neighbor = $('.tile[data-row="' + (cordsx+i) + '"][data-col ="'+(cordsy+j)+'"]');
revealNeighbors(neighbor);
}
}
}
function nearbyBombCount(tile) {
var cx = tile.data("row");
var cy = tile.data("col");
var nearbyBombs = 0;
for (var n = -1; n < 2; n++) {
for (var m = -1; m < 2; m++) {
if (cx + n < 1 || cy + m < 1) {continue;}
else if (cx + n > $("#width").val() || cy + m > $("#height").val()) {continue;}
var neighbor = $('.tile[data-row="' + (cx+n) + '"][data-col ="'+(cy+m)+'"]');
if (neighbor.data("contains") == 0) {
nearbyBombs++;
}
}
}
return nearbyBombs;
}
function flagKey(tile) {
// tile is already revealed
if (tile.data("revealed") == true) {
return;
}
// tile is already flagged
else if (tile.data("flagged") == true) {
tile.data("flagged", false);
tile.css("background-color", "white");
flags--;
// contains bomb
if (tile.data("contains") == 0) {
trueFlags--;
}
return;
}
// tile not flagged
else if (tile.data("flagged") == false) {
flags++;
tile.data("flagged", true);
tile.css("background-color", "red");
// contains bomb
if (tile.data("contains") == 0) {
trueFlags++;
console.log(trueFlags);
}
}
else {
return;
}
}
My guess is that there's something wrong with my revealNeighbors() function or it's some scope issue, but I can't for the life of me figure out what it is.
Hi I change a litle and works fine
<html>
<head>
<style>
.tile{padding:5px;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
Width : <input type="text" id="width" value="15" /> Height :<input type="text" id="height" value="15" /><input type="button" onclick="newGame()" id="btnstart" value="start" />
<br />
<div>
<div id="board" >
</div>
</div>
<script>
var flags = 0;
var trueFlags = 0;
function newGame() {
var cols = $("#width").val();
var rows = $("#height").val();
if (cols < 8 || rows < 8) {
return;
}else if (cols > 40 || rows > 30) {
return;
}
boardClear();
possibleBombs = (rows * cols) - 1;
numBombs = 0;
for (var i = 1; i <= rows; i++) {
for (var j = 1; j <= cols; j++) {
if (numBombs < possibleBombs) {
var q = Math.floor(Math.random() * 50) + 1;
if (q <= 2) {
numBombs += 1;
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 0 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
}
else {
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + 'data-flagged = ' + false + '></button>').prop("revealed", false);
}
}
else {
$("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
}
}
$("#board").append("<br/>");
}
$(".controls h2").text("Bombs to go: " + numBombs);
$(".tile").css("background-color", "white");
$(".tile").width(15);
$(".tile").height(15);
console.log("bombs: " + numBombs, "possible: " + possibleBombs);
$(".tile").click(function (e) {
if (e.shiftKey) {
flagKey($(this));
$(".controls h2").text("Bombs to go: " + (numBombs - flags));
}
else if ($(this).data("contains") == 0) {
console.log("you lose");
boardClear();
newGame();
return;
}
else {
revealNeighbors($(this));
// if (gameWon() == true) {
// alert("You have won!");
// newGame();
// }
return;
}
});
}
function boardClear() {
$("#board").empty();
}
function revealNeighbors(tile) {
var cordsx = tile.data("row");
var cordsy = tile.data("col");
// tile has bomb
if(tile.data("contains") == 0) {return;}
// tile is flagged
else if(tile.data("flagged") == true){return;}
// tile has been revealead already
else if(tile.prop("revealed") == true) {return;}
// reveal the tile
var tileBombs = nearbyBombCount(tile);
tile.prop("revealed", true);
tile.text(tileBombs);
tile.css("background-color", "grey");
if (tileBombs == 0){tile.text("");}
else if(tileBombs != 0) {return;}
for (var i = -1; i <= 1; i++) {
for (var j = -1; j <= 1; j++) {
if (cordsx + i < 1 || cordsy + j < 1) {continue;}
else if (cordsx + i > $("#width").val() || cordsy + j > $("#height").val()) {continue;}
else if (i == 0 && j == 0) {continue;}
var neighbor = $('.tile[data-row="' + (cordsx+i) + '"][data-col ="'+(cordsy+j)+'"]');
revealNeighbors(neighbor);
}
}
}
function nearbyBombCount(tile) {
var cx = tile.data("row");
var cy = tile.data("col");
var nearbyBombs = 0;
for (var n = -1; n < 2; n++) {
for (var m = -1; m < 2; m++) {
if (cx + n < 1 || cy + m < 1) {continue;}
else if (cx + n > $("#width").val() || cy + m > $("#height").val()) {continue;}
var neighbor = $('.tile[data-row="' + (cx+n) + '"][data-col ="'+(cy+m)+'"]');
if (neighbor.data("contains") == 0) {
nearbyBombs++;
}
}
}
return nearbyBombs;
}
function flagKey(tile) {
// tile is already revealed
if (tile.data("revealed") == true) {
return;
}
// tile is already flagged
else if (tile.data("flagged") == true) {
tile.data("flagged", false);
tile.css("background-color", "white");
flags--;
// contains bomb
if (tile.data("contains") == 0) {
trueFlags--;
}
return;
}
// tile not flagged
else if (tile.data("flagged") == false) {
flags++;
tile.data("flagged", true);
tile.css("background-color", "red");
// contains bomb
if (tile.data("contains") == 0) {
trueFlags++;
console.log(trueFlags);
}
}
else {
return;
}
}
</script>
</body>
</html>
i am trying to create a function that automatically create questions to do.
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var totalvar = getRandomInt(2,4);
var main = "";
for (var i = 1; i <= totalvar; i++) {
var test = getRandomInt(1,3);
// alert(test);
var myArray = ["A","B","C","A'","B'","C'"];
var text ="";
for (var a = 1; a <= test; a++) {
function random(array) {
return array[Math.floor(Math.random() * array.length)]
}
var testing = random(myArray);
if (testing =="A") {
var testing2 ="A'";
} else if (testing =="A'") {
var testing2 ="A";
} else if (testing =="B") {
var testing2 ="B'";
} else if (testing =="B'") {
var testing2 ="B";
}else if (testing =="C") {
var testing2 ="C'";
} else if (testing =="C'") {
var testing2 ="C";
}
//alert(testing);
//alert(myArray);
text += testing
var index = myArray.indexOf(testing);
if (index > -1) {
myArray.splice(index, 1);
}
var index = myArray.indexOf(testing2);
if (index > -1) {
myArray.splice(index, 1);
}
}
var brackets = getRandomInt(1,3);
var chances = getRandomInt(1,3);
var lastLetter = main.charAt(main.length - 1);
if (brackets == 1) {
text = "(" + text + ")";
if (main == "") {
main = text;
} else if ( lastLetter == ')') {
if ( chances !== 1) {
main += text;
}else
main += "+" + text;
}else
main += "+" + text;
} else {
if (main == "") {
main = text;
} else if ( lastLetter == ')') {
if ( chances !== 1) {
main += text;
}else
main += "+" + text;
}else
main += "+" + text;
}
}
I have manage to get it to display questions that i want
B'C'+(A'C'B')+BCA
B+(C')(CAB)
A'BC+(C')A+AB'
B'C'+AB(A'C'B')+BCA
I am stucked as i couldnt get the function for the next step where it multiples the value outside the bracket
B'C'+A'C'B'+BCA
B+C'CAB
A'BC+C'A+AB'
B'C'+ABA'C'B'+BCA
The above is what i hope to achieve but im unable to create the function out
any tips guys?
use replace:
var str = "B'C'+(A'C'B')+BCA";
var response = str.replace(/([\(\)]+)/g, '');
console.log(response);
// output: "B'C'+A'C'B'+BCA"
Highlight and Crossout values i am storing to database so, we can remain next time in questions I just want to be worked highlight and crossout in html using jquery same way or another way.
I am trying this code and sometimes it generates problem while calling jQuery functions it generates double output while when we do highlight questions and crossout on html content sometimes highlight and crossout also not working with selecting using Ctrl+A or select all with my code.
Click Here For Output
HTML:
<style>
.highlight{background:yellow;}
.crossout{text-decoration: line-through;}
</style>
<input type="button" onClick="return false;" id="btn_highlight" unselectable="on" value="highlight" class="unselectable" alt="highlight" width="36" height="38">
<input type="button" onClick="return false;" id="btn_crossout" unselectable="on" value="crossout" class="unselectable" alt="crossout" width="36" height="38" />
<input name="highlight" id="highlight" type="text" value=""/>
<input name="crossout" id="crossout" type="text" value=""/>
<div class="highlight_area">
<div id="high" class="question_area">
<div class="question_stem">
<p>A 47-year-old male with chronic kidney disease and peptic ulcer disease presents to the emergency room with chest pain. The patient states the pain increases with breathing and radiates to his back but improves with leaning forward. He states that he recently had a viral upper respiratory infection that left him with a cough for the past 3 weeks. An echocardiogram is ordered which appears normal. EKG shows diffuse ST segment elevations with PR depression. What is the most appropriate treatment at this time?</p>
</div>
<br>
</div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer11" value="1"><label for="answer11">A. NSAID only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer22" value="2"><label for="answer22">B. Colchicine only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer33" value="3"><label for="answer33">C. NSAIDS and colchicine</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer44" value="4"><label for="answer44">D. Corticosteroids</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer55" value="5"><label for="answer55">E. Dialysis</label></div>
<input type="hidden" name="data[Answer][correct]" value="2" id="AnswerCorrect">
</div>
JQUERY:
$(document).on('click', '#btn_highlight', function() {
select('#highlight');
apply('highlight');
});
$(document).on('click', '#btn_crossout', function() {
select('#crossout');
apply('crossout');
});
function select(id) {
function append(id, begin, end) {
// console.log('Add: ' + begin + ' to ' + end);
var highlights = $(id).val().trim().split(',');
var start = -1;
var done = -1;
var duplicate = -1;
var inside = -1;
var out = [];
var previous = 99999999;
var on = false;
for (x in highlights) {
var mark = highlights[x];
if (!mark) continue;
// console.log('Check: ' + mark + ' Start: ' + start + ' End: ' + done);
if (duplicate == mark) {
// console.log('Repeated mark');
out.push(mark);
}
if (done >= 0) {
out.push(mark);
continue;
} else if (start < 0) {
if (end < mark) {
// console.log('Prepend new');
out.push(begin);
out.push(end);
out.push(mark);
start = mark;
done = end;
} else if (end == mark || begin < mark) {
if (!on && end <= mark) {
// console.log('Prepend consecutive');
out.push(begin);
out.push(end);
out.push(mark);
done = mark;
} else if (on) {
// console.log('Start inside');
inside = begin
} else {
// console.log('Start new');
out.push(begin);
}
start = begin;
} else if (begin == mark) {
// console.log('Start overlapped');
duplicate = mark;
start = mark;
} else {
// console.log('Skip one');
out.push(mark);
}
}
if (done < 0 && start >= 0) {
if (end == mark) {
if (inside >= 0) {
// console.log('End overlapped from inside');
out.push(inside);
on = !on;
} else if (duplicate < 0) {
// console.log('End overlapped from outside');
out.push(end);
}
done = mark;
} else if (end > previous && end < mark) {
if (!on || duplicate >= 0) {
// console.log('End new');
out.push(end);
}
out.push(mark);
done = mark;
}
}
on = !on;
// console.log(out);
previous = mark;
}
if (done < 0) {
if (duplicate >= 0 && begin == mark) {
out.push(begin);
out.push(begin);
out.push(end);
} else {
if (start < 0) {
out.push(begin);
} else if (duplicate >= 0) {
// console.log('End from duplicate');
out.push(duplicate);
}
out.push(end);
}
}
$(id).val(out.toString().trim(','));
// console.log(id + ': ' + $(id).val());
if (out.length % 2 != 0) {
console.log('Error!');
}
}
var temp = '#temp';
function getIndex(elem, offset) {
var parent = $(elem).parents('.highlight_area');
elem.nodeValue = temp + elem.nodeValue;
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.nodeValue = elem.nodeValue.substr(temp.length);
return offset;
}
function getIndex2(elem, offset) {
var parent = elem.parents('.highlight_area');
elem.text(temp + elem.text());
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.text(elem.text().substr(temp.length));
return offset;
}
function getElem(node) {
if (node.is('.highlight,.crossout')) {
node = node.parent();
}
return node;
}
var highlight = window.getSelection();
// console.log(highlight);
var base = highlight.focusNode;
var anchor = highlight.anchorNode;
var baseOffset = highlight.focusOffset;
var anchorOffset = highlight.anchorOffset;
if (!highlight.rangeCount || !$(base).parents('.highlight_area').length || !$(anchor).parents('.highlight_area').length) {
// console.log(highlight.rangeCount + ' ; ' + $(base).parents('.highlight_area').length + ' ; ' + $(anchor).parents('.highlight_area').length);
return;
}
baseOffset = getIndex(base, baseOffset);
anchorOffset = getIndex(anchor, anchorOffset);
var stem = $('.highlight_area');
var baseIndex = getElem($(base.parentElement)).index();
var anchorIndex = getElem($(anchor.parentElement)).index();
var start = Math.min(baseOffset, anchorOffset);
var end = Math.max(baseOffset, anchorOffset);
// console.log('Offset: ' + start + ' to ' + end);
// console.log('Indexes: ' + baseIndex + ' v ' + anchorIndex);
if (baseIndex == anchorIndex) {
append(id, start, end);
} else {
var children = stem.find(':not(.highlight,.crossout)');
var startIndex = Math.min(baseIndex, anchorIndex);
var endIndex = Math.max(baseIndex, anchorIndex);
var child = $(children[startIndex]);
var text = child.text();
var textStart = getIndex2(child, text.length);
append(id, start, textStart);
for (var i = startIndex + 1; i < endIndex; i++) {
child = $(children[i]);
text = child.text();
if (!text.trim().length) continue;
append(id, textStart, textStart + text.length);
textStart = textStart + text.length;
}
var child = $(children[endIndex]);
var textStart = getIndex2(child, 0);
append(id, textStart, end);
}
}
function apply() {
var highlights = $('#highlight').val().split(',');
var crossouts = $('#crossout').val().split(',');
var marks = {};
for (x in highlights) {
if (typeof marks[highlights[x]] != 'undefined') {
// 2 consecutive highlights
marks[highlights[x]] = 4;
} else {
marks[highlights[x]] = 1;
}
}
for (x in crossouts) {
if (typeof marks[crossouts[x]] == 'undefined') {
marks[crossouts[x]] = 2;
} else {
if (marks[crossouts[x]] == 4) {
// 2 highlights and a crossout
marks[crossouts[x]] = 6;
} else if (marks[crossouts[x]] == 2) {
// 2 consecutive crossouts
marks[crossouts[x]] = 5;
} else if (marks[crossouts[x]] == 6) {
// 2 consecutive highlights and crossouts
marks[crossouts[x]] = 7;
} else if (marks[crossouts[x]] == 3) {
// 2 consecutive crossouts and highlight
marks[crossouts[x]] = 8;
} else {
// highlight and crossout
marks[crossouts[x]] = 3;
}
}
}
var stem = $('.highlight_area');
var children = stem.find(':not(.highlight,.crossout)');
var childIndex = 0;
var child = $(children[childIndex]);
var text = child.text().replace(/(<([^>]+)>)/ig, "");
var high = false;
var cross = false;
var previousMark = 0;
var passedChars = 0;
var mode = 0;
var string = '';
var nextEdge = 0;
stem.empty();
child.empty();
var first = true;
var maxLoop = 10;
for (x in marks) {
if (x == '') continue;
// console.log('Mark: ' + x);
nextEdge = 1 * passedChars + 1 * text.length;
// console.log('Next edge: ' + nextEdge);
var loopCount = 0;
while (x > nextEdge && loopCount++ < maxLoop) {
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
passedChars = 1 * passedChars + 1 * text.length;
previousMark = passedChars;
// move on to next
childIndex = childIndex + 1;
child = $(children[childIndex]);
text = child.text();
child.empty();
nextEdge = 1 * text.length + 1 * passedChars;
// console.log('Next edge : ' + nextEdge);
}
// console.log('Select: ' + previousMark + ' to ' + x);
string = text.substr(previousMark - passedChars, x - previousMark);
// console.log(string);
var type = '';
if (high) {
type = type + ' highlight';
}
if (cross) {
type = type + ' crossout';
}
if (type) {
var span = $('<span></span>').addClass(type);
span.text(string);
child.append(span);
} else {
child.append(string);
}
previousMark = x;
if (marks[x] == 1) {
high = !high;
} else if (marks[x] == 2) {
cross = !cross;
} else if (marks[x] == 3) {
high = !high;
cross = !cross;
} else if (marks[x] == 4) {
high = true;
} else if (marks[x] == 5) {
cross = true;
} else if (marks[x] == 6) {
high = true;
cross = !cross;
} else if (marks[x] == 7) {
high = true;
cross = true;
} else if (marks[x] == 8) {
high = !high;
cross = true;
}
}
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
childIndex = childIndex + 1;
while (childIndex < children.length) {
child = $(children[childIndex]);
child.find('.highlight,.crossout').each(function(i, e) {
child.html(child.html().replace($(e).outerHtml(), $(e).text()));
});
stem.append(child);
childIndex = childIndex + 1;
}
}
apply();
Click Here For Output
for another project we are trying to fade through the RGB color space (from one color to another).
As a proof of concept we build the logic in JavaScript. As a final result, the background of a div should be changed to the given color, step by step.
But in our example the div just get set to the final color and doesn't show the steps between the start and end color.
Since we can't get it to work, our qustion: What is wrong here? is the logic flawed or our JS skills :) ?
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<script>
$(function() {
var colors = [];
$('#go').click(function() {
console.log($('#red1').val()+" "+$('#green1').val()+" "+$('#blue1').val()+" "+$('#red2').val()+" "+$('#green2').val()+" "+$('#blue2').val());
slidecolor($('#red1').val(), $('#green1').val(), $('#blue1').val(), $('#red2').val(), $('#green2').val(), $('#blue2').val());
readArray();
});
function slidecolor(StartsR, StartsG, StartsB, aimR, aimG, aimB) {
StartsR = parseInt(StartsR);
StartsG = parseInt(StartsG);
StartsB = parseInt(StartsB);
aimR = parseInt(aimR);
aimG = parseInt(aimG);
aimB = parseInt(aimB);
if(aimR >= StartsR)
{
var directionR = 1;
console.log("größer");
var distanceR = aimR - StartsR;
}
else
{
var directionR = 0;
console.log("kleiner");
var distanceR = StartsR - aimR;
}
if(aimB >= StartsB)
{
var directionB = 1;
var distanceB = aimB - StartsB;
}
else
{
var directionB = 0;
var distanceB = StartsB - aimB;
}
if(aimG >= StartsG)
{
var directionG = 1;
var distanceG = aimG - StartsG;
}
else
{
var directionG = 0;
var distanceG = StartsG - aimG;
}
if((distanceR >= distanceB) && (distanceR >= distanceG)) { var distance = distanceR; }
if((distanceG >= distanceR) && (distanceG >= distanceB)) { var distance = distanceG; }
if((distanceB >= distanceR) && (distanceB >= distanceG)) { var distance = distanceB; }
var stepsR = Math.round(distance/distanceR);
var stepsG = Math.round(distance/distanceG);
var stepsB = Math.round(distance/distanceB);
console.log(distance+" "+distanceR);
console.log(stepsR+" "+stepsG+" "+stepsB);
var tmpstepsR = 0;
var tmpstepsG = 0;
var tmpstepsB = 0;
for(i=0; i<=distance; i++) {
console.log(i);
if(i==0)
{
console.log("FIRST RUN");
if(directionR == 1) {
var tmpR = StartsR + 1;
tmpstepsR = stepsR;
}
else
{
var tmpR = StartsR - 1;
tmpstepsR = stepsR + 1;
}
if(directionG == 1) {
var tmpG = StartsG + 1;
tmpstepsG = stepsG;
}
else
{
var tmpG = StartsG - 1;
tmpstepsG = stepsG;
}
if(directionB == 1) {
var tmpB = StartsB + 1;
tmpstepsB = stepsB;
}
else
{
tmpstepsB = stepsB;
var tmpB = StartsB - 1;
}
}
else
{
console.log("NEXT RUN");
if(((stepsR == i) || (tmpstepsR == i)) && tmpR != aimR)
{
tmpstepsR = tmpstepsR + stepsR;
if(directionR == 1) {
var tmpR = tmpR + stepsR;
}
else
{
var tmpR = tmpR - stepsR;
}
}
if(((stepsG == i) || (tmpstepsG == i)) && tmpG != aimG)
{
tmpstepsG = tmpstepsG + stepsG;
if(directionG == 1) {
var tmpG = tmpG + stepsG;
}
else
{
var tmpG = tmpG - stepsG;
}
}
if(((stepsB == i) || (tmpstepsB == i)) && tmpB != aimB)
{
tmpstepsB = tmpstepsB + stepsB;
if(directionB == 1) {
var tmpB = tmpB + stepsB;
}
else
{
var tmpB = tmpB - stepsB;
}
}
}
console.log('rgb('+ tmpR +','+ tmpG +','+ tmpB +')');
colors.push('rgb('+ tmpR +','+ tmpG +','+ tmpB +')');
}
}
function readArray(){
colors.forEach(function(entry){
timeOut(entry);
$('#color').css("background-color", entry);
});
}
function timeOut(entry){
setTimeout(function(){$('#color').css("background-color", entry);}, 3000);
}
});
</script>
<h1>Farbe 1</h1>
red: <input id="red1">
green: <input id="green1">
blue: <input id="blue1">
<h1>Farbe 2</h2>
red: <input id="red2">
green: <input id="green2">
blue: <input id="blue2">
<button id="go">LET'S GO</button>
<div id="color" style="width:500px;height:500px"></div>
</body>
</html>
Please note that some parts may be a bit buggy or ugly since it's just a first try. The last part were we added some time out were some last resort and may be not best practice...
EDIT: jsfiddle
In readArray, you're iterating over all entries in the colors array. This iteration takes very little time (As in, faster than you can notice). During that iteration, all 3-second timeouts are set. They aren't sequenced, they're all just set to be executed ~3 seconds after the forEach is done.
You'll need to properly sequence your callbacks:
function readArray(){
timeOut(colors, 0);
}
function timeOut(array, index){
var entry = colors[index];
$('#color').css("background-color", entry);
var nextIndex = index + 1;
if(nextIndex < array.length){
setTimeout(function(){
timeOut(array, nextIndex);
}, 30);
}
}
Basically, at the moment the current "step" is executed, you set the timeout for the next step.
Example Fiddle
Please note I set the timeout to 30 ms per step, so you can actually notice the fade.
(Instead of readArray();, you can just use timeOut(colors, 0);, of course, so you can remove readArray altogether)
I am creating a website application that allows users to select a seat, if it is not already reserved, and reserve it.
I have created a very round about way of getting the seats that are previously reserved using iFrames, however that was temporarily, now I need to make it secure and "proper javascript code" using proper practices. I have no clue what AJAX (or JSON) is, nor how to add it to this code, but it needs to get the file "seatsReserved"+this.id(that is the date)+"Que.html" and compare the string of previously reserved seats to see which class to make the element. If this is horrible, or if any of the other things could work better, I am open to criticism to everything. Thank you all!
Here is the javascript code:
A little side note, all of the if statements are due to different amount of seats in each row
<script>
var i = " 0 ";
var counter = 0;
var leng=0;
document.getElementById("Show1").addEventListener("click", changeDay);
document.getElementById("Show2").addEventListener("click", changeDay);
document.getElementById("Show3").addEventListener("click", changeDay);
function changeDay() {
var iFrame = document.getElementById("seatList");
iFrame.src = "seatsReserved" + this.id + "Que.html";
document.getElementById('date').innerHTML = this.id;
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.removeEventListener("click", selectedSeat);
}
else {
document.getElementById(let +k).className = "openseat";
document.getElementById(let +k).removeEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
}
function loadChanges() {
var iFrame = document.getElementById("seatList");
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
var leng = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.addEventListener("click", selectedSeat);
seat.className = "openseat";
}
else {
document.getElementById(let +k).className = "notAvailible";
document.getElementById(let +k).addEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
i = " 0 ";
counter = 0;
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
document.getElementById("seatnums").innerHTML = counter;
}
i = document.getElementById("seatString").innerHTML;
counter = document.getElementById("seatnums").innerHTML;
function selectedSeat() {
var w = this.id;
var l = (" " + w);
var b = (" " + w + " ");
if (counter < 5) {
if (i.indexOf(b) <= 0) {
this.className = "closedseat";
i = i + b;
i = i.replace(" 0 ", " ");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter + 1;
document.getElementById("seatnums").innerHTML = counter;
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
function doNothing() {
}
var rannum = Math.random() * 1000;
document.getElementById('getConfirmation').value = rannum;
</script>