React onClick preinitialization - javascript

This is my React.component code. OnClick event executed on page initialization and i cant fix this, i tried 2 pull onClick over the maping, but this has no sense:
handleClick (id){
alert(id);
}
render() {
var tmp = this.handleClick;
return(
<div className="thirteen wide column">
<div className="rrc-title">Магазины, нарушающие РРЦ</div>
<div className="custom-hr"></div>
<div className="ui grid">
{
jsonResult.data.map(function(el){
return (
<div className="three wide column">
<div className="store-item-bad" onClick={tmp(el.siteId)}>
<div className="siteName">{el.siteName}</div>
{
el.values.map(function(element){
var processWidth ={
background : element.color,
width: element.percent+'%'
}
return(
<div className="BarItem">
<div className="progressBar">
<div className="ui tiny progress">
<div className="bar" style={processWidth}></div>
</div>
</div>
<div className="progressCounter">{element.count}</div>
</div>)
})
}
</div>
</div>
);
})
}
</div>
<div className="rrc-title">Магазины, соблюдающие РРЦ</div>
<div className="custom-hr"></div>
<div className="ui grid">
{
jsonResult.data.map(function(el){
return (
<div className="three wide column">
<div className="store-item-ok">
<div className="siteName">{el.siteName}</div>
{
el.values.map(function(element){
var processWidth ={
background : element.color,
width: element.percent+'%'
}
return(
<div className="BarItem">
<div className="progressBar BarFloatingLeft">
<div className="ui tiny progress">
<div className="bar" style={processWidth}></div>
</div>
</div>
<div className="progressCounter">{element.count}</div>
</div>)
})
}
</div>
</div>
);
})
}
</div></div>
);
}
It's easy thing, but i can't focus right now, so i need ur help guys:)

Try:
onClick={this.handleClick.bind(this,el.siteId)} or
onClick={tmp.bind(this,el.siteId)}
And add arrow func in map:
map(e=>{})

Related

WordPress InnerBlocks Gutenberg don't save correct

I have a very simple InnerBlock. When I'm opening a page I can create a nest the blocks without any issue. I can save and view the page everything is correct. However when I'm trying to edit the page again I get the Block validation failed error:
Content generated by `save` function:
<div class="container my-4 my-md-5" class="wp-block-wpptheme-faq-section"><div class="row"><div class="col-12"><div class="accordion" id="faq"><div></div></div></div></div></div>
Content retrieved from post body:
<div class="container my-4 my-md-5" class="wp-block-wpptheme-faq-section"><div class="row"><div class="col-12"><div class="accordion" id="faq"><div>
Why is the block not saving correctly?
const ALLOWED_BLOCKS = ['wpptheme/faq-block'];
registerBlockType('wpptheme/faq-section', {
//built-in attributes
title: 'FAQ Abschnitt',
icon: 'star-filled',
category: 'wpptheme',
edit() {
return ([
<div class="wpptheme-custom">
<h3>Häufig gestelle Fragen</h3>
<div>
<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } />
</div>
</div>
]);
},
save() {
return (
<div class="container my-4 my-md-5">
<div class="row">
<div class="col-12">
<div class="accordion" id="faq">
<div>
<InnerBlocks.Content />
</div>
</div>
</div>
</div>
</div>
);
}
});
registerBlockType('wpptheme/faq-block', {
//built-in attributes
title: 'FAQ Block',
icon: 'star-filled',
parent: [ 'wpptheme/faq-section' ],
category: 'wpptheme',
edit() {
return ([
<div class="wpptheme-custom">
<h4>Block</h4>
</div>
]);
},
save() {
return (
<h3>Test</h3>
);
}
});
The issue how the classes are being applied in save() of wpptheme/faq-section. CSS classes in React should be passed in with "className" property, unlike vanilla HTML.
Updated save() for wpptheme/faq-section:
...
save() {
return (
<div className="container my-4 my-md-5">
<div className="row">
<div className="col-12">
<div className="accordion" id="faq">
<div>
<InnerBlocks.Content />
</div>
</div>
</div>
</div>
</div>
);
}
...

React - Show/hide when mouse hovers using hooks

