using jquery to display words consecutively - javascript

I have a page that has 2 columns of words, 20 total, that are of a certain class (dim) and each a unique id. The ‘dim’ class defines the words as hidden. I have the following jQuery code running when I press a button:
$().ready(function()
{
var x = 20; // will be dynamic later :-)
$("#btn1").click(function()
{
for(i=1 ; i <= x ; i++)
{
//alert(i);
$(".dim").removeClass("hilite");
// this 'turns off' all the words
$("#wrd-"+i).addClass("hilite");
// this turns on the i'th word
}
});
});
When I uncomment the alert line I’m able to see that each word becomes visible and then hides again, just like it’s supposed to. The only problem is that it happens too fast. I want a way to make each loop wait a given number of nanoseconds. I’ve tried the setTimeout method but I can’t get it to do anything. Any idea how to slow this down? I’ve tried using .show and .hide but all the effects seem to happen at once.
My goal is to have the first word in column 1 display for 2 seconds. Then it goes away and word 1 in column 2 displays for 2 seconds. Then word 2 column 1, then word 2 column 2 and so on.
Thanks

You shouldn't need IDs like #wrd3 to step through the list of elements.
I haven't tailored the DOM selection for you, but this code will show and hide each item in a set, with a pause between. The interval in .fadeIn means the item will be showing for that about of time before the .fadeOut() function starts.
var things = $('.foo');
var index = 0;
things.hide();
var showHide = function() {
things.eq(index).fadeIn(2000,function(){
$(this).fadeOut(2000);
});
index++;
setTimeout(showHide,3000);
};
showHide();
Of course, you can change the fades to .show() and .hide(), or whatever other animation you want.

Related

Qualtrics display logic interferes with javascript .hide()

I have a side-by-side question in Qualtrics with 30 rows. Each of the first 20 rows has display logic such that they only appear when something is entered in text boxes in prior questions. Each of the last 10 rows has display logic such that at least 10 rows show up in the entire question, i.e. row 21 only shows up if none of the first 20 are displayed, row 22 shows up if only one of the first 20 are displayed... row 30 shows up if 9 of the first rows are displayed, and none of them appear if at least 10 of the first rows are displayed.
The first column of the question is a checkbox, and I'm using the following Javascript to hide the checkboxes for the last 10 rows:
Qualtrics.SurveyEngine.addOnload(function()
{
var qid = this.questionId;
var p = $(qid);
p.down('label[for="QR~'+qid+'#1~21~1"]').hide();
p.down('label[for="QR~'+qid+'#1~22~1"]').hide();
p.down('label[for="QR~'+qid+'#1~23~1"]').hide();
p.down('label[for="QR~'+qid+'#1~24~1"]').hide();
p.down('label[for="QR~'+qid+'#1~25~1"]').hide();
p.down('label[for="QR~'+qid+'#1~26~1"]').hide();
p.down('label[for="QR~'+qid+'#1~27~1"]').hide();
p.down('label[for="QR~'+qid+'#1~28~1"]').hide();
p.down('label[for="QR~'+qid+'#1~29~1"]').hide();
p.down('label[for="QR~'+qid+'#1~30~1"]').hide();
});
It works fine if none of the previous rows are displayed:
But bombs if even one of the previous rows is displayed:
I poked around with Inspect Element on the preview to see if the tags changed somehow, but couldn't find anything unexpected as far as changing IDs. When checking the element for the checkbox on row 23 when none of the first 20 rows appear:
<input id="QR~QID4#1~23~1" name="QR~QID4#1~23~1" value="Selected"
data-runtime-checked="runtime.Children.1.Choices.23.Answers.1.Selected"
aria-labelledby="question1QID4 question1QID4-answer1QID4 choice23QID4"
class="QWatchTimer" type="checkbox">
<label for="QR~QID4#1~23~1" class="q-checkbox" data-runtime-class
-q-checked="runtime.Children.1.Choices.23.Answers.1.Selected"
style="display: none;"></label>
As expected, the label code is grayed out. When one of the first 20 rows appears, it's much the same, but style="display: none;" does not appear at the end:
<input id="QR~QID4#1~23~1" name="QR~QID4#1~23~1" value="Selected"
data-runtime-checked="runtime.Children.1.Choices.23.Answers.1.Selected"
aria-labelledby="question1QID4 question1QID4-answer1QID4 choice23QID4"
class="QWatchTimer" type="checkbox">
<label for="QR~QID4#1~23~1" class="q-checkbox" data-runtime-class
-q-checked="runtime.Children.1.Choices.23.Answers.1.Selected"></label>
I'm at a loss for how activation of display logic would interfere with the Javascript.
After a few hours of percolating, I remembered that if a display logic hides an item with Javascript, that script won't run. I hadn't realized that it's not just on a line-by line basis - looks like if one element controlled by one line of code gets hidden, the whole block of code gets invalidated.
I was able to solve it with a loop that dynamically considered only the rows that would be displayed:
Qualtrics.SurveyEngine.addOnload(function()
{
//Remove checkboxes for last ten options
var qid = this.questionId;
var p = $(qid);
var count = Qualtrics.SurveyEngine.getEmbeddedData('count');
var min = 21+count;
for (var i = min; i < 31; i++) {
p.down('label[for="QR~'+qid+'#1~'+i+'~1"]').hide();
}
});
At least in my case, the count variable was used to determine how many of the last 10 rows to display. Once I built that into the parameters for the loop, nothing would be invalidated by the display logic. (Check here for the process on that if interested.)
Lesson learned: I should've been using a loop to begin with - modifying the parameters is an easy step after that.

