Multiple declaration of Id for getElementById - how to automate? - javascript

I have such a small javascript code (I use it in Markdown):
<button title="Click to show answer" type="button" class="btn btn-primary"
onclick="if(document.getElementById('spoiler') .style.display=='none')
{document.getElementById('spoiler') .style.display=''}
else{document.getElementById('spoiler') .style.display='none'}">
show/hide
</button><div id="spoiler" style="display:none">
***
Hidden Text
***
</div>
The problem is that if I want to make several buttons on one page to hide the text, then I need to rename spoiler to spoilerN 4 times
Questions:
(Minimum) Is it possible to compactly output Id to a separate variable in this piece of code?
(Maximum) Is it possible to automatically generate a variable? So that the code itself reuses the variable every time a new button is declared?

You would be better doing away with inline style AND javascript, and doing this in css with some javascript to control adding.removing css classes.
Assuming the button is always a sibling of the spoiler div, you can do this by having just a class on the spoiler div and attaching it automatically to every instance on a page:
document.querySelectorAll(".spoiler").forEach(s => {
s.previousSibling.addEventListener("click", () => {
s.classList.toggle("show");
});
})
.spoiler{
display:none
}
.show{
display:block
}
<button title="Click to show answer" type="button" class="btn btn-primary">
show/hide
</button><div class="spoiler">
***
Hidden Text
***
</div>

Jamie's answer turned out to be very similar to the truth! Thanks!
But in Markdown, my colleagues and I made a number of small edits, because the solution did not work right away. The working version looks like this:
First chunk (One, at the beginning of the document (or in style.css for all Rmd files in bookdown)):
.spoiler{
display:none
}
.show{
display:block
}
The second piece (actually hidden texts)
<button title="Click to show answer" type="button" class="btn btn-primary">
show/hide
</button><div class="spoiler">
***
Hidden Text
***
</div>
<button title="Click to show answer" type="button" class="btn btn-primary">
show/hide
</button><div class="spoiler">
***
Hidden Text2
***
</div>
The third piece (one, at the very end of the Rmd file)
Changed previousibling to previousElementSibling
document.querySelectorAll(".spoiler").forEach(s => {
s.previousElementSibling.addEventListener("click", () => {
s.classList.toggle("show");
});
})
Thank you for your help!

Related

Reading/Displaying different text files with one function in jQuery

I'm trying to build a notary of sorts. This notary will have different buttons and with the press of each button a different message of plain text will display in a custom div. I want all buttons to display different messages, but display them in the same div and when a different button is pressed, the former message will fade away and the new message will fade in.
I have a basic understanding of the jQuery.get() and this is my JS and HTML code that I've used to read/display one file in that custom div by clicking the button labeled "First":
function Answer() {
jQuery.get("file.txt", function(text) {
$(".answerBox").text(text);
})
};
<body>
<div class="content">
<div class="buttons">
<button class="button" type="button" onclick="Answer()">First</button>
<button class="button" type="button" onclick="Answer()">Second</button>
</div>
<div class="textBox">
<div class="answerBox">Click Any Question Button</div>
</div>
</div>
</body>
The issue comes when clicking the button labeled "Second", it reads the same file.txt and displays the same message. I am puzzled as to how I can expand this single function to encompass all 300 some odd buttons I will need and yes, each button will display a different message and will be tied to a different txt file. I really don't want to rewrite this small function 300 some times and I know there is a better way I just cannot find it.
So I've just asked this question, but I've been digging a bit more and I think I may have found something useful. I've rewritten my JS function and HTML as:
`function Answer(file) {
let list = [];
url = "files/" + file
list.push(url);
if (list.includes(url)) {
jQuery.get(url, function(text) {
$(".answerBox").fadeOut(() => {
$(".answerBox").text(text);
})
$(".answerBox").fadeIn(2000)
});
<div class="buttons">
<button class="button" type="button" onclick="Answer('file.txt')">First</button>
<button class="button" type="button" onclick="Answer('file1.txt')">Second</button>
</div>
`
This kinda solves my initial problem, but now I will need to make 300 instances of buttons in HTML. Is there any other way or is this the best I can do with what I know?

show button only if following div tag has some value

I have following html code - which displays a button and user clicks on it - it display
some text below.
<div>
<button class="btn-default btn-primary show-answer-button">Show</button>
<div class="answer"></div>
</div>
But sometimes, when user clicks the button, there is no text . (so it displays nothing).
I would like to display this button only when the "answer" has some text. How to achieve this ?
I tried following (adding a id='answer-part' and insert a line at js file) but it didn't work:
<div id="answer-part">
<button class="btn-default btn-primary show-answer-button">Show</button>
<div class="answer"></div>
</div>
and add this at .js file
$('.answer-part:empty').hide();
Try using the length property and contents() together:
$('button.btn-default.btn-primary.show-answer-button').click(function () {
if ($(this).next().contents().length) $(this).next().show()
})
jsFiddle example
$('.answer:empty').hide().prev('button').hide();
You can do it like this:
$('.show-answer-button')[$('.answer').text() ? "show":"hide"]();

