How do I enable pop-up menus from materialise in React? - css

I have a React app, I'm trying to add a NavBar there like this
<ul id="dropdown1" className="dropdown-content">
<li><NavLink to="/create">Create lessons</NavLink></li>*/}
<li><NavLink to="/lessons">Lessons</NavLink></li>
<li><NavLink to="/quizes">Quizes</NavLink></li>
<li><NavLink to="/quizcreator">Create QuizGame</NavLink></li>
<li></li>
<li></li>
</ul>
<nav>
<div className="nav-wrapper">
Logo
<ul className="right hide-on-med-and-down">
<li><NavLink to="/home">Home</NavLink></li>
<li><a className="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i
className="material-icons right">arrow_drop_down</i></a></li>
<li><a href="/" onClick={logoutHandler}>Logout</a></li>
</ul>
</div>
</nav>
I would like this thing to open and show the contents either when clicked or hovered over
The materialize css website describes the following code
$(".dropdown-trigger").dropdown();
But I can't figure out where to insert it? Application on the MERN stack

<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Dropdown Structure -->
<ul id="dropdown1" class="dropdown-content">
<li>one</li>
<li>two</li>
<li class="divider"></li>
<li>three</li>
</ul>
<nav>
<div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<!-- Dropdown Trigger -->
<li><a class="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>

According to the official doc you should be able to enable all your dropdowns like the following:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
Here is an example (please open in full-page):
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Dropdown Structure -->
<ul id="dropdown1" class="dropdown-content">
<li>one</li>
<li>two</li>
<li class="divider"></li>
<li>three</li>
</ul>
<nav>
<div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<!-- Dropdown Trigger -->
<li><a class="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>

add a onclick event in your second "li" item, pass the event object, call dropdown() function by fetching the classname from the event object.
<li>
<a className="dropdown-trigger" href="#!" onclick{(e) => e.target.className.dropdown();} data-target="dropdown1">
Dropdown<i className="material-icons right">arrow_drop_down</i>
</a>
</li>

Easy ! just add this code to the js file
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
You haven't init the dropdown that's why it's not working ! And don't use this framework maybe MDbootstrap will be perfect because they give you a React version and they have a pretty documentation without ads !

As You said, you are using React, and based on the link that you left on the question, $(".dropdown-trigger").dropdown(); is the jQuery way, you need to find out the React way
You could install materialize-css package, I guess you will find How to use materialize-css with React? helpful for this purpose
then import and use the package like this:
import React, { useRef, useEffect } from 'react';
import M from 'materialize-css';
function DropDown() {
const dropDownTriggerRef = useRef();
useEffect(() => {
M.Dropdown.init(dropDownTriggerRef.current);
}, [])
return (
// all of the other tags and other stuff
....
<li>
<a className="dropdown-trigger"
href="#!" data-target="dropdown1"
ref={dropDownTriggerRef}
>
Dropdown
<i className="material-icons right"> arrow_drop_down </i>
</a>
</li>
....
);
}

Related

Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>

