Greasemonkey - how to change certain text in a value?

Scorpion Ghost

Elite Member
Executive VIP
Jr. VIP
Joined
Mar 22, 2013
Messages
8,692
Reaction score
10,261
We have this HTML on a page which appears after I do a few clicks (not on pageload):

HTML:
<input class="form-control" value="07/01/2022 12:00 AM" type="text">

I want to change the "AM" to "PM" using Greasemonkey. I tried one method, and while I could see the change in the text box, it wasn't actually "recorded" by the site.

Then I found another method which works, except it breaks the entire site and I can't click anything else on the site after running the code:

JavaScript:
var els = document.getElementsByClassName("form-control");
for(var i = 0, l = els.length; i < l; i++) {
  var el = els[i];
  document.body.innerHTML = document.body.innerHTML.replace(/AM/gi, 'PM');
}

I found this code here (I edited it slightly using one of the replies to make it work) - https://stackoverflow.com/questions/1155353/find-and-replace-in-a-webpage-using-javascript

One of the guys gave this reply:

Modifying innerHTML, which inculdes each element's children, is a very bad advice because it'll break lots/most of pages that use addEventListener and element references.

I think this is my problem. When I run the code, it makes the change I want, but it breaks the site.

Can anyone help? Thanks
 
Do you have access to the html and can you modify? Open up the html and to that tag add an id like so:

HTML:
<input id="UniqueID" class="form-control" value="07/01/2022 12:00 AM" type="text">

Next up. Wherever you added that js script. Change it to this:
JavaScript:
let elem = document.getElementById("UniqueID");
// UniqueID is the Id value you set  in the input tag

elem.value.replace('AM', 'PM');

Let me know if it worked.
 
Do you have access to the html and can you modify? Open up the html and to that tag add an id like so:

HTML:
<input id="UniqueID" class="form-control" value="07/01/2022 12:00 AM" type="text">

Next up. Wherever you added that js script. Change it to this:
JavaScript:
let elem = document.getElementById("UniqueID");
// UniqueID is the Id value you set  in the input tag

elem.value.replace('AM', 'PM');

Let me know if it worked.

I don't have access to the HTML, but I may be able to modify it using Greasemonkey. Not sure if that would work though.

I tried this in the browser console:

JavaScript:
let elem = document.getElementsByClassName("form-control");
elem.value.replace('AM', 'PM');

It doesn't work. I get this error:

SyntaxError: redeclaration of let elem

Would adding an ID to the code make any difference than using the class?
 
SyntaxError: redeclaration of let elem
That means Some other variable which is a const also has the name elem. Try changing "let elem" to something else like "let UniqueElementHandler = ... "
It won't work without the right html anyways ig.

Would adding an ID to the code make any difference than using the class
Yes. It makes a massive difference. Your code `document.getElementsByClassName('form-control') captures all the elements that have the class "form-control" and then changes each of those element's innerHTML. That breakes the site.

You need an unique identifier for that input form. The classname isn't one. An id would be one. So would be an absolute XPATH.

Also, what is GreaseMonkey?
 
Okay anyway, I took care of what I needed using iMacros.

I'd feel better if Greasemonkey was doing it, but I do what I can...

That means Some other variable which is a const also has the name elem. Try changing "let elem" to something else like "let UniqueElementHandler = ... "
It won't work without the right html anyways ig.


Yes. It makes a massive difference. Your code `document.getElementsByClassName('form-control') captures all the elements that have the class "form-control" and then changes each of those element's innerHTML. That breakes the site.

You need an unique identifier for that input form. The classname isn't one. An id would be one. So would be an absolute XPATH.

Also, what is GreaseMonkey?

Ok a simple thing has gotten ridiculously hard and time-consuming, so I took care of what I needed in another way. Thanks anyway :)

Greasemonkey is a browser extension that allows you to do Javascript and Jquery stuff in the browser. Like you can do clicks and fill forms and remove elements and pretty much anything with Javascript and Jquery (different browsers have different limitations though, I think). There's also Tampermonkey and Violentmonkey, but I only ever used Greasemonkey.

