react-materialize $(...).tabs is not a function - javascript

Can't call .tabs() function from materialize, everything looks imported and in the right order, materializecss then jQuery then materialize.js. jQuery functions work fine, materialize - don't
$(...).tabs is not a function
The problem should be somewhere in import but I can't get what's wrong.
index.html
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Import materialize.css -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet" >
<title>Title</title>
</head>
<body>
<div id="root"></div>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
</body>
Component where I'm calling from
import React,{Component} from 'react';
import {Tab,Tabs} from 'react-materialize'
export default class Tab1 extends Component{
next(){
let $ = require('jquery');
$('ul.tabs').tabs('select_tab','tab_01');
// alert();
}
render(){
return(
<div className="swipeTab" >
<a onClick={()=> this.next()} className="waves-effect btn onasTabTrigger hoverable">Button</a>
</div>
);
}
}
This Tab1 component is simply placed as a content of the tab in the parent
<Tabs className='tabs z-depth-1' tabOptions={{swipeable: true }} onChange={() => console.log(this)}>
<Tab title="tab1" active >
<Tab1 />
</Tab>
<Tab title="tab2" >
<Tab2/>
</Tab>
</Tabs>

Put tab initialisation in componentDidMount.
Remove initialisation from click event on next call.
//onClick={()=> this.next()} remove it
component :
let $ = require('jquery');
export default class Tab1 extends Component{
componentDidMount(){
//initialisation goes here.
$('ul.tabs').tabs('select_tab','tab_01');
}
render(){
return(
<div className="swipeTab" >
<a className="waves-effect btn onasTabTrigger hoverable">Button</a>
</div>
);
}
}

Related

Scripts not working in React, NextJS project unless I specifically refresh the page