Navigation with an if that counts and add elements certain times

I'm looking to create a interactive nav bar for my own personal study purposes, so the idea behind it is if you click on down the number in the corner of the screen changes and a new image and text pops up every time this goes til number(page 5) all the other elements would be on display none except that one page that is active
I'd like to know if it would be possible to create a nav bar and lets say you have a set up nav with 2 buttons up and down how to make certain things not show up and others show up, i think my counter or var is not calculating properly, this is my javascript if statement( more in depth js fiddle https://jsfiddle.net/emilegmn/1L3h51zw/ )
if(numberCount < 1 ) {
add class to nav showing only one button ( down )
}
and this is my counter
numberCount = numberCount + 1
and then after that between 2-4 to show 2 buttons ( up and down )
and at 5 to only show up.
If someone has any things or knows something online that does this, please link me to it if you want!
I have tried finding how to do this but I am still trying to get it all figured out,
Thanks in advance and for your time!
If I understand correctly, is this what you want to achieve:
User clicks between two buttons to make new things appear (like a slider maybe?) but in a nav bar.
To do so you need JavaScript as well as an HTML structure that helps you out. In summary, you could do something along these lines. Granted this only takes into account a sort of "next button", if you want a previous one then you just need to add another function that instead of adding to the current_slide , subtracts from it.
Happy coding!
HTML
<nav id="slider-nav">
<div id="slide-1" class="active"></div>
<div id="slide-2"></div>
<div id="slide-3"></div>
<div id="slide-4"></div>
</nav>
CSS
With this you make sure that only the <div> with class .active is visible
#slider-nav div:not(.active) {
display:none;
}
JS
This would be your sweet JavaScript (jQuery)
//To be placed within your document ready function
const nav_slides =[]; //Holds the id of all your slides
var current_slide = 0;
$('#slider-nav div').each(function(){
nav_slides.push('#' + $(this).attr('id'));
});
/*This would be the part of when clicking happens on the 'next' button in your nav.
Keep in mind that the definition of the function must be within the same
scope as the defined variable, current_slide and nav_slides.
Hopefully, all encapsulated into one single scope that is your api.*/
function nextSlide(){
$(nav_slides[current_slide]).removeClass('active');
current_slide = (current_slide + 1) % nav_slides.length;
//Move on to next slide
//It's a circular counter, when it reaches max slide 4, it'll go back to 0
$(nav_slides[current_slide]).addClass('active');
}
ps: The initialization of current_slide is not dynamic. If in your HTML you happen to change who the first slide with active class is, then you need to update it in your JS. It would be very useful to initialize that current_slide dynamically, in other words, not hard coded out of laziness.

How to edit the ID of each button in a class if a condition is true in JavaScript?

