React - will not re render on state change - reactjs

I'm all new to react.
Why does my page not re render on mouse over and mouse out when my state changes? If I look at console.log, I can see the state changes. But I can't get this to work. Here is my code:
export default class Nav extends React.PureComponent {
constructor(props) {
super(props);
this.navLevelOneId = '';
this.state = {
showSubMenu: []
};
}
// Mouse over function
handleHover = (id,event) => {
let showSubMenu=this.state.showSubMenu;
showSubMenu[id]=!showSubMenu[id]
this.setState({showSubMenu: showSubMenu}, () => {
console.log(this.state.showSubMenu);
});
}
render() {
return (
<div ref="megaMenu" className="navbar navbar-default navbar-static-top">
<div className="container">
<div className="navbar-header">
<button type="button" className="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
</div>
<div className="navbar-collapse collapse">
<ul className="nav navbar-nav">
<li onMouseOver={this.handleHover.bind(this,0)} onMouseOut={this.handleHover.bind(this,0)}>
<a>Home</a>
</li>
<li className="dropdown menu-large" onMouseOver={this.handleHover.bind(this,1)} onMouseOut={this.handleHover.bind(this,1)}>
<a className="dropdown-toggle" data-toggle="dropdown">Product Listing</a>
<ul className={"dropdown-menu megamenu row " + this.state.showSubMenu[1]}>
<li>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
</li>
</ul>
</li>
<li className="dropdown menu-large" onMouseOver={this.handleHover.bind(this,2)} onMouseOut={this.handleHover.bind(this,2)}>
<a className="dropdown-toggle" data-toggle="dropdown">Categories</a>
<ul className={"dropdown-menu megamenu row " + this.state.showSubMenu[2]}>
<li>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
<div className="col-sm-6 col-md-3">
<a href="" className="thumbnail">
<img src="http://placehold.it/150x120" alt="test" />
</a>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
);
}
}