I'm sure I'm not explaining it properly, but hopefully you get the idea.
 
That means Some other variable which is a const also has the name elem. Try changing "let elem" to something else like "let UniqueElementHandler = ... "
It won't work without the right html anyways ig.


Yes. It makes a massive difference. Your code `document.getElementsByClassName('form-control') captures all the elements that have the class "form-control" and then changes each of those element's innerHTML. That breakes the site.

You need an unique identifier for that input form. The classname isn't one. An id would be one. So would be an absolute XPATH.

Also, what is GreaseMonkey?

Here is what Greasemonkey is, one example.

I'm trying to automate some automation, and I use iMacros (another automation browser extension that does clicks on webpages). And I have an issue where there is a table of days in July, but it also includes a few last days of June and few first days of August.

If my iMacro clicks on 28, the table will flip me back to June (because the 28 of June comes before 28 of July). What I could do is have my iMacro click on the second 28 in the table, but this is inefficient because different months have different amount of days from the previous months. So July may be showing 27/28/29/30 of June on the table, but August may be showing 26/27/28/29/30 of July on the table.

So automating for long-term, if I always click the second day, I'll always miss 1-3 days each month. In the example above, the 2nd 26 of July doesn't exist on the page because the 26 of June is not displayed, and then when my iMacro tries to click the 2nd 26 of July it will fail, resulting in no click, and a failed attempt at that particular action.

So I tried using Stylem (browser extension that allows you to manipulate CSS on a page) in order to set the first line of days of each month as "display:none". But this didn't work because with "display:none" the code still remains visible in the HTML, and iMacros still click where I don't want them to click.

And this is where Greasemonkey comes in:

JavaScript:
$(".rdtDays > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(1)").remove ();

I put this in and Greasemonkey will always REMOVE that content. It won't just hide it from being displayed, it will REMOVE it, NUKE it out of existence. Unfortunately the content I'm trying to hide has absolutely no unique selectors, so I'm forced to use a "CSS selector". Luckily the page is pretty static, so the CSS selector should remain the same for a long long time, hopefully.

And so now whenever that page loads, Greasemonkey removes the first line of days from the table, and my iMacro can always click on the 1st option of the day I need, and it will always get the correct one :cool:

Greasemonkey is awesome dude, I use it a lot. But I suck at coding so I spend hours figuring things out reading Stackoverflow and the internet, and if the situation is really hard then I ask here or on Stackoverflow for help, and usually a wizard pops in and solves my problem (usually here and not on stackoverflow, as the guys on stackoverflow are kinda dicks, downvoting me and shit haha), or I figure out an ugly solution and I implement it. My ugly solutions are usually very ugly and unnecessarily long scripts, but they work and I move on :p
 
Last edited:
And just to finish this... I thought it was finished... but then the script would remove content over and over again. And I can't use a setTimeout thing because, well, it's not efficient in this case.

So I needed something to wait for my element to appear, and then run my code 1 time. And stackoverflow has TONS of replies and methods to do this, and I don't understand any of them. I tried a few, failed. You guys just love to complicate. You would make boiling an egg complicated. And all I need is simple stuff.

Anyway after many years and countless hours, I got something that works:

JavaScript:
// ==UserScript==
// @name        asd
// @include     https://stupidsite.com/
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0.   It restores the sandbox.
 */



// Wait for element to exist.
  function elementLoaded(el, cb) {
    if ($(el).length) {
      // Element is now loaded.
      cb($(el));
    } else {
      // Repeat every 500ms.
      setTimeout(function() {
        elementLoaded(el, cb)
      }, 500);
    }
  };

  elementLoaded('.rdtDays', function(el) {

    $(".rdtDays > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(1)").remove ();

  });

This works. It waits for a certain class to appear, and then runs my .remove code.

I have no idea what all this code is. Okay, I have a little idea, but not really. I just click with my mouse a little bit, and eventually I get something working.

Okay we're done here I can't grow old doing this :D
 
Back
Top