0

I am trying to implement a feature where I can the toggles the display of two buttons and submit a form.

  • Code

test() {
  var x = document.getElementById("iniciar");
  var y = document.getElementById("pausar");

  if (x.style.display === "none") {
    x.style.display = "block";
    y.style.display = "none";

  } else {
    x.style.display = "none";
    y.style.display = "block";
  }
}
<div class="images-board">

  <div id="iniciar" class="buttons">
    <form class="btn" action="{{ url_for("index")}}" method="post">
      <button class="form" onclick="test()" type="submit" class="btn btn-dark"><i class="fa fa-trash"></i> Iniciar</button>
    </form>
  </div><br>

  <div id="pausar" style="display:none" class="buttons">
    <form class="btn" action="{{ url_for("index")}}" method="get">
      <button onclick="test()" class="form" type="submit" class="btn btn-dark"><i class="fa fa-trash"></i> Pausar</button>
    </form>
  </div><br>

</div>

But every change made by JavaScript is reversed when the forms are submitted.

Is there any way I can toggle the buttons and submit the forms?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Vanessa
  • 62
  • 7
  • You can't use `function` as the name of the function, it's a reserved word. – Barmar Sep 09 '22 at 01:19
  • 1
    I don't see anything in your code that will display that error message. – Barmar Sep 09 '22 at 01:28
  • Why are you using `type="submit"` for the buttons? You don't want to submit the form, you just want to toggle the divs. – Barmar Sep 09 '22 at 01:30
  • Perhaps you pulled up the wrong path to the HTML page in your browser. – code Sep 09 '22 at 01:30
  • @Barmar I need submit the form because I will use the post method. – Vanessa Sep 09 '22 at 01:54
  • But if you submit the form then why do you need to toggle anything. Submitting the form reloads the page, so you lose your changes. – Barmar Sep 09 '22 at 01:56
  • I think that you are misunderstanding name property of function. Because function is a reserved word, so it cannot use here. – Quyen Nguyen Sep 09 '22 at 01:57
  • @Barmar You are right, that's exactly what happened now. – Vanessa Sep 09 '22 at 01:59
  • Because this butons will work this way: clicking on button 1 goes to state 2, clicking on button 2 goes to state 1. So it doesn't make sense to have the buttons appear at the same time. How can I solve my problem? – Vanessa Sep 09 '22 at 02:02
  • onsubmit="return false". you can add it for form tag – Quyen Nguyen Sep 09 '22 at 02:22
  • Can't you just not use a form? What's the purpose? – code Sep 09 '22 at 04:16
  • @Vanessa - You dont need any javascript for this. When you submit the form, control returns server side to whatever language you are using. If you are using php (as an example), then you have the opportunity to alter the form before it is shown again. What language are you using server-side ? And you – Rohit Gupta Sep 09 '22 at 04:20
  • @QuyenNguyen if I use `onsubmit="return false"`, I will only use the post or get method with one button, the goal was to access the post or get method by clicking both. – Vanessa Sep 09 '22 at 12:56
  • @RohitGupta I am making use of python on serve-side. It makes sense what you said, however I don't know how I would do to toggle the buttons through python. In this case, could I use jinja2 to create an if condition? – Vanessa Sep 09 '22 at 13:00
  • Yes you can use jinja – Rohit Gupta Sep 09 '22 at 13:11
  • You actually have to change the contents of index.html file itself. – Rohit Gupta Sep 09 '22 at 22:18
  • I posted the new code I made with a reply. What do you mean by _change the contents of index.html file itself_? – Vanessa Sep 09 '22 at 22:43

2 Answers2

-1

You can change with this way:

index.html file

    <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="index.js"></script>
  </head>
  <body>
    <div class="images-board">
      <div id="iniciar" class="buttons">
        <form class="btn" onsubmit="return false">
          <button
            class="form"
            onclick="test()"
            type="submit"
            class="btn btn-dark"
          >
            <i class="fa fa-trash"></i> Iniciar
          </button>
        </form>
      </div>
      <br />

      <div id="pausar" style="display: none" class="buttons">
        <form class="btn">
          <button
            onclick="test()"
            class="form"
            type="submit"
            class="btn btn-dark"
          >
            <i class="fa fa-trash"></i> Pausar
          </button>
        </form>
      </div>
      <br />
    </div>
  </body>
</html>

index.js

function test() {
  var x = document.getElementById("iniciar");
  var y = document.getElementById("pausar");

  if (x.style.display === "none") {
    x.style.display = "block";
    y.style.display = "none";
  } else {
    x.style.display = "none";
    y.style.display = "block";
  }
}

It is worked with me!

Quyen Nguyen
  • 271
  • 2
  • 9
  • 1
    Please read the question carefully. What does this have to do with the OP's problem? – code Sep 09 '22 at 01:34
  • Well, her problem could be using name property of the wrong function. function is a reserved word, so cannot be used here @code – Quyen Nguyen Sep 09 '22 at 01:54
  • Actually, that's not the problem. I was trying to submit the forms and make the button display changes, so every change I make goes back to the original state. – Vanessa Sep 09 '22 at 02:09
  • @Vanessa you can add onsubmit="return false" for form tag. this is solve your problems. looks like the code above – Quyen Nguyen Sep 09 '22 at 02:20
  • @QuyenNguyen You are right. But I can only use the post or get method with one button, the goal was to access the post or get method by clicking both. – Vanessa Sep 09 '22 at 12:54
-1

One possible issue you are having is that the click event has isTrusted false. If you plan on doing a lot of similar stuff I would suggest you switch to using puppeteer as is done by basically all simulational QA. this google search might help

