Hamburger menu from HTML to ReactJS - reactjs

I'm trying to "converting" my code from HTML to ReactJS. What I tried and I couldn't make it worked is this line of code:
<div className = "title-bar" data-responsive-toggle = "center_menu">
<button className = "menu-icon" type = "button" data-toggle></button>
<div className = "title-bar-title"></div>
</div>
When I'm pressing that hamburger icon, that list "Home, Extensii etc" should appear. In HTML I made it worked fine. ReactJS it's not taking my data-responsive-toggle center_menu id. How should look the code, what is the correct syntax?
P.S.: I'm new in React, I'm trying to learn it.

well I don't know about whether you want it to look normal all the way and just have that burger on smaller screens or it's a burger menu all along but generally speaking for what you have asked, you need conditional classes to actually toggle between display:block; and display:none; and you need to handle that with the click event, so basically:
<div className ="title-bar">
<button className = "menu-icon" type = "button" onClick={this.toggleMenu}></button>
<div className = "title-bar-title"></div>
</div>
<div className={`example-menu ${this.isclicked}?" collapsed-menu": " closed-menu" `}>
<ul class = "menu dropdown" data-dropdown-menu>
<li>Home
....
<li>Contact</li>
</ul>
</div>
and that's what this.toggleMenu does:
toggleMenu() {
this.setState(state => ({
isclicked: !state.isclicked
}));
}
needless to talk about those two classes collapsed-menu and closed-menu, they would be sth like these:
.collapsed-menu{
....
display:block;
}
.closed-menu{
...
display:none;
}

There are several tutorials available on how to do it, e.g. here: https://css-tricks.com/hamburger-menu-with-a-side-of-react-hooks-and-styled-components/
Also you could use npm libraries to achieve the expected results.

what about the css (media query), did you specify the min-width value for the display??

Related

how to get reference to the element hidden in lwc?

I am learning lwc and I came across this problem. I have the following code.
html:
<template if:true={showLayout}>
<template if:true={showAllTabs}>
<div class="tab-container">
<div class="left-arrow">
'Left icon code'
</div>
<ul class="slds-tabs_default_nav tab-list">
'li elements to disply the tabs'
</ul>
<div class="right-arrow">
'Left icon code'
</div>
</div>
</template>
</template>
I am trying to get the reference of the ul element and right-arrow div in javascript to decide whether right navigation arrow should be shown or not based on scroll available on ul element. But, I am unable to get the reference of these 2 elements. I know that they are hidden thats why I am not able to find the reference. But, how to overcome this issue.
I tried to get the reference in renderedCallback() and in the function where showAlltabs becomes true, nothing worked.
JS:
renderedCallback(){
let tabList = this.template.querySelector('.tab-list');
let rightArrow = this.template.querySelector('.right-arrow');
}
handleLayoutOpen(){
this. showAllTabs = true;
let tabList = this.template.querySelector('.tab-list');
let rightArrow = this.template.querySelector('.right-arrow');
}
In both function I get undefined for both the elements.
Went through this developer guide https://lwc.dev/guide/html_templates#render-html-conditionally , nothing is mentioned about template reference here.
PS: I am very new to LWC, please be kind in your answer.
I was able to find a alternate solution to this problem. I used slds-hideand slds-show classes, instead of if:true.
<div class='slds-hide'>
<div class='slds-hide'>
<div class="tab-container">
<div class="left-arrow">
'Left icon code'
</div>
<ul class="slds-tabs_default_nav tab-list">
'li elements to disply the tabs'
</ul>
<div class="right-arrow">
'Left icon code'
</div>
</div>
</div>
</div>
In JS I used Element.classList.add() and Element.classList.remove() methods to show and hide the divs whenever I need.
NOw I am able to get the reference of the hidden elements as they are not truly absent in the dom.

How to toggle text without jquery in react?

I'm trying to make a menu in react, that turns into a dropdown menu on smaller devices. I want to avoid using jQuery, since as far as I know you should avoid using it in React.
I want the dropdown menu to, well, drop down only if you click a certain thing on the navbar, to reduce the place it would take on the website if it would be always opened on smaller devices. In my case now, the stuff I click is "dropdown. My dropdown menu works, but I want to make my "V" into a "O" when the menu expands, and back to "V" when I close the menu.
I tried to do it with If, but I couldn't figure it out.
JSX:
<div id="container">
<h1 id="logo">Logo</h1>
<h1 id="navitem1">Menu option1</h1>
<h1 id="navitem2">Menu option2</h1>
<h1 id="navitem3">Menu option3</h1>
<h1 id="dropdown" onClick={DropDown}>V</h1>
</div>
const DropDown = () => {
if (document.getElementById('dropdown').innerText = 'V'){
document.getElementById('dropdown').innerText = 'O'
}
}
The If method I'm using here changes the "dropdown" element to O, but I don't know how to change it back to V.
in react you don't manipulate dom directly.
you can handle it with useState hook. first define the state in the component.
const [dropDownText,setDropDownText] = useState("V")
so your DropDown function should be :
const DropDown = () => {
if (dropDownText=== 'V'){
setDropDownText("O")
}else{
setDropDownText("V")
}
}
and the the element should be
<div id="container">
<h1 id="logo">Logo</h1>
<h1 id="navitem1">Menu option1</h1>
<h1 id="navitem2">Menu option2</h1>
<h1 id="navitem3">Menu option3</h1>
<h1 id="dropdown" onClick={DropDown}>{dropDownText}</h1>
</div>

React: no <span> around text nodes