removing button dynamically

in this fiddle,under appointments tab,there is a add timing button.When this button is clicked then a new row is added along with another add timing button.But I did not want another add timing buttons so i made this fiddle
added a class timing
<button class="btn btn-primary timing" type="button" data-bind="click: $parent.addSlot" value="Add">Add Timing</button>
and
in js
self.addSlot = function () {
//self.schedules.push(new Model.Schedule(null));
console.log('added');
self.doctor.schedules.push(new Schedule(null));
$('.timing:last').hide();
};
now the problem in the above fiddles there is one JSON so initally only one add timing button is added but if the JSON is 2 then 2 add timings button are added like this fiddle
so can any body please tell me how will I have only on add timings button.
You can move the Add Timing button outside the table and access the $root context instead of the $parent context
<!-- ... -->
</table>
<button class="btn btn-primary timing" type="button" data-bind="click: $root.addSlot" value="Add">Add Timing</button>
This way the Add Timing button will not be duplicated with every entry. You must also remove the
$('.timing:last').hide();
Otherwise, the button will be hidden on your first adding.
See updated JSFiddle
Update:
According to Binding context, $data works equally well in this case
data-bind="click: $data.addSlot"
See another JSFiddle

javascript - remove element

My question is rather elementary, but I do not understand why, in the following code, on button click only button dissapears, instead of the whole div:
<script>
function remove(id) {
//get the element node
element = document.getElementById(id);
//remove the element from the document
document.removeChild(element);
}
</script>
<div id="intro" class="jumbotron">
<h1>Your Offline Web Dictionary!</h1>
<p class="lead">
<div class="controls">
<input class="span7 " type="text" placeholder=" " name="key">
</div>
<div>
<button class="btn btn-large btn-success" onclick="remove(intro)">
Dictionary Search
</button>
</div>
</div>
JSFiddle
The problem is that the button element has a remove property so that is called instead of your remove function. And also the string thing.
<button class="btn btn-large btn-success" onclick="window.remove('intro');console.log(this.remove);">
Search
</button>
http://jsfiddle.net/HMEVd/76/
Two problems. Firstly, intro should be a string, not an identifier, so use remove('intro') in your onclick.
Second, document.rwmoveChild is incorrect. removeChild should be called on the parent of the element you are removing. It is common to use:
element.parentNode.removeChild(element);
intro should be sent to the function as a string rather than a variable, i.e, 'intro'
Also, you must rename your function, for example, removeById instead of remove. Then it works perfectly.
The function remove actually does something completely different. (Your function is not even invoked when it is named remove as you can see by putting an alert message into it.)
function removeById(id) {
//get the element node
element = document.getElementById(id);
//remove the element from the document
document.removeChild(element);
}
...
<button class="btn btn-large btn-success" onclick="removeById('intro')">

How do I navigate to another page on button click with Twitter Bootstrap?

I have to render a html page residing in templates/home.html
I have a button in index.html as:
<div id="browse_app">
<button class="btn btn-large btn-info" type="button">Browse</button>
</div>
All I want to do is when I click on Browse, it takes me to home.html
I tried to write jQuery as:
// onClick on 'Browse' load the internal page
$(function(){
$('#browse_app').click(function(){
$.load('templates/home.html');
});
});
But this doesn't work since load needs to put data somewhere in current page
How do I get to the home.html on button click?
As far as I can tell you are using Twitter Bootstrap. The documentation for Buttons addresses your point:
Default buttons
Button styles can be applied to anything with the .btn class applied. However, typically you'll want to apply these to only <a> and <button> elements for the best rendering.
This is what you want:
<div id="browse_app">
<a class="btn btn-large btn-info" href="templates/home.html">Browse</a>
</div>
In the worst case scenario, this way the rendering of the button won't look nice but the link will work. Using JS, your worst case scenario will render the link useless.
Use: onclick="window.location='INSERT HTML FILE HERE'" in your button tag
One I prepared earlier:
<button class="btn" style="text-align:inherit" onclick="window.location='./Learn/'">« About HerdMASTER 4</button>
I wanted to go to the directory Learn from another directory in the same folder
It's a more elegant solution using the bootstrap class that is included, meaning you don't have to hack code into your page. I wish there was a bit more functionality documentation about the various classes for bootstrap as I figured this out from the above code rather than finding it by a google search.
Use this:
$(function(){
$('#browse_app').click(function(){
window.location='templates/home.html'
});
});
Use onclick="window.open('YourPage.aspx','_self');"
For Example:
<button type="submit" onclick="window.open('YourPage.aspx','_self');" class="btn btn-default">Your Page</button>

Categories