I'm trying to create a show/hide div for when my mouse enters and leaves the container. I was following this example here (https://upmostly.com/tutorials/react-onhover-event-handling-with-examples) but I've run into a problem when I hover my mouse over the 'delete-container' div, it disappears. This problem occurs because it takes the action onMouseLeave. Is there a way I can fix this or possibly make my solution better? Here is a demo of what is happening (https://i.gyazo.com/528d909625b6b3828325c4e62894d1c3.mp4).
import React, { useState } from 'react';
import axios from 'axios';
export default function JobInfo({ jobs_info }) {
const [isShown, setIsShown] = useState(false);
const changeBackground = (x) => {
x.target.style.backgroundImage =
'linear-gradient(to right, #4639a7, #78019c)';
};
const changeBackground2 = (x) => {
x.target.style.background = 'rgb(37, 45, 73)';
};
return (
<div className='row'>
<div
className='container'
onMouseEnter={() => setIsShown(true)}
onMouseLeave={() => setIsShown(false)}
>
<div className='row'>
<div className='job-title'>{jobs_info.title}</div>
</div>
<div className='row wrapper'>
<div className='category-title'>Category</div>
<div className='location-title'>Location</div>
<div className='type-title'>Type of Job</div>
<div className='creator-title'>Job Creator</div>
</div>
<div className='row wrapper'>
<div className='category'>{jobs_info.job_team.title}</div>
<div className='location'>
{jobs_info.job_location.title}
</div>
<div className='type'>{jobs_info.job_work_type.title}</div>
<div className='creator'>{jobs_info.user.name}</div>
</div>
</div>
<div
className='counter-container'
id='counter-container'
onMouseEnter={changeBackground}
onMouseLeave={changeBackground2}
>
Candidates <br />
{jobs_info.candidates_count}
</div>
{isShown && (
<div className='delete-container center'>
<ion-icon id='trash' name='trash'></ion-icon>
</div>
)}
</div>
);
}
The issue happens because delete-container is outside of the container hierarchy and hence mouseleave event is triggered on the container. Render the delete-container as a child of container and style it accordingly
return (
<div className='row'>
<div
className='container'
onMouseEnter={() => setIsShown(true)}
onMouseLeave={() => setIsShown(false)}
>
<div className='row'>
<div className='job-title'>{jobs_info.title}</div>
</div>
<div className='row wrapper'>
<div className='category-title'>Category</div>
<div className='location-title'>Location</div>
<div className='type-title'>Type of Job</div>
<div className='creator-title'>Job Creator</div>
</div>
<div className='row wrapper'>
<div className='category'>{jobs_info.job_team.title}</div>
<div className='location'>
{jobs_info.job_location.title}
</div>
<div className='type'>{jobs_info.job_work_type.title}</div>
<div className='creator'>{jobs_info.user.name}</div>
</div>
{isShown && (
<div className='delete-container center'>
<ion-icon id='trash' name='trash'></ion-icon>
</div>
)}
</div>
<div
className='counter-container'
id='counter-container'
onMouseEnter={changeBackground}
onMouseLeave={changeBackground2}
>
Candidates <br />
{jobs_info.candidates_count}
</div>
</div>
);
However you could simply use CSS hover event to show or hide the delete-container without the need for state after renderingdelete-containeras a child ofcontainer`
.scss
.container {
.delete-container {
display: none;
// other styles
}
&:hover {
.delete-container {
display: block;
}
}
// other styles
}

React.js - Close and add another row div after X items

I'm learning React.js.
I have this code:
const articles = Object
.keys(this.state.articles)
.map(key => <ArticleThumb key={key} details={this.state.articles[key]} />)
;
return (
<div className="container">
<div className="row">
{ articles }
</div>
</div>
)
Assuming I have 6 items, here is the code after rendering:
<div className="container">
<div className="row">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
<div id="item4"></div>
<div id="item5"></div>
<div id="item6"></div>
</div>
</div>
But I want to have only 3 items per line like this:
<div className="container">
<div className="row">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
<div className="row">
<div id="item4"></div>
<div id="item5"></div>
<div id="item6"></div>
</div>
</div>
What is the best way to do this?
The easy answer is to use something like lodash's chunk function https://lodash.com/docs/4.17.4#chunk
However, if you are not using npm and or do not want to add additional dependencies you are going to have to use a good old fashioned javascript for loop to perform the grouping you need.
With the markup you have you could do it via css:
.container {
display: flex;
flex-wrap: wrap;
}
.row {
width: 33%;
box-sizing: border-box;
}
I made a ArticleGrid component:
class ArticleGrid extends Component {
render() {
let articlesRows = Object
.keys(this.props.rows)
.map(key => <ArticleRow key={key} articles={this.props.rows[key]} />)
;
return (
<div id="articles" className="container">
{articlesRows}
</div>
);
}
}
export default ArticleGrid;
A ArticleRow component:
class ArticleRow extends Component {
render() {
let articles = Object
.keys(this.props.articles)
.map(key => <ArticleThumb key={key} details={this.props.articles[key]} />)
;
return (
<div className="row">
{articles}
</div>
);
}
}
export default ArticleRow;
I used lodash's chunk and values function (ty Deadron) and it's done:
let articles = _.values(this.state.articles);
let articlesRows = _.chunk(articles, 3);
return (<ArticleGrid rows={articlesRows} />);

React.js+Bootstrap rendering rows

I am using bootstrap and I want to render 4 columns in row. However I do not know how many columns I will have, so it should work for any number of columns and also first column can be different react component then other columns.
What I want to achieve:
<div class="row">
<div class="col-md-3 component-type-1">...</div>
<div class="col-md-3 component-type-2">...</div>
<div class="col-md-3 component-type-2">...</div>
<div class="col-md-3 component-type-2">...</div>
</div>
<div class="row">
<div class="col-md-3 component-type-2">...</div>
<div class="col-md-3 component-type-2">...</div>
<div class="col-md-3 component-type-2">...</div>
<div class="col-md-3 component-type-2">...</div>
</div>
I tried something but did not managed to achieve what I want..
import chunk from 'lodash/chunk.js'
class Test extends React.Component {
render() {
let component1=null;
if (this.state.shouldBeComponent1) {
component1=<Component1 key="component1" />;
}
let items = [];
if (component1!=null) items.push(component1);
this.state.dataForComponents2.forEach((data) => {
items.push(<Component2 key={data.ID} />)
});
const rows = chunk(items, 4);
let pageBody=null;
if (items.length>0) {
pageBody=(
rows.map((row) => {
<div className="row">
{
row.map((item) => (
{item}
))
}
</div>})
);
}
return (
<div>
<div className="header">
///Other unreleated code
</div>
{pageBody}
</div>
);
}
Seems something wrong with your pageBody
Try this.
let pageBody= [];
if (items.length>0) {
rows.forEach((row, idx) => {
pageBody.push
(
<div key={idx} className="row">
{row}
</div>
)}
);
}
And example here

How to show loader in reactjs and meteor?

I have a page where 3 recipes are listed along with more button. When more button is clicked more 3 recipes are listed. What i am trying to do is before listing more 3 recipes i want to show a spinner/loader icon but i could only change the text of button. How can i show loader icon as soon as more button is clicked and before those additional 3 recipes are listed. I am using meteorjs and reactjs.
my code for this is
export default class Home extends Component {
constructor(){
super();
this.state = { limit:3 , loading:false }
this.addMore = this.addMore.bind(this);
}
getMeteorData(){
let data = {};
data.recipes = [];
data.recipes = Recipes.find({},{sort:{createdAt:-1}}).fetch();
let recipeHandle = Meteor.subscribe('recipelist',this.state.limit);
if(recipeHandle.ready()){
data.recipes = Recipes.find({},{sort:{createdAt:-1},limit:this.state.limit}).fetch();
}
return data;
}
addMore(){
this.setState({
limit:this.state.limit + 3, loading: true }, () => {
this.setTimeout(()=>{
this.setState({loading:false});
},2000);
});
}
render() {
console.log('this.data.recipes',this.data.recipes);
let recipes = _.map(this.data.recipes,(recipe) => {
return <RecipeList key={recipe._id} recipe={recipe} loading={this.state.loading} />
});
return (
<div className="row">
<div className="intro blink z-depth-1">
<div className="row">
<div className="col l7">
<h1 className="heading flow-text blink">Sell your Recipe</h1>
</div>
</div>
</div>
<div className="row">
<div className="col s12">
{recipes}
</div>
</div>
<button onClick={this.addMore} type="button" className="btn coral more">More</button>
</div>
);
}
}
ReactMixin(Home.prototype, ReactMeteorData);
You could remove the loading state, and just compute the loading state from the data: {this.state.limit !== this.data.recipes.length && <img src="path_to_loader.gif" />}
I am not sure where you want to show the loader, but for example you could do:
render() {
console.log('this.data.recipes',this.data.recipes);
let recipes = _.map(this.data.recipes,(recipe) => {
return <RecipeList key={recipe._id} recipe={recipe} loading={this.state.loading} />
});
return (
<div className="row">
<div className="intro blink z-depth-1">
<div className="row">
<div className="col l7">
<h1 className="heading flow-text blink">Sell your Recipe</h1>
</div>
</div>
</div>
<div className="row">
<div className="col s12">
{recipes}
</div>
</div>
{this.state.limit !== this.data.recipes.length && <img src="path_to_loader.gif" />}
<button onClick={this.addMore} type="button" className="btn coral more">More</button>
</div>
);
}

Categories