[TamperMonkey] Select field value

Hi, from the bottom of this page I’m trying to change last ‘select’ name from “Indice e sommario” to “Classificazione”. I tried:

// ==UserScript==
// @name         Select 'Classificazione'
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://sol.unibo.it/SebinaOpac/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=google.it
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
window.addEventListener('load', function() {
document.getElementsByName('canale')[5].value = 'CL';
      }, false);
})();

but in this way the arrow of the empty field next to it to scroll the list of terms disappears.
Thank you!

1 Like

Try this:

let select = document.getElementsByName('canale')[5];
select.options[6].removeAttribute('selected');
select.options[8].setAttribute('selected','');

Thanks, Archibald, same result, the arrow disappears.

This appears to work

  // A little clearer as to what element in the DOM we are selecting
  const criteria = document.querySelector('li[data-field="INDICE"]')
  const selectOpts = criteria.querySelector('select[name="canale"]')
  
  selectOpts.value = 'CL'
  selectOpts.dispatchEvent(new Event('change'))

Create a reusable function:

To improve on that, and make something that is more re-usable we could wrap it in a function

const selectOption = function (criteria, value) {
  // use a template string to parse the criteria e.g.
  // const who = 'World!'; `Hello ${who}` → 'Hello World!'
  const selectedCriteria = document.querySelector(`li[data-field="${criteria}"]`)
  const selectOpts = selectedCriteria.querySelector('select[name="canale"]')
  
  selectOpts.value = value
  selectOpts.dispatchEvent(new Event('change'))
}

selectOption('INDICE', 'CL')

Final script:

(function() {
  'use strict';

  const selectOption = function (criteria, value) {
    const selectedCriteria = document.querySelector(`li[data-field="${criteria}"]`);
    const selectOpts = selectedCriteria.querySelector('select[name="canale"]');
    
    selectOpts.value = value;
    selectOpts.dispatchEvent(new Event('change'));
  }

  window.addEventListener('load', function() { selectOption('INDICE', 'CL'); });
})();

1 Like

Arrow does not disappear here:

That’s the solution, thanks very much, rpg_digital!!!

P.S. Thanks, Archibald, don’t know why, but with TamperMonkey the arrow disappears with my and your script.

Wao, great!! Does your script let 2 fields change at the same time? For example:

  1. [Contesto di ricerca] From Catalogo to Libro moderno
  2. From Indice e sommario to Classificazione

The script I wrote for you was targeting the criteria fields. For what you are asking now, you would need a more general selector.

  const selectOption = function (selector, value) {
    const selectOpts = document.querySelector(selector)
  
    // if a valid select element
    if (selectOpts && selectOpts.matches('select')) {
      selectOpts.value = value
      selectOpts.dispatchEvent(new Event('change'))
    }
  }

// explicit selections
selectOption('.riga-contesto select[name="contesto"]', 'tnatm')
selectOption('li[data-field="INDICE"] select[name="canale"]', 'CL')

Final script:

(function() {
  'use strict';

  const selectOption = function (selector, value) {
    const selectOpts = document.querySelector(selector);
  
    // if a valid select element
    if (selectOpts?.matches('select')) {
      selectOpts.value = value;
      selectOpts.dispatchEvent(new Event('change'));
    }
  }

  window.addEventListener('load', function() { 
    selectOption('.riga-contesto select[name="contesto"]', 'tnatm');
    selectOption('li[data-field="INDICE"] select[name="canale"]', 'CL');
  });
})();
1 Like

Perfect, thanks so much, rpg_digital!!

1 Like

Hi, rpg_digital, may I ask you how would last script change replacing also “ISBN/ISSN” with “Soggetto”? Thank you!

To find the solution in chrome right click on the ISBN select option and click on ‘inspect’. You will be able to see that the field containing ISBN is a list item with a data-field property of ‘ISBN’.

inspect-element

From that we can write the selector to target the select option menu we want