Another issue you could be having is that most Web Apps these days have a shadow DOM in a walled garden that you are not allowed to interact with. This DOM is usually the interior source of truth for the app, and on interaction it replaces the shallow surface you see in the dev tools.

I recently started automating a lot of simple tasks with puppeteer after tampermonkey started failing me similarly, here are some pointers to get You started if you`d like. It's kind of a commitment to learning, but it quickly becomes vastly superior to anything else.

after installing node & running in node.js in a file run using cmd or whatever (i use git bash)
//Edit

npm init -y
npm i -D child_process path puppeteer-core

child-process is to spawn the puppet browser
I'd add dotenv if you can code much. Edit\\

node filename.js

import puppeteer from "puppeteer-core";
import cp from "child_process";
import path from "path";

// or just hard code an OS path to chrome.exe here is mine
const user_dir = path.resolve("C:\\\\", "Users", "%REPLACE_USER%");
const ad_local = path.join(user_dir, "AppData", "Local");
const chrome = path.join(ad_local, "Chromium", "Application", "chrome_proxy.exe");

let http;

// required for puppeteer to talk to pre-opened browser
let wsChromeEndpointUrl;

// https://stackoverflow.com/questions/51200626/using-a-settimeout-in-a-async-function
const wait = (delay = 300) => new Promise((resolve) => setTimeout(resolve, delay));

const _l = (s) => {
    console.log(s);
};

// this opens browser with an open socket you can drive from nodejs
// don't use it for ANY secure login such as banking or email
// --user-data-dir is a dir for node/browser to peek/share
// opening some other browser after you can see wsChromeEndpointUrl listed there, careful yeah!
// http://127.0.0.1:9222/json/version
// edit: `start chrome.exe` is good for windows, you can use cp.execFile("chrome.exe...") fairly directly otherwise. You get hangs in windows on Ctrl-C without `start...`
const open_browser = async () => {
    _l(`${chrome} --remote-debugging-port=9222 --user-data-dir=remote-profile`);
    await wait(2500);
    try {
        cp.exec(
            `start ${chrome} --remote-debugging-port=9222 --user-data-dir=remote-profile ${landing}`,
        );
    } catch (err) {
        _l(`L:175, F:server_proc.js open_browser err: ${JSON.stringify(err)}`);
    }
    await wait(2500);
};

(async () => {
    try {
        // console.log("http?");
        http = await import("http");
    } catch (err) {
        _l("[075] puppers.js - http support is disabled!");
        return;
    }
    await connect_browser();
    if (!wsChromeEndpointUrl) {
        _l("[161] main.js - browser failed to initialize, terminating");
        return;
    }
    await now_you_can_drive(wsChromeEndpointUrl);
})();
// 127.0.0.1
// aka localhost
const try_connect_browser = () => {
    return new Promise((resolve, reject) => {
        const options = {
            hostname: "127.0.0.1",
            port: 9222,
            path: "/json/version",
            method: "GET",
        };
        const req_ = http.request(options, async (res_) => {
            await res_.on("data", async (d) => {
                if (d) {
                    wsChromeEndpointUrl = JSON.parse(d)["webSocketDebuggerUrl"];
                    resolve(true);
                }
            });
        });
        req_.on("error", async (err) => {
            // console.error(err);
            _l("[110] puppers.js - chrome proxy err = err: ");
            _l(err);
            reject();
        });
        req_.end();
    });
};

const connect_browser = async (retries_remaining = 1) => {
    await try_connect_browser()
        .then(async (res) => {})
        .catch(async (err) => {
            _l(`[149] puppers.jscatch err: ${err}`);
            await open_browser();
            await wait(4000);
            await connect_browser(retries_remaining - 1);
        });
};

async function now_you_can_drive(wsChromeEndpointUrl) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: wsChromeEndpointUrl,
        defaultViewport: null, // <= set this to have viewport emulation off
        devtools: true,
    });
    const new_page = await browser.newPage();
    await new_page.goto(URL_HERE, {
           waitUntil: "networkidle0",
    });
    await wait(4000);
    await new_page.click('#pausar');
    // id is supposed to be unique, ...lordy
    
}

Recommend starting with long timeouts and reduce moderately testing a run immediately after reducing. page.evaluate can be notoriously complex to deal with as a debug setup is a bit of a learning curve beyond these basics. eval blocks are super nasty cause you can't console.log easily it is possibly the worst place to learn HTML or JS, a technical challenge even for programmers. Also, I've no doubt professionals can notice you even with significant humanizer work on the interactions (jazz hands). Time flies, even knowing the code it's a lift without dev tools going which you can, but I've not set that up yet for puppeteer. Use a separate browser and treat the process like work, don't forget. https://github.com/puppeteer/puppeteer Version needs to approximately match if you aren't running the auto updating 'head' You can grab the already open tab using a generator function or some other async loop I think this may already be way ahead.

Edit++ I don't use it this on youtube or facebook, not sure what general policy is there and I imagine our corpo overlords might ban your IP for botting/scraping if not careful. This script is incredibly fresh (aka working right now) Sept 2022. I don't have this kind of code in my git cause I use it for web dev mostly (which is not what this is). Also lowerCamelCase is professional and underscores_not_so_much, but I don't use QWERTY anymore and _ is better on a hold to shift kb. FYI in case you are trying to learn conventions they are lowerCamelCase almost unilaterally now. Also I don't have the rep to respond to your new question below, but Jinja doesn't run in the browser so you can't use it to make async changes in anyway. I would suggest jQuery as the goto for some basic toggling callbacks.

Zaira
  • 42
  • 2