There are many similar problems, but I can't solve this background error warning. Strictly speaking, I'm still a novice. I know to change li, but I don't know where to start. Please help me. This error warning:
next-dev.js?3515:20 Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>.
at li
at li
at ul
at div
at div
at Top (webpack-internal:///./components/header/Top.js:28:84)
at header
at Header (webpack-internal:///./components/header/index.js:18:11)
at div
at Home
at PersistGate (webpack-internal:///./node_modules/redux-persist/es/integration/react.js:39:5)
at Provider (webpack-internal:///./node_modules/react-redux/es/components/Provider.js:13:3)
at MyApp (webpack-internal:///./pages/_app.js:22:11)
at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:11)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:301:63)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:850:919)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:62:1)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:172:11)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:347:11)
I hope something can help me correct him. Like obsessive-compulsive disorder, I can't face the red color of the back. This is my original code:
import styles from "./styles.module.scss";
import { MdSecurity } from "react-icons/md";
import { BsSuitHeart } from "react-icons/bs";
import { RiAccountPinCircleLine, RiArrowDropDownFill } from "react-icons/ri";
import Link from "next/link";
import { useState } from "react";
import UserMenu from "./UserMenu";
export default function Top() {
const [ loggedIn, setLoggedIn ] = useState(true);
const [visible, setVisible] = useState(false);
return (
<div className={styles.top}>
<div className={styles.top_container}>
<div></div>
<ul className={styles.top_list}>
<li className={styles.li}>
<MdSecurity />
<span>Buyer Prodtection</span>
</li>
<li className={styles.li}>
<span>Customer Service</span>
</li>
<li className={styles.li}>
<span>Help</span>
</li>
<li className={styles.li}>
<BsSuitHeart />
<Link href={"/profile/whishlist"}>
<span>Whishlist</span>
</Link>
</li>
<li
className={styles.li}
onMouseOver={() => setVisible(true)}
onMouseLeave={() => setVisible(false)}
>
{loggedIn ? (
<li className={styles.li}>
<div className={styles.flex}>
<img
src={"/"}
width={22}
height={22}
alt=''
/>
<RiArrowDropDownFill />
</div>
</li>
) : (
<li className={styles.li}>
<div className={styles.flex}>
<RiAccountPinCircleLine />
<span>Account</span>
<RiArrowDropDownFill />
</div>
</li>
)}
{visible && <UserMenu loggedIn={loggedIn} />}
</li>
</ul>
</div>
</div>
);
}
You cannot nest li tags in html.
For example
<ul>
<li>
<li></li>
</li>
</ul>
If you would like a nested list, you can do this
<ul>
<li>
<ul>
<li></li>
</ul>
</li>
</ul>

Materialize - Like that triggers sidenav disappears

I am trying to get a sidemenu to work on Materialize when should be very simple:
First I add the sidenav content to the page:
<ul id="slide-out" class="sidenav">
<li><div class="user-view">
<div class="background">
<img src="images/office.jpg">
</div>
<img class="circle" src="images/yuna.jpg">
<span class="white-text name">John Doe</span>
<span class="white-text email">jdandturk#gmail.com</span>
</div></li>
<li><i class="material-icons">cloud</i>First Link With Icon</li>
<li>Second Link</li>
<li><div class="divider"></div></li>
<li><a class="subheader">Subheader</a></li>
<li><a class="waves-effect" href="#!">Third Link With Waves</a></li>
</ul>
Then I add the jquery code:
$( document ).ready(function() {
$('.sidenav').sidenav();
});
And finally the part where to problem is:
I have a nav which goes at the top of the page:
<nav>
<div class="nav-wrapper">
<img src="icon.png" alt="" />
<ul class="left hide-on-med-and-down" style="position: relative; left: 100px;">
<li>Trigger SideNav</li><!-- This is just not showing -->
</ul>
</div>
</nav>
For some reason this menu is not showing:
<li>Trigger SideNav</li>
unless I take this off it ... data-target="slide-out" class="sidenav-trigger"
How can I fix this?
In addition to what Moein said (the sidenav-trigger menu only appears when the page width is less than 993px), you can make it appear all the same adding the show-on-large class to your menu button.
Something like:
<nav>
<div class="nav-wrapper">
<i class="material-icons">menu</i>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Menu</li>
<li>Info</li>
</ul>
</div>
</nav>
as I know this is not a problem and the element that has sidenav-trigger class will be shown when the width of the browser is less than 993px. just resize your browser window width to reach less than 993px and see the result.
If it does not work:
I think the problem can be with the content of your link. replace the image with a text and try again.
For reputation reasons, I'm not allowed to comment. It'll work with the javascript code
document.addEventListener('DOMContentLoaded', function(){
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, {});
});
Instead of the code which is given in the official documentation you've to change this piece of code
M.Sidenav.init(elems, options);
with this
M.Sidenav.init(elems, {});
With the official javascript code you'll notice that there's an error in the console when you load the page.

Can't get bootstraps dropdowns to work

