1

I've been searching restlessly for a way to automatically select a survey form button that contains a specific word. I am using Tampermonkey in Google Chrome. In this case, I would like to automatically select buttons with the word 'Male' in them.

Here is an example of the type of button I am talking about (including CSS/HTML):

enter image description here

So for the question: "What is your gender?", I would like to automatically select 'Male.' I have been running through all of the stackoverflow questions I can find that could possibly help, but with no results. I chose a label-based method and used "textContent" to hopefully be able to recognize the text within the form question.

Here is the code I am currently working with (from How can I auto-select a radio button with Greasemonkey?):

// ==UserScript==
// @name         Button Text Form Filler
// @include      https://tasupport.co1.qualtrics.com/jfe/form/SV_0qez6NHJGoCAmMt
// @version      1.0
// @description  Demonstration script to change form values
// ==/UserScript==

var labels = document.getElementsByTagName('label'); 
for (var i = 0; i < labels.length; ++i) { 
    if (labels[i].textContent == "Male") { 
        labels[i].click(); 
    }
}

Unfortunately, the code doesn't work and the button for 'Male' is not selected on page load. This can be tested in the 2nd page of the following website: https://tasupport.co1.qualtrics.com/jfe/form/SV_0qez6NHJGoCAmMt (where the above screenshot comes from).

I have also tried the following with jQuery (How do I automatically click this button with tampermonkey?):

// ==UserScript==
// @name         jQuery Button Test
// @version      0.1
// @require      https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
// @include      https://tasupport.co1.qualtrics.com/jfe/form/SV_0qez6NHJGoCAmMt
// ==/UserScript==

$(document).ready(function() {
  $("button:contains('Male')").click();
});

Again, nothing.

There are a few similar questions to mine scattered across stackoverflow, but none of the solutions appear to work here, or perhaps the code I am working with is outdated. I would appreciate any and all help. Thanks in advance.

theCrabNebula
  • 731
  • 2
  • 13
  • 29

3 Answers3

1

Try if this works

$( ".SingleAnswer span" ).each(function( index ) {
       if($( this ).text().includes("Male")) {
           $( this ).click()
       }
});
  • Thanks for the response. I tried it in the console but kept getting the error: Uncaught TypeError: Cannot read property 'each' of null at :1:26 – theCrabNebula Jan 18 '19 at 23:45
1

I have tried the following in the dev console and it works. Hope it helps

Array.from(document.querySelectorAll('label > span')).find(e => e.textContent === 'Male').parentElement.click()

The label has an id you can use. You don't need to search in the textContent for Male when you use these id.

document.getElementById('QID2-1-label').click()

edit

for tampermonkey you need some settings to deal with the xhr requests. You need jQuery, waitForKeyElements.js and the @match needs your xhr urls.

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You

// @match        https://tasupport.co1.qualtrics.com/jfe/form/SV_0qez6NHJGoCAmMt
// @match        https://tasupport.co1.qualtrics.com/jfe2/form/SV_0qez6NHJGoCAmMt/next?rand=775440350&tid=1&t=1547858208474
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==

const fire = () => Array.from(document.querySelectorAll('label > span')).find(e => e.textContent === 'Male').parentElement.click();

// another option
// const fire = () => document.getElementById('QID2-1-label').click();

waitForKeyElements (
    "#QID2-1-label",
    fire
);
d-h-e
  • 2,478
  • 1
  • 10
  • 18
  • This works in the console on my end as well! Thank you. Unfortunately, it doesn't appear to work on page load in Tampermonkey. Do you know why this would be? – theCrabNebula Jan 19 '19 at 00:21
  • I think it may be AJAX driven so I am trying to find solutions that deal with dynamic loading. – theCrabNebula Jan 19 '19 at 00:38
  • 1
    yes, you are right. The AJAX-Requests are the problem. I have edit my post. Hope it works for you – d-h-e Jan 19 '19 at 01:19
  • Thanks again! Just wondering, is there a way to do this with the first jQuery code you posted? I would like to use the method of finding the actual string of text instead of using elementID if possible. I would like to apply this method to other webpages that might have different element IDs. – theCrabNebula Jan 19 '19 at 01:26
  • 1
    The first code works too. (not jQuery - normal JavaScript) `const fire = () => Array.from(document.querySelectorAll('label > span')).find(e => e.textContent === 'Male').parentElement.click()` – d-h-e Jan 19 '19 at 01:31
  • Beautiful, this is amazingly helpful. One last question, say I want to apply this on a different page, but the labels are different. Is there another way to use "waitForKeyElements" that could be more generally applied? – theCrabNebula Jan 19 '19 at 01:42
  • 1
    If you know, that all sites have ` – d-h-e Jan 19 '19 at 01:59
  • That might just work! It worked when I tried it with Tampermonkey on my example page. You've helped so much, thanks again! – theCrabNebula Jan 19 '19 at 02:09
  • Oh, and say I want to include other words, like 'Mr.," for instance. How could I do this? I would need to modify find(e => e.textContent === 'Male'). Maybe find(e => e.textContent === 'Male', 'Mr.')? Or should I just add another line and replace 'Male"? – theCrabNebula Jan 19 '19 at 02:14
1

There is no button element. The element listening to the user click event is actually a hidden input:

<li class="Selection reg">
  <!-- this input -->
  <input choiceid="1" aria-labelledby="QID2-1-label" class="radio QR-QID2-1 QWatchTimer" type="radio" name="QR~QID2" id="QR~QID2~1" value="1" data-runtime-checked="runtime.Selected">

  <!-- not these elements -->
  <label for="QR~QID2~1" class="q-radio q-checked" aria-hidden="true" data-runtime-class-q-checked="runtime.Choices.1.Selected"></label>  <span class="LabelWrapper"> 
  <label for="QR~QID2~1" id="QID2-1-label" class="SingleAnswer  q-checked" data-runtime-class-q-checked="runtime.Choices.1.Selected"><span>Male</span></label></span> <div class="clear"></div>
</li>

So you need to call the click method of the input element to trigger it. For example you could do:

var labels = document.getElementsByTagName('label');

for (var i = 0; i < labels.length; ++i) { 
    if (labels[i].textContent == "Male") { 
        labels[i].parentElement.parentElement.firstElementChild.click()
    }
}
Saraband
  • 1,540
  • 10
  • 18