I had to refactor a large codebase built on pure HTML, CSS, and javascript into a ReactJS and NextJS application. The codebase had a whole lot of links and scripts whereby some scripts applied for all pages while some applied for only specific pages.
In the set-up I did, I created a Meta.js file where I kept all links and scripts and also created a Layout.js file which held the Meta.js as well a common navbar and sidebar layout which was applied to all pages.
The issue I am facing presently now is that some scripts/functionality do not work unless the page is refreshed. For instance, I enter the application from the homepage which is the index.js file, and then navigate to the settings page, which is a settings.js file.
The settings.js page has some tab that uses some script in it but will not work unless I reload the page. What can be the issue with this and how can I fix this.
Here are some of the important files listed below:
Meta.js
import React from 'react'
import Head from 'next/head'
import Script from 'next/script'
const Meta = ({title, keywords, description}) => {
return (
<>
<Head>
<meta charSet="utf-8" />
<meta content="Webflow" name="generator" />
</Head>
<Script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></Script>
<Script src='/CustomScript.js'></Script>
<Script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' strategy='beforeInteractive' crossOrigin="anonymous"></Script>
<Script src='/webflow.js'></Script>
<Script src='https://fengyuanchen.github.io/datepicker/js/datepicker.js'></Script>
<Script src='https://cdn.jsdelivr.net/npm/flatpickr'></Script>
<Script src='https://cdn.quilljs.com/1.3.6/quill.js' strategy='beforeInteractive'></Script>
</>
)
}
export default Meta
Layout.js
import Nav from "./Nav";
import Meta from "./Meta";
const Layout = ({children}) => {
return (
<>
<Meta />
<Nav/>
<div className="body">
<main>
{children}
</main>
</div>
</>
);
}
export default Layout;
_app.js
// styles
import '../styles/normalize.css'
import '../styles/webflow.css'
import '../styles/listwise.webflow.css'
import '../styles/styles.css'
// website constant layout
import Layout from '../components/Layout'
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
Nav.js
import React from 'react'
import Image from 'next/image'
import Link from 'next/link'
const Nav = () => {
return (
<div className="app-nav-layout">
<Link href="#"><Image src="/listwise-logo-black-nospace.svg" width={130} height={130} alt="" className="left-navbar-logo" /></Link>
</div>
<nav role="navigation" className="left-navbar-menu w-nav-menu">
<Link href="/dashboard/listings/addListing">Create new listing</Link>
<Link href="/">Dashboard<br/></Link>
<Link href="/dashboard/listings/allListings"><a className="left-navbar-link w-nav-link"><span className="material-icons-round md-18 mr-8">list_alt</span> Listings<br/></a></Link>
<Link href="/dashboard/settings/settings">Account settings</Link>
<Link href="/dashboard/listings/myListwise">My Listwise</Link>
</nav>
</div>
)
}
export default Nav
settings.js
import React, {useState} from 'react'
import Head from "next/head"
import Script from "next/script"
const settings = () => {
return (
<>
<Head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" />
<link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css" />
<link rel="stylesheet" href="https://unpkg.com/filepond/dist/filepond.min.css" />
<Script src="https://unpkg.com/filepond-plugin-file-encode/dist/filepond-plugin-file-encode.min.js"></Script>
<Script src="https://unpkg.com/filepond/dist/filepond.min.js"></Script>
</Head>
<div className="app-main-layout-container">
<div className="tabs-menu w-tab-menu">
<a data-w-tab="Personal" className="tab-link w-inline-block w-tab-link w--current">
<div className="material-icons-round md-24 icon-acc-settings">person</div>
<div className="tab-text">Personal profile</div>
</a>
<a data-w-tab="Business" className="tab-link w-inline-block w-tab-link">
<div className="material-icons-round md-24 icon-acc-settings">store</div>
<div className="tab-text">Business profile</div>
</a>
<a data-w-tab="Social" className="tab-link w-inline-block w-tab-link">
<div className="material-icons-round md-24 icon-acc-settings">share</div>
<div className="tab-text">Social links</div>
</a>
</div>
<div className="tabs-content w-tab-content">
<div data-w-tab="Personal" className="w-tab-pane w--tab-active">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="name-4" className="label">Upload profile photo</label>
</form>
</div>
<div data-w-tab="Business" className="w-tab-pane">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="name-4" className="label">Business name</label>
<div className="hint marginb--20px">This is usually the name you work under</div><input type="text" className="input w-input" maxLength="256" name="Business-Name" data-name="Business Name" placeholder="Enter business name" id="business-name" required="" />
</form>
</div>
<div data-w-tab="Social" className="w-tab-pane">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="instagram-link" className="label">Instagram profile link</label><input type="text" className="input w-input" maxLength="256" name="Instagram-Link" data-name="Instagram Link" placeholder="www.instagram.com/myname" id="instagram-link" /></div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default settings
Also, I will like to ask how best to render those scripts that only work for specific pages, should I add the to the Meta.js file which gets loaded on the initial rendering of the application, or creates a separate file and add it to the page that needs it when the page is navigated to.
The Nextjs Script component can take a strategy prop. It has a default value of afterInteractive which means the script will first load the main javascript that's necessary for the page to become interactive before the script you've linked in the Script tag.
If you need any script to load early because some functionality of your page relies on it you'd want to set the strategy prop to beforeInteractive like so:
<Script src=" ... " strategy="beforeInteractive" />
More information on Next docs
I am also facing this issue but for the time being i just fixed this issue by importing all script code into useEffect here i am removing all events before my script code in useEffect
useEffect(() => {
$(document).ready(function () {
var allElems = $('body').find('*');
allElems.each(function () {
var elm = this, //javascript DOM object
$elm = $(this) //jquery object for element.
$elm.off();
// your script code here
});
});

custom modal does not appear react.js

I'm trying to call this Modal, but does not appear. I tried to put the Modal into a render() but it does not work too. I used inspect element tool and it shows the div from Modal but show it "grey".
This is the Modal
import React from 'react';
import './Modal.css';
const modal = props =>(
<div className="modal">
<header className="modal__header">
<h1>{props.title}</h1>
</header>
<section className="modal__content">
{props.children}
</section>
<section className="modal__actions">
{props.canCancel && (<button className="btn" onClick={props.onCancel}>Cancel</button>)}
{props.canConfirm &&(<button className="btn" onClick={props.onConfirm}>Confirm</button>)}
</section>
</div>
);
export default modal;
and I´m trying to call the Modal here
import React,{Component} from 'react';
import Modal from '../components/Modal/Modal.js';
import './Investments.css';
class InvestmentsPage extends Component{
render(){
return(
<React.Fragment>
<Modal>
<p>Modal content</p>
</Modal>
<div className="investment-control">
<p>Modal</p>
<button className="btn btnt1" >Crear </button>
</div>
</React.Fragment>);
}
}
export default InvestmentsPage;
Your approach is wrong. I am guessing here your modal is hidden under some other DOM element. You should use ReactDOM.createPortal() for modals, tooltips etc. :
In index.html under the existing div with id='root' create new
div with id='modal';
In your modal Component as listed above import ReactDOM from 'react-dom'
and return
ReactDOM.createPortal(your_JSX_here, document.querySelector('#modal'))

bulma menu toggle in gatsbyjs not working

GatsbyJS beginner here, trying to get the Bulma responsive menu toggle to apply the "is-active" class to the menu (gatsby v2 with gatsby starter netlify cms). all code here: https://github.com/pddew/gatsby-starter-netlify-cms
Currently the toggle button and script tags appear but the button doesn't respond.
There is a working version of this in the gatsby starter business- when I inspect and compare my site with this, I can't spot the error, only that there is no event listener on toggle button, when it seems there should be.
When I inspect the site, the toggle.js script is being called and put in before the closing body tag, and the viewed.
I have tried building and deploying with no luck, clearing caches and swapping the scripts for bulma's suggested code.
Here is the relevant code.
Any help with this greatly appreciated; I'm a bit stuck!
in Layout.js:
import React from 'react' import Helmet from 'react-helmet'
import Navbar from '../components/Navbar' import Footer from '../components/Footer' import './all.sass'
const TemplateWrapper = ({ children }) => ( <div>
<Helmet title="Immediate Start Jobs" />
<Navbar />
<div>{children}</div>
<Footer /> </div> )
export default TemplateWrapper
in Navbar:
<button className="button navbar-burger" data-target="navMenu">
<span />
<span />
<span />
</button>
</div>
<div className="navbar-menu" id="navMenu">
<div className="navbar-start">
<Link className="navbar-item" to="/about">
About
</Link>
<Link className="navbar-item" to="/products">
Products
</Link>
<Link className="navbar-item" to="/blog">
Blog
</Link>
</div>
in html.js
import React from "react"
import PropTypes from "prop-types"
export default class HTML extends React.Component {
render() {
return (
<html {...this.props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{this.props.headComponents}
</head>
<body {...this.props.bodyAttributes}>
{this.props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: this.props.body }}
/>
{this.props.postBodyComponents}
<script src={__PATH_PREFIX__ + '/js/toggle.js'} />
</body>
</html>
)
}
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
And my toggle.js, stored in static/js/
document.addEventListener('DOMContentLoaded', function () {
// Get all "navbar-burger" elements
var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0)
// Check if there are any navbar burgers
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach(function ($el) {
$el.addEventListener('click', function () {
// Get the target from the "data-target" attribute
var target = $el.dataset.target
var $target = document.getElementById(target)
// Toggle the className on both the "navbar-burger" and the "navbar-menu"
$el.classList.toggle('is-active')
$target.classList.toggle('is-active')
})
})
}
})
I'm new to Gatsby myself, but I had to find a way to get my navbar to function. My solution is pretty quick and dirty, but it works. If your building a website with a lot of components that change state, I would suggest using redux and a central store instead. My solution was just having a navbar that handled its own state.
import React, { Component } from 'react'
import Link from 'gatsby-link'
class Navbar extends Component {
state = {
//This sets the state of Bulma elements
navbarIsActive: "navbar-item has-dropdown"
}
//This opens the navbar dropdown
navbarOpenDropdown = () => {
this.setState({
navbarIsActive: "navbar-item has-dropdown is-active"
})
}
//This closes the navbar dropdown
navbarCloseDropdown = () => {
this.setState({
navbarIsActive: "navbar-item has-dropdown"
})
}
render() {
return(
<div>
<nav class="navbar is-transparent" role="navigation" aria-label="dropdown navigation">
<a class="navbar-item">
<h1>Title!</h1>
</a>
<div
class={this.state.navbarIsActive}
onMouseEnter={this.navbarOpenDropdown}
onMouseLeave={this.navbarCloseDropdown}
>
<a class="navbar-link">
Docs
</a>
<div class="navbar-dropdown is-boxed">
<Link to="/">Home</Link>
<Link to="/about">About Us</Link>
<Link to="/blog">Blog</Link>
<hr class="navbar-divider"/>
<div class="navbar-item">
Version 0.7.2
</div>
</div>
</div>
</nav>
<section class="hero">
<div class="hero-body">
<p class="title">
Documentation
</p>
<p class="subtitle">
Everything you need to <strong>create a website</strong> with Bulma
</p>
</div>
</section>
</div>
)
}
}
export default Navbar;
That's just my two pennies' worth: https://nhpcr.codesandbox.io/
src/Navbar.js
import React from 'react';
import PropTypes from 'prop-types';
const NavbarItem = props => (
<a className="navbar-item is-capitalized" href={`#${props.page}`}>
{props.page}
</a>
);
const NavbarBurger = props => (
<button
onClick={props.toggleMenu}
className={`button navbar-burger ${props.active ? 'is-active' : ''}`}
>
<span />
<span />
<span />
</button>
);
export default class Navbar extends React.Component {
state = {
activeMenu: false,
};
toggleMenu = () => {
this.setState({
activeMenu: !this.state.activeMenu,
});
};
render() {
let { pages = [], color } = this.props;
let navbarItems = pages.map(page => <NavbarItem page={page} key={page} />);
return (
<nav className={`navbar is-fixed-top is-${color}`}>
<div className="navbar-brand">
<NavbarItem page="logo" />
<NavbarBurger
active={this.state.activeMenu}
toggleMenu={this.toggleMenu}
/>
</div>
<div
className={`navbar-menu ${this.state.activeMenu ? 'is-active' : ''}`}
>
<div className="navbar-start">{navbarItems}</div>
</div>
</nav>
);
}
}
Navbar.propTypes = {
pages: PropTypes.array.isRequired,
color: PropTypes.string,
};
src/index.js
import React from 'react';
import { render } from 'react-dom';
import Navbar from './Navbar';
import 'bulma/css/bulma.css';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const pages = ['about', 'contact', 'sitemap'];
const App = () => (
<div style={styles}>
<Navbar pages={pages} />
</div>
);
render(<App />, document.getElementById('root'));

React: how can I import another class to use when using React in HTML

I added react to an HTML page. With this approach, how can I write a class above my App class and import it to use within Class?
class Header extends React.Component
above my App class but it I keep getting an error:
super expression must be null or a function
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
</head>
<body>
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="text/babel">
class App extends React.Component {
componentDidMount() {}
render() {
return (
<div className="">
</div>
);
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
</script>
</body>
</html>
The class would be just another React Component, so you can just render it as you would any:
class Header extends React.Component {
render() {
return (
<h1>My Custom Header</h1>
)
}
}
class App extends React.Component {
componentDidMount() {
}
render() {
return (
<div className="">
<Header/>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
That said, you might just want to use functional components in such (stateless) cases.

Render array data in class i react

I have to make a card.
For that I need to make 3 components.
First for Card Header
Second for Card Description and
Third for main Card that will give values to both components.
In my Card class I want to display the array data. I have no idea how to do that.
I believe I should use map() but I do not understand how.
My structure should be like Card header1 with Card description1 then Card header2 with Card description2.
<!Doctype html>
<html>
<head>
<title>React Cards</title>
<link rel="stylesheet" href="screen1.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
<script type="text/jsx">
class Header extends React.Component { render () { return (
<div className='t1'>
<h1>{this.props.text}</h1>
</div>
) } } class CardDesc extends React.Component { render () { return (
<div className='t2' id='this.props.id'>{this.props.text}</div>
) } } class Card extends React.Component { render () { return (
<div className='t3'>
<Header text="this.props.head" />
<CardDesc text="this.props.des" />
</div>
) } } var cardContent = [ {head:'Header one',des:'000'}, {head:'Header two',des:'001'},
{head:'Header three',des:'002'}, {head:'Header four',des:'004'}, {head:'Header
five',des:'005'}, {head:'Header six',des:'006'} ]; ReactDOM.render(
<Card />, document.getElementById('root'))
</script>
<div id="root"></div>
</body>
</html>
When you want to pass a variable as props, don't use quotes, instead use {}, so change:
<Header text="this.props.head"/>
<CardDesc text="this.props.des" />
To:
<Header text={this.props.head}/>
<CardDesc text={this.props.des} />
Now, you can simply render your cards like so:
ReactDOM.render(
<div>
{cardContent.map(cardItem => <Card head={cardItem.head} des={cardItem.des} />)}
</div>
, document.getElementById('root'))
As you can see, a root element (div in this case) is required for the render function.
Another method would be to create a CardList component, and render that, instead of having the map in ReactDOM.render.
I think multiple rendering to the root element is bad idea, you can try create new component like App or whatever, end map your card components into it.
Look at this

Categories

Resources