I've checked my javascript files and I think I have all the right ones. But I am not getting anything to dropdown.
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap-dropdown.js"></script>
...
<div class="span3"><center>
Buy A Contract
<ul class="dropdown-menu">
<li>Hello World</li>
<li>Why am I not seeing this?</li>
</ul>
</div>
</center>
</div>
...
Looks like one obvious issue: no jQuery reference. Also, since you included this:
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
you don't need to reference bootstrap-dropdown.js (the min file contains all the plugins).
EDIT:
To be clear, you need to have a script tag pointing to a copy of the jQuery library somewhere before the Bootstrap references, so your head should look similar to:
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
You might need to back the jQuery version down, since you're linking to an older version of Bootstrap. If you're getting errors from the Bootstrap source, change the jQuery version to 1.8.3.
Jquery is important to be declared before every other script on your page.
In header insert the below line before every script.:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
But you also have the wrong syntax to create a dropdown menu . It has to be like below:
<ul class="nav">
<li>Link</li>
<li>Link</li>
<li class="dropdown"> <!-- this is the item where your dropdown menu will popup-->
<a data-toggle="dropdown" class="dropdown-toggle" href="#">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu"><!-- your drop-down -menu-->
<li>nav1
</li>
<li>nav2
</li>
</ul><!-- dropdown menu ends-->
</li><!-- li with dropdown ends-->
</ul><!-- Main nav ends-->

CSS tabs not working with anchors on bootstrap?

Attempt 1
<div class="bs-docs-example">
<ul class="nav nav-tabs">
<li class="active">Homeaaa</li>
<li>Profilefff</li>
<li>Messagesbbb</li>
</ul>
</div>
JSfiddle
I have also tried setting a data-toggle attribute to "tab", but that only allowed me to click between tabs, it didn't separate the aaa/fff/bbb into different tabs.
This should be possible to be done without any JavaScript.
Attempt 2
The closest I've gotten to a working one is:
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active">
Stir
</li>
<li>
Drink
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="ter">fff</div>
<div class="tab-pane" id="gin">ggg</div>
</div>
</div>
JSfiddle
But this didn't change the URL of the viewer to /#ter or /#gin on click. Also it doesn't seem to work normally in the fiddle...
Your jsFiddle works as expected -- anchor links take you to #gin and #ter. On the other hand, I believe you need to use some JavaScript to actually change the active tab. Here's a try that uses a bit of jQuery:
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active">
Stir
</li>
<li>
Drink
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="ter">fff</div>
<div class="tab-pane" id="gin">ggg</div>
</div>
</div>
JavaScript:
$(document).ready(function() {
$(".nav-tabs li a").click(function() {
var li = $(this).parent("li");
var wch = this.getAttribute("href");
$(li).addClass("active"); //make current li active
$(li).siblings("li").removeClass("active"); //make others inactive
$(".tab-content div").removeClass("active"); //make all tabs inactive first
$(wch).addClass("active"); //activate our tab;
return false; //don't change URL
});
});
And a little demo: little link. Note that the use of jQuery isn't needed; you can easily convert to vanilla JavaScript if you want to avoid using it.
Hope that helped!

jsfiddle work error

I made my menu at jsfiddle and here's my work.
but I got different result on my page.
is jsfiddle working?
do I need to modify some code?
<div id="menu_main">
<ul>
<li class="mainop">Category
<ul>
<li><a href='../index.php?category=Blogging'>Blogging</a></li>
<li><a href='../index.php?category=General'>General</a></li>
<li><a href='../index.php?category=Arts and Entertainment'>Arts and Entertainment</a></li>
<li><a href='../index.php?category=Womens Interests'>Womens Interests</a></li>
<li><a href='../index.php?category=Writing and Speaking'>Writing and Speaking</a></li>
</ul>
</li>
</ul>
</div>
my script
<script language="JavaScript" type="text/javascript">
$(document).ready(function() {
$(".mainop").hover(function() {
var $this = $(this);
$this.find("ul").slideDown("fast");
$this.children('a:first-child').addClass('active');
}, function() {
var $this = $(this);
$this.find("ul").slideUp("fast");
$this.children('a:first-child').removeClass('active');
});
});
</script>
According to JSFiddle, the output HTML of your code looks like this:
<div id="menu_main">
<ul>
<li class="mainop">Main option
<ul style="display: block; "></ul>
</li>
<li class="mainop">Main option</li>
<li class="mainop">Main option</li>
</ul>
</div>
All the list elements are gone.
I can see that you're referencing the columnizer jQuery plugin, but you haven't included it in your JSFiddle page. That could be the reason you're not getting the same results. If you remove the call to columnize, the list elements reappear, but it doesn't look pretty.

Resources