How to toggle "View replies" button into "Hide replies" on click? - javascript

I used bootstrap button("View x replies") to toggle the visibility of the replies in the comments.It works fine to toggle the content.But I want that if someone click on "View x replies" button the content of the button will be changed into "Hide x replies".After that when user will on "Hide replies" it will change into "View replies" as like as first it is.I used javascript to achieve this.
Here is my code:
<button class="btn btn-primary d-block" id ="show-{{comment.id}}" type="button"
data-toggle="collapse" data-target="#{{comment.id}}"
aria-expanded="false" aria-controls="collapseExample"
onClick = "myFunction1({{ comment.id }}, {{ comment.get_children.count }} );">
View {{ comment.get_children.count }} replies
</button>
<script>
function myFunction1(comment_id, comment_get_children_count) {
var id = comment_id;
var count = comment_get_children_count;
var x = document.getElementById("show-" + id );
var y = "View " + count + " replies";
var z = "Hide " + count + " replies";
if (x.innerHTML = y){
x.innerHTML = z;
}
// else part is not working
else {
x.innerHTML = y;
}
}
</script>
It works fine when I click "View x replies" it changes into "Hide x replies".But next when I click on "Hide x replies", it is not changing into "View x replies" what I want.
So how can I solve this problem? Any suggetion?
Thanks in advance.

