How to place glyphicon in bootstrap navbar within a react.js project - javascript

How can I display a glyphicon in a bootstrap navbar? I have a React.js project that I have been working on, and I would like to relocate the GitHub glyphicon to the navbar. So far I have something looking like the below.
The code pertaining to the navbar in the App.js
import React, {PropTypes} from 'react';
import NavBar from './common/NavBar-test';
import FontAwesome from 'react-fontawesome';
var navbar = {};
navbar.brand = {linkTo: "#", text: "app"};
navbar.links = [
{linkTo: "#Demonstration", text: "Demonstration"},
{linkTo: "#Demonstration2", text: "Demonstration #2"},
{linkTo: "https://github.com/user/app", text:"GitHub Source Code"},
{linkTo: "https://itunes.apple.com/us/app/", text: "App Store"},
{linkTo: "https://github.com/user/appr", text: "The Future of app"}
];
And Navbar-test.js
import React, { PropTypes } from 'react';
// create classes
var NavBar = React.createClass({
render: function(){
return(
<nav className="navbar navbar-default navbar-static-top">
<div className="container-fluid">
<div className="navbar-header">
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
<span className="sr-only">Toggle navigation</span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
<NavBrand linkTo={this.props.brand.linkTo} text={this.props.brand.text} />
</div>
<div className="collapse navbar-collapse" id="navbar-collapse">
<NavMenu links={this.props.links} />
</div>
</div>
</nav>
);
}
});
var NavBrand = React.createClass({
render: function(){
return (
<a className="navbar-brand" href={this.props.linkTo}>{this.props.text}</a>
);
}
});
var NavMenu = React.createClass({
render: function(){
var links = this.props.links.map(function(link){
if(link.dropdown) {
return (
<NavLinkDropdown key={link.text} links={link.links} text={link.text} active={link.active} icon={link.icon} />
);
}
else {
return (
<NavLink key={link.text} linkTo={link.linkTo} text={link.text} active={link.active} />
);
}
});
return (
<ul className="nav navbar-nav">
{links}
</ul>
);
}
});
var NavLinkDropdown = React.createClass({
render: function(){
var active = false;
var links = this.props.links.map(function(link){
if(link.active){
active = true;
}
return (
<NavLink key={link.text} linkTo={link.linkTo} text={link.text} active={link.active} />
);
});
return (
<li className={"dropdown " + (active ? "active" : "")}>
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
{this.props.text}
<span className="caret"></span>
</a>
<ul className="dropdown-menu">
{links}
</ul>
</li>
);
}
});
var NavLink = React.createClass({
render: function(){
return(
<li className={(this.props.active ? "active" : "")}>
<a href={this.props.linkTo}>{this.props.text}{this.props.icon}</a>
</li>
);
}
});
export default NavBar;
Ideally, I'd like to place the GitHub glyphicon in front of the text that states GitHub Source Code.

It looks like you are mapping over the links (which is cool), but you can add your desired GitHub data before the mapped links.
You might end up with something like this:
<span>
<NavLink>GitHub Source Code</NavLink>
<GlyphIcon />
</span>
// Then map over links here

In short, I finally got the glyphicons to display how I would like them to.
I needed to modify the source of the Navbar-test to support icons.
Something like,
class NavMenu extends React.Component {
render() {
var links = this.props.links.map(function(link){
if(link.dropdown) {
return (
<NavLinkDropdown key={link.text} links={link.links} text={link.text} active={link.active} icon={link.icon} />
);
}
else {
return (
<NavLink key={link.text} linkTo={link.linkTo} icon={link.icon} text={link.text} active={link.active} />
);
}
});
return (
<ul className="nav navbar-nav">
{links}
</ul>
); // close return
} // close render
} // close NavMenu

Related

Change the value in massive by pressing button(React)

