If statement & PopUp window in React

In summary: Left: '55%' }} /> Yes </label> } position="right center" > <div> <h3>Why</h3> <label>
  • #1
mathmari
Gold Member
MHB
5,049
7
Hey! :smile:

I have a checkbox with radio button and I want that a popup message is shown if we have selected the second option. I tried to do that with if statement but it doesn't work. How do we write the if statement in React? Isn't it 'condition ? true : false' ? Do we not check if the value or the id is the one of the correct option?
And also how is the popup message defined?

The part for the radio buttons that I used is :

JavaScript:
<input type="radio" id="No" value="No" name="answer" /> No
<input
     type="radio"
     id="Yes"
     value="Yes"
     name="answer"
     style={{
              marginLeft: '55%'
     }}
/>
Yes

I want that if we select the answer 'Yes' then a pop up message should appear.

As for the pop up I tried:

JavaScript:
<Popup trigger={<button> Trigger</button>} position="right center">
              <div>Popup content here !</div>
</Popup>

But this just makes visible or invisible respectively the part in <div>. How does a pop up window appear?

🤔
 
Last edited:
Technology news on Phys.org
  • #2
I wrote now the following :

JavaScript:
<input type="radio" id="No" value="No" name="answer" /> No
      <Popup
         trigger={
            <label>
              <input
                  type="radio"
                  id="Yes"
                  value="Yes"
                  name="answer"
                  style={{
                      marginLeft: '55%'
                  }}
               />
               Yes
            </label>
        }
        position="right center"
     >
        <div>
           <h3>Why</h3>
               <label>
                  <input type="radio" value="reason1" name="reason" />Reason1
                  <br></br>
                  <input type="radio" value="reason2" name="settings" /> Reason2
               </label>
       </div>
Now I get a popup of the form :

popup.png


Could we style it do get a popup of the form :

popUP2.png


?
 
  • #3
mathmari said:
Could we style it do get a popup of the form :
No, that's not a popup, it's a (modal) Dialog: https://mui.com/material-ui/react-dialog/

Different animal.
 
Last edited:
  • Like
Likes mathmari
  • #4
pbuk said:
No, that's not a popular, it's a (modal) Dialog: https://mui.com/material-ui/react-dialog/

Different animal.

I have already tried the version of the link you sent but I get an error message that it must be typescript instead of javascript. 🤔
 
  • #5
mathmari said:
JavaScript:
<input type="radio" id="No" value="No" name="answer" /> No
      <Popup
         trigger={
            <label>
              <input
                  type="radio"
                  id="Yes"
                  value="Yes"
                  name="answer"
                  style={{
                      marginLeft: '55%'
                  }}
               />
               Yes
            </label>
        }
        position="right center"
     >
        <div>
           <h3>Why</h3>
               <label>
                  <input type="radio" value="reason1" name="reason" />Reason1
                  <br></br>
                  <input type="radio" value="reason2" name="settings" /> Reason2
               </label>
       </div>

I used now the above code and I have add two buttons, one "Close" and one "OK", but I got stuck on how to make the "Close" Button to close that popup window. Could you help me with that? 🤔
 
  • #6
mathmari said:
I have already tried the version of the link you sent but I get an error message that it must be typescript instead of javascript. 🤔
What exactly is the message?

Have you noticed there are now 2 versions of the boilerplate scripts on the MUI documentation site - you switch between them with the buttons at the top left of the box: the image below shows Typescript select (by default). If you do not have a TS transpiler in your build chain you will need to select the JS version.

1665751667974.png
 
  • Like
Likes mathmari
  • #7
pbuk said:
What exactly is the message?

Have you noticed there are now 2 versions of the boilerplate scripts on the MUI documentation site - you switch between them with the buttons at the top left of the box: the image below shows Typescript select (by default). If you do not have a TS transpiler in your build chain you will need to select the JS version.

View attachment 315585

Ah ok! And then when we want to call it we define <FormDialog /> ? 🤔
 
  • #8
mathmari said:
I used now the above code and I have add two buttons, one "Close" and one "OK", but I got stuck on how to make the "Close" Button to close that popup window. Could you help me with that? 🤔
Popup is not a Material UI component (there are two with subtle differences: Popover or Popper). Note that popups/popovers don't generally have buttons, they are intended to close when you click elsewhere. If there is more interaction the normal design idiom is a dialog.

If you are using reactjs-popup there is documentation on closing buttons here https://react-popup.elazizi.com/react-modal/, however note that Material UI is designed to be a complete UI framework and may not play nicely with 3rd party components.
 
  • Like
Likes mathmari
  • #9
pbuk said:
If you are using reactjs-popup there is documentation on closing buttons here https://react-popup.elazizi.com/react-modal/, however note that Material UI is designed to be a complete UI framework and may not play nicely with 3rd party components.