According to React 15.0 release notes, React is no longer supposed to emit <span> tags around text nodes. I tried that using jsbin and script
const Span = () => (<span>a</span>)
const text = 'text'
const Text = () => (<span>{text}</span>)
const Div = (<div>
<Span/><Span/><Span/><Text/>
</div>)
ReactDOM.render(Div, document.querySelector('#target'))
is rendered as
<div data-reactroot="">
<span>a</span>
<span>a</span>
<span>a</span>
<span>text</span>
</div>
So it doesn't work. I'd expect string a to be rendered without surrounding <span> tags. How is this feature supposed to work? Is it necessary to enable it in some way?
The feature is used when writing something like this:
<div>{'a'}{'b'}</div>
"a" and "b" was surrounded by tags and the dom was kinda full with this tags when using this multiple times in different components.
With 0.14.8 this was rendered as:
<div data-reactid=".0">
<span data-reactid=".0.0">a</span>
<span data-reactid=".0.1">b</span>
</div>
With 15.0 this is rendered as:
<div data-reactroot>
<!-- react-text: 2 -->a<!-- /react-text -->
<!-- react-text: 3 -->b<!-- /react-text -->
</div>
This is explained in https://github.com/facebook/react/pull/5753 and can be tested with something like https://codesandbox.io/s/N1znXxXL.

Hide a div after user selects one option

i did not found the answer i was looking for, so that why i'm creating this question. I have a div that shows another one on click but i need to hide it (the div that appears on click) after the user selects one of the options, how can i do that?
When user's click on "#showmenu" the div ".mob" appears, after clicking in one of the ".mob" li's the ".mob" div dissapears.
P.S: Sorry for my bad english.
HTML:
<div id="showmenu"><img src="images/mobile.png" /></div>
<div class="mob" style="display: none;">
<ul>
<a data-scroll href="#home"><li>INÍCIO</li></a>
<a data-scroll href="#servicos"><li>EU FAÇO</li></a>
</ul>
</div>
Code:
$(document).ready(function() {
$('#showmenu').click(function() {
$('.mob').slideToggle("fast");
});
});
I dont have any idea of the bootstrap or jquery plugins you are using but based on what is given, i'd say this should work.
$(document).ready(function() {
$('#showmenu').click(function() {
$('.mob').slideToggle("fast");
$('.mob a').click(function () {
$('.mob').slideToggle("fast");
});
});
});
Point to note there is a performance issue here , i.e code could be optimized better to search for classes or elements within a specific div than the whole document
Should those really be <a> if you don't intend to go anywhere? Can they just be <li>?
After that I think you want to give id's to the <li> that you have and then create a function much like the one you did for $('showmenu').click... that would hide the .mob.
Or if the <li> all get treated the same, maybe give them all the same class and just have one function for the class.

How to make a Bootstrap dropdown with React

I am a noobie at React and I am trying to make a Bootstrap dropdown. The html that I am attaching to is here:
<ul class="dropdown-menu" id="dropdown">
</ul>
And here is what I want to put in my render method to insert inside of my html:
render: function() {
return (
<li>Books</li>
<li>Podcasts</li>
<li>Tech I Like</li>
<li>About me</li>
<li>Add a Blog</li>
);
}
But of course I can only return one element. What is the right way of doing this in React? How could I add multiple <li>'s into a dropdown like this? I tried wrapping the whole thing in a <div>, but that messes up my css.
react bootstrap makes working with react & bootstrap a bit easier:
render: function(){
return (
<DropdownButton title="Dropdown">
<MenuItem href="#books">Books</MenuItem>
<MenuItem href="#podcasts">Podcasts</MenuItem>
<MenuItem href="#">Tech I Like</MenuItem>
<MenuItem href="#">About me</MenuItem>
<MenuItem href="#addBlog">Add a Blog</MenuItem>
</DropdownButton>
);
}
This looks about the same, but has event-handlers & adds all the right classes. As #sophie-alpert said, though, render must return a single DOM parent element.
Unfortunately this is one situation where React's ability to return only a single node from render is annoying. Your best bet is probably to return the <ul> itself from render:
render: function() {
return (
<ul className="dropdown-menu" id="dropdown">
<li>Books</li>
<li>Podcasts</li>
<li>Tech I Like</li>
<li>About me</li>
<li>Add a Blog</li>
</ul>
);
}
then render that entire component into another container like a <div>. In a future version of React we're hoping to remove this restriction so that something like your original code will work.
You can use react-select react component.It is very simple and easy to use.
var Select = require('react-select');
var options = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' }
];
function logChange(val) {
console.log("Selected: " + val);
}
<Select
name="form-field-name"
value="one"
options={options}
onChange={logChange}
/>
If you don't want to employ rebuilt dependencies like react bootstrap to work with both react and bootstrap, simply do the important js tricks which they do. In your case, basically a dropdown click event toggles the popper wrapper with .show css class. So you can define an onClick method and toggle the class inside it. For example in the following code I get the nextSibling and then toggle the class name for it with .show and finally inner div will be shown:
<div className="dropdown">
<a className="btn text-light" href="#" onClick={(e) => this.handleOption(e)}>open dropdown</a>
<div className="dropdown-menu dropdown-menu-left dropdown-menu-arrow">
<a className="dropdown-item" href="#">edit</a>
<a className="dropdown-item" href="#">delete</a>
</div>
</div>
Note that this tricks help you in case of few bootstrap functionalities in your project, otherwise employ rebuilt dependencies to have a clean and standard code.

Resources