You are not checking the condition properly in your IF statement.
= is assignment operator VS == comparison operator
= is an assignment operator and to check whether to change innerHTML. You need to use != (Inequality operator) this to change the innerHTML of your button.
MDN Operators
Live Demo:
function myFunction1(comment_id, comment_get_children_count) {
var id = comment_id;
var count = comment_get_children_count;
var x = document.getElementById("show-" + id);
var y = "View " + count + " replies";
var z = "Hide " + count + " replies";
if (x.innerHTML.trim() != z) {
x.innerHTML = z;
} else {
x.innerHTML = y;
}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<button class="btn btn-primary d-block" id="show-12" type="button" data-toggle="collapse" data-target="#12" aria-expanded="false" aria-controls="collapseExample" onClick="myFunction1(12, 12 );">
View 12 replies
</button>

Related

Why does JavaScript sometimes function not work when button is clicked?

I have a JavaScript voting system that has three buttons:
Vote Up, clear, and Vote Down
When I clicked the Vote Up button, it stays in zero. I have to press the Vote Up button several times to get it to vote up. Same with Vote down. When I pressed Clear, it does nothing.
Here is what I've done:
Assign function to Vote Up, and Vote Down and clear:
<button onclick="voteup()">
Vote Up
</button>
<button onclick="votedown()">
Vote Down
</button>
<button onclick="clear()">
Clear
</button>
Making a paragraph to display the result:
<p Id="vote">
You have 0 votes
</p>
Creating a global variable so I can access the variable on future functions:
var a = 0;
Creating the vote up functions:
function voteup() {
var b = a++;
Display the result in voteup() function:
document.getElementById('vote').innerHTML = "You have" + ' ' + b + "votes";
}
Making the second function (votedown):
function votedown(){
var b = a --;
document.getElementById('vote').innerHTML = "You have" + ' ' + b + "votes";
}
Create the function for clear:
function clear() {
document.getElementById('vote').innerHTML = "Your votes has been cleared";
}
I set the variable out of the function so voteup and votedown functions can access the a variable. I can't understand this.
var a = 0;
function voteup() {
a++;
document.getElementById('vote').innerHTML = "You have " + a + " votes";
}
function votedown() {
a--;
document.getElementById('vote').innerHTML = "You have " + a + " votes";
}
function clearVotes() {
document.getElementById('vote').innerHTML = "You have 0 votes";
var div = document.createElement("div");
div.innerText = "Your votes has been cleared."
div.style.color = "red";
div.style.transition = "opacity 0.25s ease-out"
document.body.appendChild(div)
setTimeout(function() {
div.style.opacity = "0";
setTimeout(function() {
div.remove()
}, 1000)
}, 3000)
a = 0
}
<button onclick="voteup()">
Vote Up
</button>
<button onclick="votedown()">
Vote Down
</button>
<button onclick="clearVotes()">
Clear
</button>
<p id="vote">
You have 0 votes
</p>
Also, you forgot a dot between document and getElementById in one of them.
Your code should be:
PS: it seems that clear is a reserved word that we cannot use as a function name
var a = 0;
const pVote = document.getElementById('vote');
function voteup() {
pVote.textContent = "You have " + ++a + " votes";
}
function votedown(){
pVote.textContent = "You have " + --a + " votes";
}
function doClear() {
a = 0
pVote.textContent = "Your votes has been cleared";
}
<button onclick="voteup()"> Vote Up </button>
<button onclick="votedown()"> Vote Down </button>
<button onclick="doClear()"> Clear </button>
<p id="vote"> You have 0 votes </p>
my way...
const p_vote = document.getElementById('vote')
, btVote = document.getElementById('bt-vote')
var voteCount = 0
btVote.onclick = e =>
{
if (!e.target.matches('button[data-op]')) return
voteCount = eval(`${voteCount} ${e.target.dataset.op}`)
p_vote.textContent = voteCount ? `You have ${voteCount} votes` : 'Your votes has been cleared'
}
#VoteBtns button { width : 10em; }
<div id="bt-vote">
<button data-op="+ 1" > Vote Up </button>
<button data-op="- 1" > Vote Down </button>
<button data-op="* 0" > Clear </button>
</div>
<p Id="vote" > You have 0 votes </p>
When using a-- the value of a is returned before the subtraction operation is executed. Thus, b is set only to the current value of a.
If you’d like this subtraction operation to occur prior to when the value is returned into b, use the decrement operator as a prefix (--a) instead.
The difference in prefix vs postfix of the decrement shorthand operator is clearly documented on its MDN page.

Javascript calculator-emptying the field before typing input

I am trying to build a calculator using JavaScript
var btn5 = document.getElementById('btn5');
var btn2 = document.getElementById('btn2');
var btn5multiply = document.getElementById('btn5multiply');
var result = document.getElementById('result');
var calInput = document.getElementById('calInput');
var backSpace = document.getElementById('backSpace');
var C = document.getElementById('C');
var blank = "Please enter a number";
btn5.addEventListener('click', runFunction5);
btn2.addEventListener('click', runFunction2);
multiply.addEventListener('click', multiplyFunction);
result.addEventListener('click', resultFunction);
backSpace.addEventListener('click', backSpaceFunction);
C.addEventListener('click', clearFunction);
function runFunction5() {
if(calInput.value == blank) {
calInput.value = "";
calInput.value += btn5.value;
} else {
calInput.value += btn5.value;
}
}
function runFunction2() {
calInput.value += btn2.value;
}
function multiplyFunction() {
calInput.value += multiply.value;
}
function resultFunction() {
if(calInput.value == "") {
calInput.value = blank;
} else {
var storeVal = calInput.value;
var cal = eval(storeVal);
calInput.value = cal;
}
}
function backSpaceFunction() {
var storeVal = calInput.value;
calInput.value = storeVal.substr(0, storeVal.length - 1);
}
function clearFunction() {
calInput.value = "";
}
<body>
<input id="calInput" type="text" disabled="true" value=""><br><br>
<button id="backSpace"><-</button>
<button id="btn5" value="5">5</button>
<button id="btn2" value="2">2</button>
<button id="multiply" value="*">X</button>
<button id="result">=</button>
<button id="C">C</button>
</body>
. In my code if someone presses the =key, it displays the message that says Please enter a number. Now I figured out the way to clear the field first when pressing the number key after pressing =key and appending every key pressed afterwards to the input field but there is too much typing of code as I have to assigned that condition to every numeric key, so is there a better way to achieve that ? Right now I have added that condition to only when 5 is pressed.
All you need to do is assign a common function to each of the buttons for their click event and within that handler, you can determine which button was actually clicked using the event.target.
Now, there's no need for an input field here at all. You aren't getting any input directly from it, you are actually using it as an output mechanism. Since you want it placed on its own line, a regular div is the better UI choice.
Next, instead of getting the value of your buttons, just work with the text that is the content of the buttons via the .textContent property of the element. This will make the HTML much simpler as well.
Now, you have eval() in your code as a way of taking the string you've built up and running it as an expression. eval() should be avoided all the time. There is hardly a use-case that requires it. It opens up security and performance problems in an application. This is a topic of some debate, but in my opinion, anyone that advocates for it is under-informed about eval() or JavaScript. It will take a little more code, but you can do the math without it.
This example answers your question and demonstrates my suggestions. I've even extended your scenario to include all the basic math operators, but there is still more that would need to be flushed on on this before it was ready for production deployment.
// Get both number buttons in an array:
var btns = Array.prototype.slice.call(document.querySelectorAll(".number"));
// Get all operator buttons in an array:
var operators = Array.prototype.slice.call(document.querySelectorAll(".operator"));
var operator = null; // Will store the last operator pressed
var result = document.getElementById('result');
var output = document.getElementById('output');
var back = document.getElementById('backspace');
var clear = document.getElementById('clear');
var blank = "Please enter a number";
// Loop over the buttons in the numbers array
btns.forEach(function(btn){
// Assign an event handler to the button
btn.addEventListener("click", btnFunction);
});
// Loop over the buttons in the operators array
operators.forEach(function(op){
// Assign an event handler to the button
op.addEventListener("click", function (evt) {
operator = evt.target.textContent; // Get the operator and store it
output.textContent += operator; // Display the operator in the expression
});
});
// Set up event handlers:
result.addEventListener("click", doMath);
clear.addEventListener("click", function() { output.textContent = ""; });
back.addEventListener("click", function(){
output.textContent = output.textContent.substring(0, output.textContent.length - 1);
});
// All event handling functions are automatically passed
// a reference to the event that triggered the function
function btnFunction(evt) {
// And that event object exposes the actual DOM object
// that triggered the event via the target property
if(output.textContent == blank) {
output.textContent = evt.target.textContent;
} else {
output.textContent += evt.target.textContent;
}
}
function doMath() {
// Check for no math to do yet
if(output.textContent === ""){
output.textContent = blank;
}
// Break up the expression into an array with the operands serving to delimit the parts
var operands = output.textContent.split(/[+-/*]/);
// Do the math:
switch (operator){
case "+" :
// Operands is an array, so we want to do the math with the two items in the array which
// we get by passing indexes of 0 and 1 to the array.
output.textContent += " = " + (parseInt(operands[0], 10) + parseInt(parseInt(operands[1], 10)));
break;
case "-" :
output.textContent += " = " + (parseInt(operands[0], 10) - parseInt(parseInt(operands[1], 10)));
break;
case "*" :
output.textContent += " = " + parseInt(operands[0], 10) * parseInt(parseInt(operands[1], 10));
break;
case "/" :
output.textContent += " = " + parseInt(operands[0], 10) / parseInt(parseInt(operands[1], 10));
break;
}
}
#output { height:1em; padding:3px; }
<body>
<!-- No need for an input element here. -->
<div id="output"></div>
<button id="backspace">←</button>
<button class="number">5</button>
<button class="number">2</button>
<button class="operator">+</button>
<button class="operator">-</button>
<button class="operator">*</button>
<button class="operator">/</button>
<button id="result">=</button>
<button id="clear">C</button>
</body>
You could determine the value of the currently clicked button, like this:
function numberClickHandler() {
calInput.value += this.value;
}
Now we only need to assign this to all buttons, e.g.:
["btn2", "btn3"].forEach(id =>
document
.getElementById(id)
.onclick = numberClickHandler
);
A little modification in the HTML will solve your issue. I suggest you add a placeholder attribute in the input. Placeholder will disappear once there is a value in input and will reappear when there is none.
More about placeholder: https://www.w3schools.com/tags/att_input_placeholder.asp
Demo: http://jsfiddle.net/lotusgodkk/GCu2D/2194/
HTML:
<input id="calInput" type="text" disabled="true" value="" placeholder="Please enter a number">
<br>
<br>
<button id="backSpace">>
</button>
<button id="btn5" value="5">5</button>
<button id="btn2" value="2">2</button>
<button id="multiply" value="*">X</button>
<button id="result">=</button>
<button id="C">C</button>
JS:
var btn5 = document.getElementById('btn5');
var btn2 = document.getElementById('btn2');
var btn5multiply = document.getElementById('btn5multiply');
var result = document.getElementById('result');
var calInput = document.getElementById('calInput');
var backSpace = document.getElementById('backSpace');
var C = document.getElementById('C');
var blank = "Please enter a number";
btn5.addEventListener('click', runFunction5);
btn2.addEventListener('click', runFunction2);
multiply.addEventListener('click', multiplyFunction);
result.addEventListener('click', resultFunction);
backSpace.addEventListener('click', backSpaceFunction);
C.addEventListener('click', clearFunction);
function runFunction5() {
calInput.value += btn5.value;
}
function runFunction2() {
calInput.value += btn2.value;
}
function multiplyFunction() {
calInput.value += multiply.value;
}
function resultFunction() {
var storeVal = calInput.value;
var cal = eval(storeVal);
calInput.value = cal;
}
function backSpaceFunction() {
var storeVal = calInput.value;
calInput.value = storeVal.substr(0, storeVal.length - 1);
}
function clearFunction() {
calInput.value = "";
}
Once, you do that you will not have to add that condition in each case.
var numericValues = document.getElementById('numericValue');
var result = document.getElementById('result');
var calInput = document.getElementById('calInput');
var backSpace = document.getElementById('backSpace');
var C = document.getElementById('C');
var blank = "Please enter a number";
numericValues.addEventListener('click', pushNumericValue);
multiply.addEventListener('click', multiplyFunction);
result.addEventListener('click', resultFunction);
backSpace.addEventListener('click', backSpaceFunction);
C.addEventListener('click', clearFunction);
function pushNumericValue(event) {
var btnTarget = event.target
if(calInput.value == blank) {
calInput.value = "";
calInput.value += btnTarget.value;
} else {
calInput.value += btnTarget.value;
}
}
function multiplyFunction() {
calInput.value += multiply.value;
}
function resultFunction() {
if(calInput.value == "") {
calInput.value = blank;
} else {
var storeVal = calInput.value;
var cal = eval(storeVal);
calInput.value = cal;
}
}
function backSpaceFunction() {
var storeVal = calInput.value;
calInput.value = storeVal.substr(0, storeVal.length - 1);
}
function clearFunction() {
calInput.value = "";
}
<body>
<input id="calInput" type="text" disabled="true" value=""><br><br>
<button id="backSpace"><-</button>
<div id="numericValue">
<button id="btn5" value="1">1</button>
<button id="btn5" value="2">2</button>
<button id="btn5" value="3">3</button>
<button id="btn2" value="4">4</button>
</div>
<button id="multiply" value="*">X</button>
<button id="result">=</button>
<button id="C">C</button>
</body>
One way to do it
Is using event delegation instead of listening all numeric values and doing an specific action. Define a parent div that have as children all numeric values and listen to it thanks to the event.target attribute you can get its value of the clicked button

Modify function to replace text as well as add at carat when button pressed

Ive built a little bit of code which adds text to a text area box depending on which button is pressed a very simple editor if you like.
Currently the code just inserts the selected text where the cursor is, but if text is highlighted then I would like it to wrap that text as well.
I have a jsfiddle at http://jsfiddle.net/gffeab94/3/
but for clarity the the function is
jQuery("document").ready(function($){
$('#bold').on('click', function () {
_insertAtCaret($('#transcription-page-wikitext'), "'''bold text here'''");
});
$('#italic').on('click', function () {
_insertAtCaret($('#transcription-page-wikitext'), "<del> </del>");
});
$('#strike').on('click', function () {
_insertAtCaret($('#transcription-page-wikitext'), "{{Paul}}");
});
function _insertAtCaret(element, text) {
var caretPos = element[0].selectionStart,
currentValue = element.val();
element.val(currentValue.substring(0, caretPos) + text + currentValue.substring(caretPos));
return false;
}
})
and the html is
<div>
<!-- editor buttons -->
<p>
<button id ="bold" class="btn btn-small btn-info" type="button">Bold</button>
<button id ="italic" class="btn btn-small btn-info" type="button">Italic</button>
<button id ="strike" class="btn btn-small btn-info" type="button">Strikeout</button>
</p>
<!-- text area -->
<textarea name="transcription-page-wikitext" id="transcription-page-wikitext" cols="76" rows="16">some text</textarea>
</div>
How can I change the function to ideally wrap or replace highlighted text, rather than just inserting at the cursor position?
Use the textarea's selectionEnd property as well as selectionStart and simple string manipulation.
Demo: http://jsfiddle.net/gffeab94/4/
Code:
function _insertAtCaret(element, text, textBefore, textAfter) {
var el = element[0];
var start = el.selectionStart;
var end = el.selectionEnd;
var newStart = start;
var newEnd = end;
var val = el.value;
var beforeSel = val.slice(0, start);
var afterSel = val.slice(end);
if (start == end) {
el.value = beforeSel + text + afterSel;
newEnd += text.length;
} else {
el.value = beforeSel + textBefore + val.slice(start, end) +
textAfter + afterSel;
newStart += textBefore.length;
newEnd = newStart + end - start;
}
el.setSelectionRange(newStart, newEnd);
}

Using an array to toggle different images

First, I cannot get morscreens[i] to produce the image from the array that I want. When I have it as is, it literally makes a [<] button, says literally "morscreens[i]" then the [>] button. when I surround the morscreens[i] with quotes (exiting then re-entering quoted text), I get the error morshots() is not defined.
Second, if I want the buttons to cycle through, should I use subroutines morPrev() and morNext() to do so? My worry is getting the value I want to be returned out of scope and placed in the appropriate locations. I worry that simply using i++ and i-- will not be enough for it to work properly, even with the 2 if statements.
var mordorscreens = new Array();
mordorscreens[0] = '<img src=\"http://i.imgur.com/83HCt.png\" alt=\"scrns1\">';
mordorscreens[1] = '<img src=\"http://i.imgur.com/5mWIy.png\" alt=\"scrns1\">';
mordorscreens[2] = '<img src=\"http://i.imgur.com/pPafl.png\" alt=\"scrns1\">';
function morshots()
{
var i = 0;
var mordor = document.getElementById("ss1");
mordor.innerHTML = '<button onClick="morPrev();"> < </button> mordorscreens[i] <button onClick="morNext();"> > </button> ';
if (i<0) {i=2};
if (i>2) {i=0};
}
This line
'<button onClick="morPrev();"> < </button>
mordorscreens[i] <button onClick="morNext();"> > </button> ';
is supposed to look like
'<button onClick="morPrev();"> < </button>'
+ mordorscreens[i] + '<button onClick="morNext();"> > </button>';
I think its a bad idea to expose the variable i to iterate over the images.
Better to assign the event handlers in Javascript instead HTML..
Try this code
HTML
<div id="ss1">
<button id="previous"> < </button>
<span id="imageSpan"></span>
<button id="next"> > </button>
</div>
Javascript
var mordorscreens = [];
mordorscreens[0] = '<img src="http://i.imgur.com/83HCt.png" alt="scrns1">';
mordorscreens[1] = '<img src="http://i.imgur.com/5mWIy.png" alt="scrns1">';
mordorscreens[2] = '<img src="http://i.imgur.com/pPafl.png" alt="scrns1">';
function morshots() {
var i = 0;
var elem = document.getElementById('imageSpan');
elem.innerHTML = mordorscreens[i];
// Data Attribute that holds the initial
// image number
elem.setAttribute('data-number', i);
}
// Call The function
morshots();
// Assign Event handlers
var buttons = document.getElementsByTagName('button');
for (var j = 0; j < buttons.length; j++) {
// Add Click events to the button
buttons[j].addEventListener('click', clickHandler);
}
function clickHandler() {
var elem = document.getElementById('imageSpan');
// Store the current Image Number in a HTML5 data-attribute
var currImage = parseInt(elem.getAttribute('data-number'), 10);
if (this.id === 'previous') {
currImage--;
currImage = currImage < 0 ? 2 : currImage;
}
else if (this.id === 'next') {
currImage++;
currImage = currImage > 2 ? 0 : currImage;
}
// Set the current Image Number
elem.setAttribute('data-number', currImage);
elem.innerHTML = mordorscreens[currImage];
}
Check JSBin Demo
This is a string with no variables in it:
mordor.innerHTML = '<button onClick="morPrev();"> < </button> mordorscreens[i] <button onClick="morNext();"> > </button> ';
You need to break out your value:
mordor.innerHTML = '<button onClick="morPrev();"> < </button>' + mordorscreens[i] + '<button onClick="morNext();"> > </button> ';

Javascript onkeydown function runs and then display goes away

first time on the website, anyway my problem is that when I use onkeydown and then use GetChar to check if the enter key was pressed, when operAtion runs,the results of the function only shows on the screen for about a second and then goes away, if the user uses the onclick (clicks the enter button), then this problem doesnt occur. How do I get the result of operAtion to stay on the screen when onkeydown is used. The website is sqrtcalc.comze.com if you want to see what I mean
sqrtcalc
<!DOCTYPE html>
<html>
<head>
<title>Square Root Calculator</title>
<script language="javascript">
function operAtion (form){
var x = form.inputbox.value;
if (isNaN(x)){
//document.write("lawl");
var y = "Enter a number";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else if (x < 0){
var y = "Number must be positive";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else if (x == ""){
var y = "uhm, you didnt enter anything";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else {
var y = Math.pow(x, 1/2)
document.getElementById("demo").innerHTML = "The square root of " + x + " is " + y;
document.getElementById("failsafe").innerHTML = "";
}
}
function GetChar (event,form){
var keyCode = event.keyCode;
if (keyCode == 13){
operAtion(form);
}
}
</script>
<p></p>
</head>
<body>
<form name="myform" action="" method="get" style = "font-size:50px"><strong>Square Root Calculator</strong></br>
</br>
<input type="text" name="inputbox" value = "" onkeydown = "GetChar(event,this.form);"> </br>
</br>
<input id="button" type="button" name="button" value=" Enter " onclick="operAtion(this.form)" >
</form>
<h1 id = "failsafe"></h1>
</br>
</br>
</br>
<h1 id = "demo"></h1>
</br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br></br>
<img border="0" src="http://counter.rapidcounter.com/counter/1353157574/a"; ALIGN="middle" HSPACE="4" VSPACE="2" style = "padding-left:1400px;">
</body>
</html>
Add this code:
window.onload = function(){
document.getElementById("myform").onsubmit = function(){
return false;
}
}
And add the id attribute id="myform" to the <form> tag.
I refactored your code a little:
I removed your inline functions (inline JS isn't exactly best
practice)
I added an ID to your form so it could be referenced
I added return false; to keep the form from submitting
onsubmit handles both click and enter
Javascript
document.getElementById('myform').onsubmit = function() {
var x = this.inputbox.value;
if (isNaN(x)) {
//document.write("lawl");
var y = "Enter a number";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else if (x < 0) {
var y = "Number must be positive";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else if (x == "") {
var y = "uhm, you didnt enter anything";
document.getElementById("failsafe").innerHTML = y;
document.getElementById("demo").innerHTML = "";
} else {
var y = Math.pow(x, 1 / 2)
document.getElementById("demo").innerHTML = "The square root of " + x + " is " + y;
document.getElementById("failsafe").innerHTML = "";
}
return false;
}​
HTML
<form name="myform" action="" method="get" style="font-size:50px" id="myform"><strong>Square Root Calculator</strong><br>
<br>
<input type="text" name="inputbox"> <br>
<br>
<input id="button" type="submit" name="button" value=" Enter ">
</form>
<h1 id="failsafe"></h1>
<h1 id="demo"></h1>
Working demo​

Categories