Reply To: How to make keypress add a CSS class to text

PennController for IBEX Forums Support How to make keypress add a CSS class to text Reply To: How to make keypress add a CSS class to text

#10614
Jeremy
Keymaster

Hi,

First let me bring your attention to what I said at the beginning of this message, repeated here:

Template scans the table and produces one output per row. So the idea is, you use Template( row => newTrial to generate one trial per row. Listing one word per row is not the ideal way to go if you want to display several of them at the same time on the page, ie. during the same trial

If you want to display several words on one screen, listing them on different lines in a CSV file is not the way to go

One way to implement what you describe is to proceed very similarly to what we discussed in the other thread: instead of incrementing the value of the Var element named “nextWordStartsAt” by 10 on each keypress and replacing the text of the Text element named “words” with the next 10 words, you increment the value by 1 each time and replace the text with the same list of words each time, just edited to place an HTML tag around the next word each time

So it could look something like this, assuming you always list 9 words in your table’s “Words” column (you could do 12 words as in your example too, just adjust the widths and heights accordingly to fit 4×4 words):

// embed each word in a span, highlight the very first one
newText("words", row.Words.split('_').map((w,i)=>`<span class='word ${i==0?'highlighted':''}'>${w}</span>`).join(''))
    .cssContainer("width","810px") // 3 times the space reserved for each word + horizontal padding
    .css({
        display: 'flex',            // items contained in the element will be rearranged smartly
        'flex-direction': 'column', // stack items in columns 
        'flex-wrap': 'wrap',        // items that overflow vertically will start on new columns
        'font-size': '50px',
        height: '210px'             // more than 3 times the space reserved for each word + vertical padding
    })
    .print()
,
newVar("listOfWords", ""), // we'll update this Var element with the list of words tagged as desired
newVar("highlightedWord").set(0) // this is the index of the highlighted word
,
newKey("NEXT", " ")
    .callback(
        // first make sure that the next index is within bounds
        getVar("highlightedWord").test.is(v=>v+1<row.Words.split('_').length).success(
            getVar("highlightedWord").set(v=>v+1) // increment the index of the highlighted word
            ,
            getVar("listOfWords") // update listOfWords with appropriate tags
                .set(getVar("highlightedWord")) // first look up the index
                .set(v=>row.Words.split('_').map((w,i)=>`<span class='word ${i==v?'highlighted':''}'>${w}</span>`).join('')) // now set the class as desired
            ,
            getText("words").text( getVar("listOfWords") ) // update the content of the Text element
        )
    )

In global_main.css, you add these rule:

.PennController-words .word {
    width: 230px;
    height: 60px;
    padding: 5px 15px;
}
.PennController-words .word.highlighted {
    outline: solid 10px yellow;
    border-radius: 0.25em;
}

Just make sure the width you pass in your script to .cssContainer is at least 3 times (the width + 2*padding) and the height you pass to .css is at least 3 times (the height + 2*padding), that you set in the file’s CSS rule for .word.

Jeremy