Check out the difference between using Component and PureComponent.
Briefly, PureComponent performs a shallow comparison on state change. That means that it compares only references for state objects and arrays (in your case this.state.showSubMenu is an array and it's reference doesn't change so React won't force a rerender there)

Related

AngularJS ng-include

I am facing problem below upon using the ng-inculde in angularJS. The bootstrap burger icon is not working. But if i'm not using the ng-include it works perfectly fine. Did I do something wrong?.
Is there any set-up first that I need to do before using the ng-include?.
Main html
...
<body>
<ng-include src="'../Content/Shared/Header.html'"></ng-include>
<ng-view></ng-view>
</body>
....
Include html
<header>
<div class="container">
<div class="row element-holder">
<div class="col-md-2 col-sm-4 col-12">
<a href="../main/index.html" class="text-logo-holder">
<span class="text">My Project</span>
</a>
</div>
<div class="col-md-4 col-sm-6 col-12">
<form ng-submit="searchProducts()" class="search-holder">
<input type="text" class="form-control" placeholder="Search Collection...." list="_items" ng-model="searchText" ng-keyup="searchItemNames()" autocomplete="off" />
<datalist id="_items">
<option ng-repeat="result in results" value="{{result}}">{{result}}</option>
</datalist>
<button type="submit" class="btn btn-primary"><i class="fas fa-search"></i></button>
</form>
</div>
<div class="col-md-6 col-sm-2 col-12">
<nav class="navbar navbar-expand-lg float-right">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<img src="../Content/dist/images/icon-header-menu.png" />
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Discover</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Help</a>
</li>
<li class="nav-item btn-nav-item">
<a class="nav-link" href="" ng-click="logout()" ng-show="isSignedIn">Logout</a>
<a class="nav-link" href="" ng-click="signin()" ng-show="!isSignedIn">Sign In</a>
</li>
<li class="nav-item">
<a id="menu-link" class="nav-link" href="#">
<img src="../Content/dist/images/icon-header-menu.png" />
</a>
</li>
</ul>
</div>
</nav>
<div class="mobile-nav float-right">
<a id="menu-link-mobile" class="nav-link" href="#">
<img src="../Content/dist/images/icon-header-menu.png" />
</a>
</div>
</div>
</div>
</div>
<div id="sidebar-menu" class="side-menu-content">
<ul class="menu-holder">
<li>
<a href="#" class="menu-item row">
<div class="col-3 icon-holder">
<img src="../Content/dist/images/icon-inbox.png" />
</div>
<div class="col-9">
Inbox
</div>
</a>
</li>
<li>
<a href="#" class="menu-item row">
<div class="col-3 icon-holder">
<img src="../Content/dist/images/icon-purchase.png" />
</div>
<div class="col-9">
Purchases
</div>
</a>
</li>
</ul>
<div class="button-holder row">
<div class="col-6 pl-default pr-default" ng-show="!isSignedIn">
<input type="submit" class="btn btn-primary" value="Login/Sign Up" ng-click="signin()" />
</div>
<div class="col-6 pl-default pr-default" ng-show="isSignedIn">
<input type="submit" class="btn btn-secondary" value="Logout" ng-click="logout()" />
</div>
<div class="col-6 pl-default pr-default">
<input type="submit" class="btn btn-primary" value="Change Password" />
</div>
</div>
</div>
ng-include will:
Fetches, compiles and includes an external HTML fragment.
So that fragment added after page load and your events bind with js will not work on these dynamically added elements. To solve it, you can bind these events with onload arguments which is expression to evaluate when a new partial is loaded. Or you can try attach event to dynamic elements in javascript
Please, remove the single quote.
<div ng-include="../Content/Shared/Header.html"></div>
It seems to be a tag closing issue.
You need to close the <header> tag at the end of Header.html
use this :
<div ng-include src="'../Content/Shared/Header.html'"></div>

Responsive Navbar-Toggle button not working

I am trying to do responsive navbar by using bootstrap in reactjs.I have update the show in state so as i do like show or hide the element but the toggle button is not trigger.If i use the script link in bootstrap its working but i don't want to use the scripting links and want to update manual.so help me out.
Here is my code:
import React, { Component } from "react";
export default class NavBar extends Component {
constructor(props) {
super(props);
this.state = {
show: true,
};
}
showToggle = () => {
this.setState({
show: false,
});
};
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-lg-12 col-md-12 col-sm-12">
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="navbar-brand">
<img
alt="logo"
src="./images/or.png"
width="100px"
height="30"
className="d-inline-block align-top img-fluid"
/>
{/* <span className="nav-brand">Ortho Life Hospital</span> */}
</div>
<button
className="navbar-toggler"
type="button"
// data-toggle="collapse"
// data-target="#navbarSupportedContent"
// aria-controls="navbarSupportedContent"
// aria-expanded="false"
// aria-label="Toggle navigation"
onClick={this.showToggle}
>
<span className="navbar-toggler-icon"></span>
</button>
{this.state.show ? (
<div
className="collapse navbar-collapse"
id="navbarSupportedContent"
>
<ul className="navbar-nav ml-auto">
<li className="nav-item ml-5">
<a className="nav-link" href="/">
Home
</a>
</li>
<li className="nav-item ml-5">
<div className="dropdown">
<a
className="nav-link"
href="/about"
id="dropdownMenuButton"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
About Us
</a>
<div
className="dropdown-menu"
aria-labelledby="dropdownMenuButton"
>
<a className="dropdown-item" href="/about/#history">
History
</a>
<a className="dropdown-item" href="/about/#vision">
Vision and Mission
</a>
<a className="dropdown-item" href="/about/#whyortho">
Why Ortho?
</a>
</div>
</div>
</li>
<li className="nav-item ml-5">
<div className="dropdown">
<a
className="nav-link"
href="/department"
id="dropDownDepartment"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
Department
</a>
<div
className="dropdown-menu"
aria-labelledby="dropDownDepartment"
>
<a
className="dropdown-item"
href="/department/#medical"
>
Medical
</a>
<a
className="dropdown-item"
href="/department/#allied"
>
Allied
</a>
</div>
</div>
</li>
<li className="nav-item ml-5">
<a className="nav-link" href="/media">
Media
</a>
</li>
<li className="nav-item ml-5">
<a className="nav-link" href="/contactus">
Contact Us
</a>
</li>
</ul>
</div>
) : null}
</nav>
</div>
</div>
</div>
);
}
}

Bootstrap Carousal in React Component : not working