Ok, so I am creating employers list with salary and Names. I want to change color of text by changing value of variable - "increase" from false to true for example. I already created code to change text taking value FROM variable
<li className={ increase ? "list-group-item d-flex justify-content-between increase" : "list-group-item d-flex justify-content-between"}>
Now I need to change value of "increase" by clicking a button <i className="fas fa-cookie"></i>
Here is a full code:
const EmployeesListItem = ({name, salary, increase}) => {
return (
//-------Here I check the value of variable----->
<li className={ increase ? "list-group-item d-flex justify-content-between increase" : "list-group-item d-flex justify-content-between"}>
<span className="list-group-item-label">{name}</span>
<input type="text" className="list-group-item-input" defaultValue={salary + "$"}/>
<div className='d-flex justify-content-center align-items-center'>
<button type="button"
className="btn-cookie btn-sm ">
<i className="fas fa-cookie"></i> //by clicking in this button I wanna change value of increase variable
</button>
<button type="button"
className="btn-trash btn-sm ">
<i className="fas fa-trash"></i>
</button>
<i className="fas fa-star"></i>
</div>
</li>
)
}
export default EmployeesListItem;
Here is EmployerList structure:
import EmployeesListItem from '../employeers-list-item/employeers-list-item'
import './employers-list.css'
const EmployersList = ({data}) => {
const elements = data.map(item => {
return(
<EmployeesListItem {...item} data={data}/> //name={item.name} salary={item.salary}
)
})
return (
<ul className='app-list list-group'>
{elements}
</ul>
)
}
export default EmployersList;
And here is App component:
function App() {
const data = [
{name: 'killer228brawlstarsassasin1993', salary:2300 ,increase: true},
{name: 'jotaro', salary:800 ,increase: false},
{name: 'Ktoh', salary:300 ,increase: true}
]
return (
<div className="app">
<AppInfo/>
<div className="search-panel">
<SearchPanel>
</SearchPanel>
<AppFilter/>
</div>
<EmployersList data={data}/>
<EmployeesAddForm/>
</div>
)
}
export default App;
the program works, but still don't know how to change the value of the INCREASE variable in the APP component by clicking on the button
You should read about React Context, this will help you to store data so it is accessible from every component: https://reactjs.org/docs/context.html
The way your app works now you need to pass a "changeIncrease"-function as prop to the EmployeesListItem component.
const changeIncrease = (name) => {
data.forEach(employee, index) => {
if(employee.name == name) {
data[index] = {...emloyee, increase: !employee.increase}
}
}
}
Maybe there's a more elegant solution out there, but this should do it

Changing state of component with OnClick in React

I am trying to change state of the component and render it to page.
var navbarValue = [{"Category":"Home","Status":1},{"Category":"About","Status":0},{"Category":"Contact","Status":0}];
class NavbarList extends React.Component {
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const {id} = event.target;
console.log(id);
if(!navbarValue[id].Status){
{navbarValue.map((obj, index) =>{
if(navbarValue[index].Status){
navbarValue[index].Status = 0;
return <li key={index}><a id={index} onClick={this.onClick}>{obj.Category} </a></li>
}
})}
navbarValue[id].Status = 1;
return <li className="active" key={id}><a id={id} onClick={this.onClick}>{navbarValue[id].Category}</a></li>
}
}
render() {
return (
<div className="navbar-wrapper">
<div className="container">
<nav className="navbar navbar-fixed-static-top navbar-inverse">
<div className="container">
<div className="navbar-header">
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span className="sr-only">Toggle navigation</span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
<a className="navbar-brand" href="#">BrandName</a>
</div>
<div id="navbar" className="collapse navbar-collapse">
<ul className="nav navbar-nav">
{navbarValue.map((obj, index) => {
if (obj.Status)
return <li className="active" key={index}><a id={index} onClick={this.onClick}>{obj.Category}</a></li>
return <li key={index}><a id={index} onClick={this.onClick}>{obj.Category} </a></li>
})}
</ul>
</div>
</div>
</nav>
</div>
</div>
)};
};
ReactDOM.render(
<NavbarList />,
document.getElementById('root')
);
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
I have an if statement in handleClick(event) which validates if function has to be run and rerender elements.
First it checks if button which is already active is not being clicked. Next if statment is in loop to find previous active element, change objects property to 0 and render to not active.
At the end render new active element to active and set objects property to 1.
Put navbarValue in a state object and update the state onClick. You don't need if/else statements here. Because your components will be rerendered on state update.
Like this: https://stackoverflow.com/a/45134876/4953199

Rerender functional component when prop changes