It works with that! Thank you! :smile:
 
Last edited:
  • #10
I have also an other question : I want to make the height of a card equal to the size of the screen, but this is not the same for each resolution. Is there a way to make it equal to the screen for each resolution? 🤔
 
  • #11
mathmari said:
Is there a way to make it equal to the screen for each resolution? 🤔
Set the height to "100vh" (100% of the view height).
 
  • Like
Likes mathmari
  • #12
pbuk said:
Set the height to "100vh" (100% of the view height).
Ok!

Can we use this one also in the TreeView sx?

JavaScript:
<TreeView
       aria-label="file system navigator"
       sx={{ flexGrow: 1, height: 195, maxWidth: 350, overflowY: 'auto' }}
>

Because here we just have a number, not px or something like that.

🤔
 
  • #13
mathmari said:
Ok!

Can we use this one also in the TreeView sx?

JavaScript:
<TreeView
       aria-label="file system navigator"
       sx={{ flexGrow: 1, height: 195, maxWidth: 350, overflowY: 'auto' }}
>

Because here we just have a number, not px or something like that.
I've no idea - I don't use React MUI - but according to POLA (the principle of least astonishment, a fundamental rule of API design), I would guess that in the sx parameter strings are passed verbatim and numbers are appended with 'px'. I would try height: '100vh'.
 
  • Like
Likes mathmari
  • #14
pbuk said:
I've no idea - I don't use React MUI - but according to POLA (the principle of least astonishment, a fundamental rule of API design), I would guess that in the sx parameter strings are passed verbatim and numbers are appended with 'px'. I would try height: '100vh'.

Ok! I have also an other question. I have an input field for the Name the next to the input field a button, but I make the scrren smaller the button goes down. How can I make it that the input field and the button get smaller but stey on the same line?

So far my code for that is :

JavaScript:
                                           <label>
                                                <input
                                                    type="text"
                                                    name="name"
                                                    placeholder="Type your name"
                                                    style={{
                                                        width: '25vw',
                                                        height: '5vh',
                                                        marginTop: '15px',
                                                        float: 'left'
                                                    }}
                                                />
                                            </label>
                                            <button
                                                id="btn"
                                                style={{
                                                    width: '8vw',
                                                    height: '5vh',
                                                    borderWidth: '0',
                                                    fontWeight: 'bold',
                                                    float: 'right',
                                                    marginTop: '15px'
                                                }}
                                            >
                                                OK
                                            </button>

🤔
 
  • #15
mathmari said:
How can I make it that the input field and the button get smaller but stey on the same line?
<input> is a plain HTML element and setting styles like that won't work. You need to use the MUI TextField component https://mui.com/material-ui/react-text-field/
 
  • Like
Likes mathmari
  • #16
How can I connect the react with FastApi? For example we have this input field with the OK button, and we have the endpoint (POST Request) /name/

Now we have to save the input at the input field in the database with the endpoint /name/ or not?

So when we call the link .../name/ then at the input field we give a name and this one must be saved in the database? Is that correct? Is that the meaning to connect the endpoints with the frontend?

I have to write the code for the request inside the jsx code where I made the input field and so on , right? First I write :
JavaScript:
    const client = axios.create({

        baseURL: "https://giant-db-connection.onrender.com/server"

    });

and then I have to save in a variable the input of the input field, or not?🤔
 
Last edited:
  • #17
mathmari said:
How can I connect the react with FastApi? For example we have this input field with the OK button, and we have the endpoint (POST Request) /name/

Now we have to save the input at the input field in the database with the endpoint /name/ or not?

So when we call the link .../name/ then at the input field we give a name and this one must be saved in the database? Is that correct? Is that the meaning to connect the endpoints with the frontend?
That all depends on what the particular API you are connecting to requires.

mathmari said:
I have to write the code for the request inside the jsx code where I made the input field and so on , right?
Absolutely not! The whole point of frameworks like React is the separation of concerns: in other words don't mix your business logic in with your presentation layer. You should do this using an event handler like in https://reactjs.org/docs/handling-events.html. That example uses the onClick event on a button, you will probably want to use the onChange event on an input (or onSubmit on a form for handling a number of changes).
 
  • Like
Likes mathmari
  • #18
pbuk said:
Absolutely not! The whole point of frameworks like React is the separation of concerns: in other words don't mix your business logic in with your presentation layer. You should do this using an event handler like in https://reactjs.org/docs/handling-events.html. That example uses the onClick event on a button, you will probably want to use the onChange event on an input (or onSubmit on a form for handling a number of changes).

So at the beginning we define:

JavaScript:
    const client = axios.create({
        baseURL: "https://giant-db-connection.onrender.com/server"
    });

and then inside the code for the input field we need an onClick:

JavaScript:
                                                  <button
                                                        id="btn"
                                                        type="submit"
                                                        style={{
                                                            width: '98px',
                                                            height: '40px',
                                                            fontWeight: 'bold',
                                                            float: 'right'
                                                        }}
                                                        onClick={activateButton}
                                                    >
                                                        OK
                                                    </button>

and then we have to define activateButton ? 🤔 I have seen the following example with GET :

JavaScript:
const TreeList = () => {
    const client = axios.create({
        baseURL: "https://abc.com/name" 
      });
    
    const [dataTree, setdataTree] = useState([]);
    // GET with Axios
    useEffect(() => {
        const fetchdataTree = async () => {
        let response = await client.get('');
        setdataTree(response.data);
        };
        fetchdataTree();
    }, []);
     
    return (
    
        <div className="row ml-1">
            <div className="col">
            
                <div className="row mt-2 ">
                    <div className=" text-dark col">
                    {dataTree.length > 0 && <Tree data={dataTree[0].tree_structure[0].Nodes } />}
                    </div>
                </div>
            
            </div>
        </div>
   )
}

So do I maybe have to use also at POST the useEffect() as follows?

JavaScript:
useEffect(() => {
        const fetchdataTree = async () => {
        let response = await client.post('');
        setdataTree(response.data);
        };
        fetchdataTree();
    }, []);
 
  • #20
As for the POST request with Axios I did :

JavaScript:
const [server, setServer] = useState('');
    const handleSubmit = (e) => {
        e.preventDefault();
        axios
            .post(`https://giant-db-connection.onrender.com/server`, { server_url: server, polling_time: 0 })
            .then((res) => console.log(res))
            .catch((error) => console.error(error));
    };

which works! Which is corresponding GET request? Just .get instead of .post? Or how is the GET request defined?
 
  • #21
mathmari said:
Which is corresponding GET request? Just .get instead of .post? Or how is the GET request defined?
Well yes axios.get() will perform a GET request, but what the path and query parameters (if any) should be depends on the API. Also it would be better to use the client you have set up instead of writing the whole URL all the time something like
JavaScript:
    const client = axios.create({
        baseURL: "https://giant-db-connection.onrender.com",
        // If you don't set a timeout it will wait forever if something is wrong.
        timeout: 5000, // 5s.
    });
    const [server, setServer] = useState('');

    // ...

    // Async/await syntax is nicer so declare the arrow function as async.
    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            const res = await client.post('/server', { server_url: server, polling_time: 0 });
            console.log(res);
        } catch (error) {
            console.error(error));
        }
    };
 
  • Like
Likes mathmari
  • #22
pbuk said:
Well yes axios.get() will perform a GET request, but what the path and query parameters (if any) should be depends on the API. Also it would be better to use the client you have set up instead of writing the whole URL all the time something like
JavaScript:
    const client = axios.create({
        baseURL: "https://giant-db-connection.onrender.com",
        // If you don't set a timeout it will wait forever if something is wrong.
        timeout: 5000, // 5s.
    });
    const [server, setServer] = useState('');

    // ...

    // Async/await syntax is nicer so declare the arrow function as async.
    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            const res = await client.post('/server', { server_url: server, polling_time: 0 });
            console.log(res);
        } catch (error) {
            console.error(error));
        }
    };
Ah ok! To call this POST request we go click on a button and with onClick we call then the above function, right?
What happens with a GET request? Then we don't click on a button, we just want that something is shown up, right? Do we just call then the function?

Is the GET request as follows when we want that just the Attributes are shown, as you see in the belox picture?

JavaScript:
const [parsed_tree, setParsedTree] = useState('');
    useEffect(() => {
        ParsedTree();
    }, []);
    const ParsedTree = () => {
        axios
            .get(`https://giant-db-connection.onrender.com/opc_ua_tree`)
            .then((res) => ((attributes = res.data.tree_structure.Nodes.Attributes), setParsedTree(attributes)))
            .catch((error) => console.error(error));
    };

🤔

1666685493773.jpeg


Or in JSON format :

1666688001409.png
 
Last edited:
  • #23
I have changed this and I think the way I get the attributes is now correct :

JavaScript:
    const [parsed_tree, setParsedTree] = useState('');
    useEffect(() => {
        ParsedTree();
    }, []);
    const ParsedTree = () => {
        axios
            .get(`https://giant-db-connection.onrender.com/opc_ua_tree`)
            .then(
                (res) => (console.log((attributes = res.data[0]['tree_structure'][0]['Nodes'][0]['Attributes'])), setParsedTree(attributes))
            )
            .catch((error) => console.error(error));
    };

The point where I got stuck right now is how to display the attributes. Do we do that with .map ? 🤔
 
  • #24
It’s not a good idea to fetch data directly in components - it’s that separation of concerns thing again. I would look at Redux, it’s designed to work well with React and it’s got a pretty good tutorial.
 
  • Like