I am using 'create-react-app' to develop e web application. I am using Context API to get the data to this component, named Carousal.js
From the bootstrap for React, but my images are not showing up in the carousal. I tried testing if the image is rendering by putting
I am not getting what am I doing wrong? ** img and img2 are from the context API
My code is below:
export default class Details extends Component {
render() {
return (
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
</ol>
<div className="carousel-inner">
<div className="carousel-item">
<img className="d-block w-100" src={img} alt="Second slide"/>
</div>
<div className="carousel-item">
<img className="d-block w-100" src={img2} alt="Third slide"/>
</div>
</div>
<a className="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span className="carousel-control-prev-icon" aria-hidden="true"></span>
<span className="sr-only">Previous</span>
</a>
<a className="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span className="carousel-control-next-icon" aria-hidden="true"></span>
<span className="sr-only">Next</span>
</a>
</div>
)
}}

The controller with the name 'viewctrl' is not registered

<div class="wrapper" id="body" ng-app="masterview" ng-controller="masterctrl" data-ng-init="getmenus()">
<header id="header">
<div class="header-width row">
<div class="col-xl-9">
<div class="logo float-xs-left">
<a href="#">
<img src="~/img/logo_accord.png" alt="Ace Report" />
</a>
</div>
</div>
<div class="col-xl-3 header-right">
<div class="header-inner-right">
<div class="float-default chat">
<div class="right-icon">
<a href="#">
<i class="fa fa-envelope-o"></i>
</a>
</div>
</div>
<div class="float-default chat">
<div class="right-icon">
<a href="#">
<i class="fa fa-comments-o"></i>
</a>
</div>
</div>
<div class="user-dropdown">
<div class="btn-group">
<a href="index.html#" class="user-header dropdown-toggle" data-toggle="dropdown"
data-animation="slideOutUp" aria-haspopup="true"
aria-expanded="false">
<img src="~/assets/images/user.jpg" alt="Profile image" />
</a>
<div class="dropdown-menu user drop-profile dropdown-card dropdown-card-profile animated flipInY">
#*
<header class="card-header d-flex">
<a href="javascript:void(0);" class="text-center">
<i class="fa fa-user"></i>
</a>
<a href="javascript:void(0);" class="text-center">
<i class="fa fa-cog"></i>
</a>
<a href="javascript:void(0);" class="text-center">
<i class="fa fa-power-off"></i>
</a>
</header>*#
<ul class="list-unstyled card-body">
#*
<li>
<a href="index.html#">
<span>
<span class="align-middle">Manage Accounts</span>
</span>
</a>
</li>*#
<li>
<a href="index.html#">
<span>
<span class="align-middle">Change Password</span>
</span>
</a>
</li>
#*
<li>
<a href="index.html#">
<span>
<span class="align-middle">Check Inbox</span>
</span>
</a>
</li>*#
<li>
<a href="#Url.Action("Logout", "Admin")">
<span>
<span class="align-middle">Sign Out</span>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!--top menu bar-->
<div id="header-icon" class="" >
<div class="header-width">
<div class="col-xl-12">
<div class="menucontainer">
<div class="overlapblackbg"></div>
<a id="navtoggle" class="animated-arrow">
<span></span>
</a>
<nav id="nav" class="topmenu" role="navigation">
<div class="sidebar-search">
<div class="logo float-xs-left">
</div>
<a href="javascript:void(0)">
<i class="search-close icon_search"></i>
</a>
</div>
<!--left menu-->
<ul id="dvMenuInner" class="nav navbar-nav">
<li ng-repeat="parent in menu" class="dropdown">
<a href="/{{parent.url}}/{{parent.actionname}}" ng-show="!parent.children">
<span class="fa fa-tachometer header-icon" aria-hidden="true"></span>{{parent.menuname}}
</a>
<a href="/{{parent.url}}/{{parent.actionname}}" ng-show="parent.children" class="dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-tachometer header-icon" aria-hidden="true"></span>{{parent.menuname}}
</a>
<ul class="dropdown-menu" ng-show="parent.children">
<li ng-repeat="child in parent.children" ng-show="!child.childrencc">
{{child.menuname}}
</li>
<li class="dropdown-submenu" ng-repeat="child in parent.children" ng-show="child.childrencc">
{{child.menuname}}
{{child.menuname}}
<ul class="dropdown-menu" ng-show="child.childrencc">
<li ng-repeat="children in child.childrencc">
{{children.menuname}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</header>
<!-- END HEADER -->
<!-- START CONTENT -->
<section id="main" class="container-fluid">
<!-- START RIGHT CONTENT -->
#*
<div class="row">
<!-- START RIGHT CONTENT -->
<section id="content-wrapper" class="form-elements">
<!-- START PAGE TITLE -->
<div class="site-content-title">
<h2 class="float-xs-left content-title-main">Client Dashboard</h2>
<!-- START BREADCRUMB -->
<ol class="breadcrumb float-xs-right">
<li class="breadcrumb-item">
<span class="fa fa-home" aria-hidden="true"></span>
Home
</li>
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<!-- END BREADCRUMB -->
</div>
<!-- END PAGE TITLE -->
</section>
</div>*#
#*
<div class="contain-inner"></div>*#
<ng-view> #RenderBody()</ng-view>
</section>
#*
</div>
I want menus to be loaded at the start of the application and I have multiple pages in MVC, so the problem is getting the error stated that controller not registered. so can you tell me how can I handle ng-app and ng-controller in master page and pages?
I am loading menus as follows:
app.controller('masterctrl', function ($scope, $http, $window) {
$scope.getmenus = function () {
var holding_url = encodeURI(APIURL + "getmenus");
$http.get(holding_url)
.then(function (response) {
$scope.names = response.data.t1;
$scope.menu = [];
$scope.childrenmenu = [];
$scope.count = 0;
angular.forEach(response.data.t1, function (value, key) {
if (value.parentid == 0) {
$scope.menu.push(value);
}
});
angular.forEach(response.data.t1, function (value, key) {
if (value.parentid != 0) {
angular.forEach($scope.menu, function (value2, key2) {
if (value.parentid == value2.menuid) {
if (value2.children == undefined) {
value2.children = [];
value2.showChildren = false;
}
value2.children.push(value);
$scope.childrenmenu.push(value);
}
});
}
});
angular.forEach(response.data.t1, function (value, key) {
if (value.parentid != 0) {
angular.forEach($scope.childrenmenu, function (value3, key3) {
if (value.parentid == value3.menuid) {
if (value3.childrencc == undefined) {
value3.childrencc = [];
value3.showChildren = false;
}
value3.childrencc.push(value);
}
});
}
});
Please see image due to that error data in table is also not loading properly, because master page and pages controller can not work together.
you need to bootstrap them using angular.bootstrap()
first give id to the child div lets say App2
<div class="ibox float-e-margins" ng-app="childview" id="App2">
</div>
angular.bootstrap(document.getElementById("App2"), ['childview']);
this will allow Angular to run subsequent views to run on the dom
Why not this ?
<div class="wrapper" id="body" ng-app="masterview" >
<div ng-controller="masterctrl" data-ng-init="getmenus()">
<!-- rest of your code --->
</div>
</div>

angular-carousel: overflow-x: scroll inside a slide

i'm trying to create a carousel that inside of it will be scrollable div with images.
The problem is that the swipe events conflict with eachother.
Plunker (the images are on slide 2)
My code:
<div class="carousel-demo">
<ul rn-carousel rn-carousel-index="carouselIndex" rn-carousel-buffered class="carousel1">
<li ng-swipe-left="left($event)">slide #1</li>
<li ng-swipe-right="right($event)">slide #2
<div class="horizontal-slide">
<div class="span2">
<a href="#" class="thumbnail">
<img src="http://placehold.it/150x100" alt="" />
</a>
</div>
<div class="span2">
<a href="#" class="thumbnail">
<img src="http://placehold.it/150x100" alt="" />
</a>
</div>
<div class="span2">
<a href="#" class="thumbnail">
<img src="http://placehold.it/150x100" alt="" />
</a>
</div>
<div class="span2">
<a href="#" class="thumbnail">
<img src="http://placehold.it/150x100" alt="" />
</a>
</div>
</div>
</li>
<li>slide #3</li>
</ul>
Thank's alot
Avi

Resources