Reading/Displaying different text files with one function in jQuery - javascript

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?

Related

Multiple declaration of Id for getElementById - how to automate?

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!

How to switch inputted text between 2 colored boxes in html

So far I only have the code that is able to make 2 boxes, made the 4 buttons, but only 1 button actually does something, and that is the start button where a there is a popup that asks for a name, and after you input that name, it will appear in the first box.
<html>
<head>
<script>
function myTask1() {
var sentence = prompt("Please enter a name");
var arrSentence = sentence.split(" ");
if (arrSentence != null) {
document.getElementById("answer1").innerHTML = arrSentence.sort(); //so we can use Array.sort() function
}
console.log(sentence);
return sentence;
}
function myFunction() {
var x = document.getElementById()
}
</script>
<style> </style>
</head>
<body>
<p><button type="button" onclick="myTask1()">Click me!</button></p>
<button type="button" onclick="ClearFields();">Clear</button>
<button type="button" onclick="myFunction()"> --> </button>
<button type="button" onclick="myTask4()"><-- </button>
<div clas="box" style="background-color:red; height:200px; margin:20px auto;">
<center>
<p id="answer1"></p>
<center>
</div>
<div class="box1" style="background-color:grey; height:200px; margin:20px auto;"> </div>
</body>
</html>
I've made some demo code for you. I assume that you're a beginner because the question is basic. This is not a problem though, starting something new is great. You can find the answer on the internet and the best programmers are often people who are good with Google. But I hope by showing you the solution anyway you get a feeling for structure. Try to understand every line. Try write it from scratch afterwards anyway. It's a great exercise.
Code: https://github.com/Bunpasi/stackoverflow-answers/blob/master/js-listbox-selector/index.html
Some things to notice:
- I've put the script in the footer so it doesn't interfere with the loading time of the page.
- I've put all code in an anonymous function to avoid global functions.
- I changed clas to class.
- I've used event listeners instead of even attributes.
- I didn't duplicate the logic for both boxes but used one function which I can use on both.
After your understand the code, there are some things you can improve on this code.
- Make sure the selection doesn't go away after the update. You can store this in the data as well. Right now the data is an array of ID's, but you can turn it into an array of objects containing even more important data, like whether it's selected.
- Move the style from the elements to the header.
Don't be discouraged by down votes.
Good luck!
Update
If you want to move all names all the time. This is what you need to do.
This line looks for all selected elements:
var selectedElements = boxes[fromId].querySelectorAll('.list_item.selected');
Remove the selected .selector:
var selectedElements = boxes[fromId].querySelectorAll('.list_item');

How to create a jQuery click handler based on a matching pattern?

I have multiple reason codes (For ex: RC1, RC2...). For each of these reason codes, I want to give the user a text box in which they can enter some comments. Also give them the option of adding multiple text boxes for each reason code.
To allow the user to add a dynamic text box, I have a button which allows the user to do so. If there was only one reason code, I can easily just just append a text box to the pre-existing text box using jquery (Using something like this: JQuery adding class to cloned element).
However since I have multiple reason codes(over 200) it doesnt make sense of having button for each reason code in Jquery. Is there a way for me to search by a basic identifier.
I have pasted the contents of the HTML file generated by my JSP file.
<div id="Reasoncode1">
<div id="inputTextBox_Reasoncode1">
<input type="text" placeholder="Add some text"/><button class="button_Reasoncode1">
+</button>
</div>
</div>
<p>
Reason code2
</p>
<div id="Reasoncode2">
<div id="inputTextBox_Reasoncode2">
<input type="text" placeholder="Add some text"/><button class="button_Reasoncode2">
+</button>
</div>
</div>
My Jquery attempt is:
$(".button_Reasoncode1").click(function() {
$('#Reasoncode1').clone().insertAfter('#inputTextBox_Reasoncode1');
});
$(".button_Reasoncode2").click(function() {
$('#Reasoncode2').clone().insertAfter('#inputTextBox_Reasoncode2');
});
I dont want to do this for each and every reason code, i was wondering if there is a better approach to this.
My JSFiddle: https://jsfiddle.net/mvp71L61/
Assuming all buttons are statically added to the DOM,
$("button[class*='button_Reasoncode']").click(function() {
var rCode = $(this).attr('class').match(/\d+/g)[0];
$("div[id='Reasoncode'+rcode]").clone().insertAfter("input[id='inputTextBox_Reasoncode'+rcode]");
});

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"]();

How to pick out classes that start with a particular string

This might be hard to explain, but I need a way to loop through a bunch of elements I've already selected and for each one find classes that start with the word "icon". So for example I might have the following elements
<div class="button iconStar"></div>
<div class="button iconPlus"></div>
<div class="button iconLeft"></div>
<div class="button iconRight"></div>
<div class="button iconUp"></div>
<div class="button iconDown"></div>
So, I begin by selecting the elements and looping through them....
$(".button").each(function(){
// Some code here
});
Now, I could put the following code in the loop...
if ($(this).hasClass("iconStar")){
$(this).append("<IMG SRC='Images/star.gif'>");
}
I would then have to repeat that for each possible icon, which seems very inefficient.
What I'd like to do in the "each" loop is just cycle through all the classes that $(this) has and pick out the one that begins with ICON and then use that to append the image.
Can anyone help?
I recommend against using classes if you're not going to associate the class with the image. (which would be the most correct way) What I would do instead is put a link to the image in the rel tag.
This does what you want, and will still validate as valid css.
<div class="button" rel="images/star.jpg">iconStar</div>
<div class="button" rel="images/plus.jpg">iconPlus</div>
<div class="button" rel="images/left.jpg">iconLeft</div>
<div class="button" rel="images/right.jpg">iconRight</div>
<div class="button" rel="images/up.jpg">iconUp</div>
<div class="button" rel="images/down.jpg">iconDown</div>
<script>
$('.button').each(function() {
$(this).append("<img src='"+$(this).attr('rel')+"'>");
});
</script>
See the example here: http://jsbin.com/acasu
Note, if you're using a lot of tiny images, you're going to want to use CSS Sprites. As it will greatly improve the performance of your page.
If you absolute had to do it the way you are suggesting, you could do the following:
$(".button[class^='button icon']").each(function() {
var iconSrc = $(this).attr('class').substr("button icon".length)
$(this).append("<img src='/images/"+iconSrc+".jpg'>");
});
For each element, get the value of the class attribute, split it by ' ', take the second part and call the image.
From the top of my head
$(".button[class^='button icon']").each(function (el) {
classStr = el.className;
classes = classStr.split(' ');
image = 'images/' + classes[1] + '.jpg';
});
Not entirely sure of the syntax, bit rusty!
Try using this selector:
$(".button[class^='button icon']")
This should select only elements that have the class button, and also have a class that start with 'icon'.
Of course, this selector also assumes that your CSS class always begins with "button" first and not "icon".

Categories