Likes mathmari
  • #25
pbuk said:
It’s not a good idea to fetch data directly in components - it’s that separation of concerns thing again. I would look at Redux, it’s designed to work well with React and it’s got a pretty good tutorial.

So is the way I do the get request completely wrong? Or just how I want to display it? 🤔
 
  • #26
When the above code is correct do we use .map to display the data?

JavaScript:
{setParsedTree .map((x) => {
     <TreeItem nodeId="{x}" label={x} />;
})}
 
  • #27
No, it's probably fine (I haven't checked the detail but if it works then it works!).

But the problem comes when you want to display somewhere else e.g. the StartTime for the node with id "i=2257". If you keep the data inside a component's event handler you will have to fetch this from the server again, however if you store the query result as part of the state of a global store you can use it wherever you want - and if that state is implemented in a reactive store then everything stays updated automatically. Redux is one such store, and is the one most often used with React.
 
  • #28
mathmari said:
When the above code is correct do we use .map to display the data?

JavaScript:
{setParsedTree .map((x) => {
     <TreeItem nodeId="{x}" label={x} />;
})}
That depends on the structure of your data and how the TreeItem component you are using works. I think you need to work that out for yourself, I can't design your whole app for you. (Well I can, but it wouldn't be cheap).

But you do have to write code that parses though: think about what you are trying to get the compiler to do with {setParsedTree .map((x) => {.

Or FOLLOW A TUTORIAL.
 
  • #29
In React can we use a while loop?

I want to return a Tree so do I not have to check if there are other non-empty children to be printed? How is this defined in React? 🤔
 
  • #30
mathmari said:
In React can we use a while loop?
React is just JavaScript (or TypeScript) so yes, you can use a while loop, although you might find that you use a forEach iterator more often. We usually add another extension to JavaScript, JSX, which means we can do something like this inside our render() method:
JavaScript:
  return (
    <div class="node">
      <h3>{node.title}</h3>
      // Check if there are any child nodes.
      if (node.children.length) {
        <ul>
          // Recursively print child nodes.
          node.children.forEach((childNode) => {
            <li><DisplayNode node={childNode} depth={depth + 1}/></li>
          });
        </ul>
      }
    </div>
  );

mathmari said:
I want to return a Tree so do I not have to check if there are other non-empty children to be printed? How is this defined in React? 🤔
See commented code above.
 
  • Like
Likes mathmari
  • #31
I had tried the following :

JavaScript:
   const [dataObj, setDataObj] = useState([]); 
 
   useEffect(() => {
        fetch('https://giant-db-connection.onrender.com/opc_ua_tree/')
            .then((res) => res.json())
            .then((data) => {
                setDataObj(data[0]['tree_structure'][0].Nodes[0]);
                console.log(dataObj.DisplayName);
                while (dataObj.Nodes) {
                    for (let i = 0; i < dataObj.Nodes.length; i++) {
                        console.log(dataObj.Nodes[i].DisplayName);
                    }
                    setDataObj(dataObj.Nodes);
                }
            });
    }, []);
I want to display all the DisplayNames. First I did it with many for loops and it worked, now I am trying to write it with less code by setting dataObj.Nodes into the current dataObj. Is this correct so far?

Can the result be also in a TreeView (TreeItem) ? 🤔
 
  • #32
mathmari said:
I want to display all the DisplayNames. First I did it with many for loops and it worked, now I am trying to write it with less code by setting dataObj.Nodes into the current dataObj. Is this correct so far?
I wouldn't do it that way. Either the date in the tree is static, in which case there is no point in using a reactive object for it, or it is dynamic in which case you don't want to be managing it inside a component - it should be in a Redux store.

mathmari said:
Can the result be also in a TreeView (TreeItem) ?
Of course, see the example at https://mui.com/material-ui/react-tree-view/#rich-object. You may want to pre-parse the data into a much more normalized format.
 
  • #33
pbuk said:
I wouldn't do it that way. Either the date in the tree is static, in which case there is no point in using a reactive object for it, or it is dynamic in which case you don't want to be managing it inside a component - it should be in a Redux store.

Could you explain that further to me? Do we have to store the data instead of dataObj in a Redux store? 🤔
 
  • #34
So we save teh whole tree in a Redux store and then we we get the component that we want to print with useSelector ? 🤔
 
  • #35
Well I'd be inclined to flatten the tree in the response into an object with the id as the key:
JavaScript:
{
  'id-1234': {
    title: '...',
    children: [
      'id-2345',
      'id-9876',
    ],
  },
  'id-2345': {
    // ...
  },
  // ...
}
which will make it much easier to use, but otherwise, yes.
 
  • Like
Likes mathmari

Similar threads

Replies
10
Views
1K
Replies
16
Views
4K
Replies
4
Views
3K
Replies
4
Views
6K
Back
Top