I'm using ChartJS to generate a pie chart in that elements are added every time the user clicks a specific button (I have 14 buttons that trigger the adding of a specific element in the pie chart, each one triggers a function that adds info to 3 arrays as needed in order for the chart to work.
Every time the user clicks a button a new one is created in a div that contains all the elements that are present in the chart because I want them to be able edit or delete the elements as needed.
To know what which elements from my arrays is edited by which edit button I'm using a variable named btnctr that I initialized with 0 at the beginning of my JS file. That variable gives every new ”edit button” an ID and then then increments, like this:
function CreateEditButton() {
var buttonnode= document.createElement('input');
buttonnode.setAttribute('type','button');
buttonnode.setAttribute('id',btnctr);
...
$("#rotationelements").append(buttonnode);
$("#rotationelements").append(' ');
btnctr++;
};
My problem is that I also have to make deleting elements possible. I'm using splice for deleting elements from the arrays, but that also messes up the position of other elements and my edit buttons become useless.
I want to also edit the IDs of my buttons when I delete elements, because I need them to be in sync.
Here's what I've come with so far:
// Get editbuttons
var editbuttons = document.getElementsByClassName('editbtn');
// Delete element
function deleteElement (x) {
names.splice(x,1);
dataset.splice(x,1);
colors.splice(x,1);
chart1.update();
time=time-length[x];
length.splice(x,1);
UpdateTime();
var delbtn=$("#"+x);
$(delbtn).remove();
var newid=x;
for (var i=0; i<editbuttons.length;i++) {
if (editbuttons[i].id>x) {
editbuttons[i].id=newid;
newid++;
btnctr=newid++;
}
}
}
Thanks!
Lulian, inside of your for loop it looks like you are only changing the id's of editbtns after the one that was deleted above. You may want to try taking out the if statement and replacing "newid" with "i":
for (var i=0; i<editbuttons.length;i++) {
// if (editbuttons[i].id>x) {
editbuttons[i].id=i;
//newid++;
btnctr=i;
// }
}
This way you can re-initialize all of you editbtn's and btnctr to match from beginning to end.

Javascript/Jquery element carousel

I am trying to make a javascript/jquery carousel. I have an unordered list and inside the ulist i have more lists. I get the first lit with:
list = $(wrapper).find("li:eq(0)").show()
On the button-next down i want it to show next list so it would be:
list = $(wrapper).find("li:eq(1)").show()
on the button-previous i want the list to show previous list. How could I achieve something like this, to append ("li:eg(x+1/x-1)).show()
Introduce a variable to keep track of the current list. When a user clicks the next button, increment it by one, and vice-versa for when previous is clicked. Then use this variable in your selector.
list = $(wrapper).find("li:eq("+ currentList +")").show()
Sidenote: You might want to introduce some bounds checking so currentList never goes below 0 and never exceeds the number of lists you have available.
//On previous click
if(currentList - 1 > 0){
//do something
}
//assign a variable to keep track of the upper bounds
var maxList = $(wrapper).find('li').length;
//On next click
if(currentList + 1 < maxList - 1){
//do something
}

Change the line selected in textarea

I'm using jquery to display the line beside the textarea.
from this link:
http://alan.blog-city.com/jquerylinedtextarea.htm
Is there any way to change the selected line, so every time the user goes to the next line the line selected changes to the current line.
$(function()
{
// Target all classed with ".lined"
$(".lined").linedtextarea(
{
//change it from 1 to the current line that the user on.
selectedLine: 1
});
// Target a single one
$("#mytextarea").linedtextarea();
});
yep,
function selectLine(n) {
if (n<1) return false; //If the total number of lines is known it is worth checking you are not above it either
$(".codelines .lineno.lineselect").removeClass("lineselect")
$(".codelines .lineno").eq(n-1).addClass("lineselect");
}
with a lot of jQuery plugins (when they are full on jQuery widgets) you can use the "options" method to do this kind of thing, like $(".lined").linedtextarea("options",{selectedLine: 6}) but it doesn't look like this has been turned into a widget. This solution is kind of reverse engineered from the fact that the mod uses the lineselect class to control which line number is highlighted.
We do some checking to make sure we will use a sane value, remove the highlight class from any lines that have it already, and add it to the n-1th line number div (-1 because eq is Zero based).
This won't work if you have multiple lined text boxes on the one page. If that's the case we need to add another parameter to define which one to target and some logic to handle that.

Categories

Resources