I'm having trouble rerendering component when parent state passed to child component changes. MapNav component contains buttons which triggers methods changing current displayed popup. My problem is to re-render UserPopup button when someone clicks zaloguj or wyloguj, it should work but it does not and i cant figure out what is wrong also i don't want to trigger animation when isLoggedIn state changes and one more thing logIn method changes state properly. isLoggedIn state is just temporary later i'll change that to use store instead. I'm trying to write as much functional component but in some cases i cant avoid using state and i bet that there are issues in my code so i'll appreciate all improvement tips.
const MapNav = (props) => {
return <div className={'mapNavContainer'}>
<ul className={'navList'}>
<li><i className={"glyphicon glyphicon-fullscreen"} /></li>
<li><i className={"glyphicon glyphicon-chevron-left"} /></li>
<li><i className={"glyphicon glyphicon-chevron-right"} /></li>
<li><i className={"glyphicon glyphicon-map-marker"} /></li>
<li><a href="#" onClick={props.onUserIconClick}><i className={"glyphicon glyphicon-user"} /></a></li>
<li><a href="#" onClick={props.onInfoClick}><i className={"glyphicon glyphicon-info-sign"} /></a></li>
</ul>
</div>
}
const UserPopup = (props) => {
return <div>
{(props.isLoggedIn) ? (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Zalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>wyloguj</button>
</div>
</div>
) : (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Niezalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>Zaloguj</button>
</div>
</div>
)
}
</div>;
};
function Welcome(props) {
return <div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Informacje o Autorze.</div>
<div className={"panel-body"}>
Basic panel example
</div>
</div>;
}
class MapHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPopup: null,
isLoggedIn: false,
username: 'gregorowicz.k#gmail.com',
};
this.onInfoClick = this.onInfoClick.bind(this);
this.onUserIconClick = this.onUserIconClick.bind(this);
this.logIn = this.logIn.bind(this);
}
onInfoClick = (e) => {
e.preventDefault();
this.setPopup(<Welcome />);
}
onUserIconClick = (e) => {
e.preventDefault();
const loginPopup = <UserPopup isLoggedIn={this.state.isLoggedIn} username={this.state.username} logIn={this.logIn} />;
this.setPopup(loginPopup);
}
setPopup = (obj) => {
this.state.currentPopup === null ? this.setState({ currentPopup: obj }) : this.setState({ currentPopup: null });
}
logIn = (e) => {
this.setState({ isLoggedIn: !this.state.isLoggedIn });
}
render() {
return (
<nav className={'header'}>
<div className={'container-fluid'}>
<div className={"navbar-header"}>
<button type="button" className={"navbar-toggle collapsed"} data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span className={"sr-only"}>Toggle navigation</span>
<span className={"icon-bar"} />
<span className={"icon-bar"} />
<span className={"icon-bar"} />
</button>
</div>
<div id={"navbar"} className={'navContainer'}>
{MapNav({onInfoClick:this.onInfoClick, onUserIconClick:this.onUserIconClick})}
{this.state.currentPopup ? this.state.currentPopup : null}
</div>
</div>
</nav>
)
}
}
// Render it
ReactDOM.render(
<MapHeader />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" />
I've solved it. There is currentPopup state in my code which stored current popup displayed, to see changes i had to unmount and mount component again after isLogggedIn state changed, so i've changed the way to display current popup. Instead storing whole component in state, i store just simple string values which provide information about current component. Anyway thank you for tips, i'll surely apply them in my code.
const MapNav = (props) => {
return <div className={'mapNavContainer'}>
<ul className={'navList'}>
<li><i className={"glyphicon glyphicon-fullscreen"} /></li>
<li><i className={"glyphicon glyphicon-chevron-left"} /></li>
<li><i className={"glyphicon glyphicon-chevron-right"} /></li>
<li><i className={"glyphicon glyphicon-map-marker"} /></li>
<li><a href="#" onClick={props.onUserIconClick}><i className={"glyphicon glyphicon-user"} /></a></li>
<li><a href="#" onClick={props.onInfoClick}><i className={"glyphicon glyphicon-info-sign"} /></a></li>
</ul>
</div>
}
const UserPopup = (props) => {
return <div>
{(props.isLoggedIn) ? (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Zalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>wyloguj</button>
</div>
</div>
) : (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Niezalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>Zaloguj</button>
</div>
</div>
)
}
</div>;
};
function Welcome(props) {
return <div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Informacje o Autorze.</div>
<div className={"panel-body"}>
Basic panel example
</div>
</div>;
}
class MapHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPopup: null,
isLoggedIn: null,
};
this.onInfoClick = this.onInfoClick.bind(this);
this.onUserIconClick = this.onUserIconClick.bind(this);
this.logIn = this.logIn.bind(this);
}
onInfoClick = (e) => {
e.preventDefault();
this.setState({ currentPopup: this.state.currentPopup === 'info' ? null : 'info' });
}
onUserIconClick = (e) => {
e.preventDefault();
this.setState({ currentPopup: this.state.currentPopup === 'user_login' ? null : 'user_login' });
}
setPopup = (obj) => {
this.setState({ currentPopup: this.state.currentPopup === 'user_login' ? null : 'user_login' });
}
logIn = (e) => {
this.setState({ isLoggedIn: !this.state.isLoggedIn });
}
render() {
return (
<nav className={'header'}>
<div className={'container-fluid'}>
<div className={"navbar-header"}>
<button type="button" className={"navbar-toggle collapsed"} data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span className={"sr-only"}>Toggle navigation</span>
<span className={"icon-bar"} />
<span className={"icon-bar"} />
<span className={"icon-bar"} />
</button>
</div>
<div id={"navbar"} className={'navContainer'}>
{MapNav({onInfoClick:this.onInfoClick, onUserIconClick:this.onUserIconClick})}
{this.state.currentPopup === 'info' ? <Welcome /> : null}
{this.state.currentPopup === 'user_login' ? (
<UserPopup isLoggedIn={this.state.isLoggedIn} logIn={this.logIn} />
) : null}
</div>
</div>
</nav>
)
}
}
// Render it
ReactDOM.render(
<MapHeader />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" />

Toggling CSS as a state for li items in React

I've a list of photos being displayed as a React Component.
The individual list items are initially displayed with a + sign. The behavior I'm trying to acheive is on clicking a particular list item, the sign changes to -, and once a different list item is clicked, the first one reverts to + and the current one goes to -.
This is my render code,
render() {
let classes = "glyphicon add-icon " + (this.state.glyphClass ? "glyphicon-plus" : "glyphicon-minus");
return (
<div className="row">
<ul className="list-inline">
{this.props.images.map(function (image) {
return (<li key={image.id}>
<a href="#" onClick={this.getMediaId} data-id={image.id} data-class={image.src} data-owner={image.owner}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
<div className="img-selector">
<span className={classes} id="plus-icon" aria-hidden="true"></span>
</div>
</div>
</a>
</li>);
}, this)}
</ul>
</div>
);
}
This is the constructor,
constructor(props){
super(props);
this.getMediaId = this.getMediaId.bind(this);
this.state = { glyphClass : true };
}
And this is the method that does the toggle,
getMediaId(event){
event.preventDefault();
this.setState({
glyphClass: !this.state.glyphClass
});
console.log(this.state.glyphClass);
....
}
The behavior that I'm getting now is that onClick on any list item all the list items are toggling to - and then on a subsequent click all are toggling to +. I'd really appreciate some help in fixing this.
You can have a selectedItem in the state instead.
constructor(props){
super(props);
this.getMediaId = this.getMediaId.bind(this);
this.state = { selectedItem : null };
}
Then in the get media set the id of selectedItem when clicked.
getMediaId(id){
this.setState({
selectedItem: id
});
}
Then you can check the id when rendering the list.
if the selectedItem has the same id of the list, render the - else render +.
render() {
return (
<div className="row">
<ul className="list-inline">
{this.props.images.map(function (image) {
const classes = this.state.selectedItem === image.id ? 'glyphicon add-icon glyphicon-minus' : 'glyphicon add-icon glyphicon-plus';
return (<li key={image.id}>
<a href="#" onClick={(event) => {event.preventDefault(); this.getMediaId(image.id); }} data-id={image.id} data-class={image.src} data-owner={image.owner}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
<div className="img-selector">
<span className={classes} id="plus-icon" aria-hidden="true"></span>
</div>
</div>
</a>
</li>);
}, this)}
</ul>
</div>
);
}

Get arguments from another component [React JS]

I'm creating a web-app using React. I'm facing a problem with my navbar and the main content:
In AppWrapper I have this:
var contents = [
<Offers />,
<Create />,
<List />
];
and where each item will be the content displaying.
In getInitialState I initialize it like this:
getInitialState: function() {
return {
currentTab: 0
};
},
Later, in render function I have this:
return (
<div>
<Navbar />
<div className='mainPanel'>
{contents[this.state.currentTab]}
</div>
</div>
);
You can see that I call the navbar component before the content.
In Navbar component I have a menu where, from there, I want to change the currentTab of AppWrapper.
How can I do that? Thank you for advance!
After trying to handle it, I found how to do that.
This is the answer:
<Navbar selectTab={this.selectTab} />
selectTab: function(tab) {
this.setState({ currentTab: tab });
}
I pass to Navbar component the function "selectTab of the parent (AppWrapper).
Then in Navbar component:
<li>
<a onClick={this.selectTab.bind(this, 0)}><i className="fa fa-dashboard fa-fw" /> Dashboard</a>
</li>
<li>
<a onClick={this.selectTab.bind(this, 1)}><i className="fa fa-edit fa-fw" /> Create</a>
</li>
Then in selectTab of Navbar I change the props to current tab.
selectTab: function(tab) {
this.props.selectTab(tab);
},
Hope someone helps this answer!

Categories