'li[data-field="ISBN"] select[name="canale"]'

If you look through the list of options in that select option menu, a little further down in the elements inspector window you will see a ‘SO’ option

sogetto

That is the value you want to change the select menu to. So put that together and you have.

selectOption('li[data-field="ISBN"] select[name="canale"]', 'SO')

Hopefully that helps you.

1 Like

Thank you very much, rpg_digital!

1 Like

Could you tell me why this TamperMonkey script doesn’t focus on “Classificazione” field?

focusme = document.querySelector("#ricerca-avanzata > form > ul > li:nth-child(5) > label.text.terms > input[type=text]");
focusme.focus();

It’s the wrong selector. If you console.log(focusme) you will get null. This means querySelector was unable to find the element in your selector.

I think this might work

const input = document.querySelector('li[data-field="INDICE"] label.text input[type="text"]')
input.focus()

Strangely I can’t test focus in the chrome console.

It’s almost 10 on a Friday night, so as far as coding problems that’s it for me now :slight_smile:

Sure, thank you again!

With the firs script It focuses on “Classificazione” field for just a fraction of second, then it focuses on default field, “Titolo”…

(function() {
  'use strict';

  const selectOption = function (selector, value) {
    const selectOpts = document.querySelector(selector);

    // if a valid select element
    if (selectOpts?.matches('select')) {
      selectOpts.value = value;
      selectOpts.dispatchEvent(new Event('change'));
    }
  }

  window.addEventListener('load', function() {
    selectOption('.riga-contesto select[name="contesto"]', 'tnatm');
    selectOption('li[data-field="ISBN"] select[name="canale"]', 'SO')
    selectOption('li[data-field="INDICE"] select[name="canale"]', 'CL');
  });
    const input = document.querySelector('li[data-field="CL"] label.text input[type="text"]')
input.focus()
})();

A tricky one.

You have something like 80+ js scripts on that page :astonished:. On selecting an option, one of those scripts makes changes to the DOM. It looks like you have spotted this e.g.

// this element
document.querySelector('li[data-field="INDICE"]...
// has it's data-field changed to
document.querySelector('li[data-field="CL"]...

In an ideal world you would want a focus callback function to fire once that script had finished doing it’s thing.

A temporary and somewhat unreliable approach is to use a setTimeout and a delay. In my tests with tampermonkey this is working.

(function() {
    const focusOnInput = function (selector, delay = 250) {
        setTimeout(() => {
            const input = document.querySelector(selector)

            if (input?.matches('input')) {
                input.focus()
            }
        }, 250)
    }

    const selectOption = function (selector, value) {
        const selectOpts = document.querySelector(selector);

        // if a valid select element
        if (selectOpts?.matches('select')) {
            selectOpts.value = value
            selectOpts.dispatchEvent(new Event('change'))
        }
    }

    window.addEventListener('load', function() {
        selectOption('.riga-contesto select[name="contesto"]', 'tnatm')
        selectOption('li[data-field="ISBN"] select[name="canale"]', 'SO')
        selectOption('li[data-field="INDICE"] select[name="canale"]','CL')

        // delay of 250ms before focusing on element (unreliable!)
        focusOnInput('li[data-field="CL"] label.text input[type="text"]', 250)
    })
})()

Will do some more digging.

1 Like

Yes, I thought about using a setTimeout, but didn’t know how.
Is it possible to add this change too? In Biblioteca/Sistema pick “Comune di Bologna” and “B. Archiginnasio” and have this result:

I tried with:

selectOption('.riga-biblioss syw-comboselect-wrapper', 'B. Archiginnasio')

but I don’t think it’s the right way. Thank you for your assistance!

There is nothing consistent or standard about this form. This appears to work though.

document.querySelector('.riga-biblioss [data-group="Comune"] li[data-cd="UBOGA"] .select').click()

Mhm, not really. If you input this string in title, for example:

andra tutto bene

the records resulting may exclude B. Archiginnasio