How to avoid repeating JSX / HTML code in react? - javascript

I am building the UI in react.js and want to improve my JSX /HTML code to be smaller.
At the moment my JSX code takes around 70 lines of code.
This is what I am building:
And my One of the problems is that in some sentences one or more words need to be bolder.
I would like to solve that in a better way than the below implemented code.
Please find below my code HTML / JSX:
<div className="search-help" ref={(node) => this.setWrapperRef(node)}>
<div className="search-help-content">
<div className="search-help-header">
<p>Use Specific Keywords for smarter filtering - English only</p>
</div>
<div className="search-help-sections">
<div className="search-help-left-content">
<p className="search-help-section-title">Logical Operator</p>
<ul className="search-help-list">
<li className="search-help-label-spacing">
<p className="search-help-label-main">
AND
<span className="search-help-label-sub">
"TX Group" <b>AND</b> "Latest News"
</span>
</p>
</li>
<li className="search-help-label-spacing">
<p className="search-help-label-main">
NOT
<span className="search-help-label-sub">
"Pochettino" <b>NOT</b> "Mourinho"
</span>
</p>
</li>
<li className="search-help-label-spacing">
<p className="search-help-label-main">
OR
<span className="search-help-label-sub">
"Cristobal Huet" <b>OR</b> "Nico Hischier"
</span>
</p>
</li>
<li className="search-help-label-spacing">
<p className="search-help-label-main">
( )
<span className="search-help-label-sub">
<b>(</b>"Jeff Bezos" <b>OR</b> "Bill Gates" <b>OR</b>
<b>(</b> "Jack Dorsey"<b>)</b> <b>AND</b> <b>(</b>"Climate Change"<b>)</b>
</span>
</p>
</li>
</ul>
</div>
<div className="search-help-right-content">
<p className="search-help-section-title">Language</p>
<ul className="search-help-list">
<li className="search-help-label-spacing">
<p className="search-help-label-main">lang:de</p>
</li>
<li className="search-help-label-spacing">
<p className="search-help-label-main">lang:eng</p>
</li>
<li className="search-help-label-spacing">
<p className="search-help-label-main">lang:fr</p>
</li>
</ul>
</div>
</div>
</div>
</div>
Any advice or idea?

It seems extracting your <li> into a component might be a good start. Build a component, say, MyListItem and extract all repeating code there. Actual unique text will be passed there through props.
To pass different bits of text into different places you can use different props like so:
<li className="search-help-label-spacing">
<p className="search-help-label-main">
{this.props.binaryOperator}
<span className="search-help-label-sub">
"{this.props.string1}" <b>{this.props.binaryOperator}</b> "{this.props.string2}"
</span>
</p>
</li>

Related

how can I make a html and css component by javascript?

I want to summarize my HTML code and making a component by Javascript. My Html code contains a list of the picture that I put them in <li> tags. every picture has a special link, and a number into a <div> tag.how can I make a pattern for generating them by javascript?
Also, I want to sort these pics by that numbers, according to, highest to lowest, and I don't know how to do that. Totally, Is it true to summarize HTML code in this way?
<ul class="product-list">
<li class="product-item">
<a id="producItem1" href="page2.htm">
<img class="clothes" src="dress1.jpg">
</a>
<div class="price-holder">
<p id="price1">250,000</p>
</div>
</li>
<li class="product-item">
<a id="producItem2">
<img class="clothes" src="coat1.jpg">
</a>
<div class="price-holder">
<p id="price2">350,000</p>
</div>
</li>
<li class="product-item">
<a id="producItem3">
<img class="clothes" src="shirt1.jpg">
</a>
<div class="price-holder">
<p id="price3">150,000</p>
</div>
</li>
<li class="product-item">
<a id="producItem4">
<img class="clothes" src="skirt1.jpg">
</a>
<div class="price-holder">
<p id="price4">200,000</p>
</div>
</li>
</ul>
use this if you want to create list from javascript data you can use objects but i used arrays because you said no server involved so you will generate the data of image names and prices manually
$(document).ready(function(){
imgz=['dress1.jpg', 'coat1.jpg', 'shirt1.jpg', 'skirt1.jpg','dress2.jpg'];
prices=[100000, 200000, 150000, 250000, 300000];
linkz=['page1.htm','page2.htm','page3.htm','page4.htm','page5.htm'];
//linkz=[];imgz.forEach((v,i)=>{linkz[i]='page'+(i+1)+'.htm';});
imgz.map((z,i)=> $('body').append(`
<li class="product-item">
<a id="producItem${i+1}" href='${linkz[i]}'>
<img class="clothes" src="${imgz[i]}">
</a>
<div class="price-holder">
<p id="price${i+1}">${prices[i]}</p>
</div>
</li>`));
});
<html><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js">
</script></head>
<body><ul class="product-list"></ul></body></html>
and if you want to create the links data automatically use this
linkz=[];imgz.forEach((v,i)=>{linkz[i]='page'+(i+1)+'.htm';});
instead of linkz=['page1.htm','page2.htm','page3.htm','page4.htm','page5.htm'];

Unable to Scroll to Div using <a href="#"> [React,react-scrollspy]

I'm using this library https://github.com/makotot/react-scrollspy to get the scroll to div effect.However after following the documentation ,I don't seem to get it working.Code :
<RewardContainer>
<div className="pageWrapper">
<div className="rewardInfoWrapper">
<div className="tabsContainer">
<div>
<Scrollspy
items={[
"section-1",
"section-2",
"section-3"
]}
currentClassName="is-current"
>
<li>
<a
href="#section-1"
className="c-side-nav__link"
>
Streak
</a>
</li>
<li>
<a
href="#section-2"
className="c-side-nav__link"
>
Gems
</a>
</li>
<li>
<a
href="#section-3"
className="c-side-nav__link"
>
Xp Points
</a>
</li>
</Scrollspy>
</div>
</div>
<div className="columnContainer">
<div className="tabInfo">
<div>
<div id="section-1">
<p>
This is Section 1
</p>
</div>
<div id="section-2">
<p>
This is Section 2
</p>
</div>
<div id="section-3">
<p>
This is Section 3
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</RewardContainer>
The issue is ,my a href="#id" tag reloads the browser and treats id as a route instead of scrolling to that div's id.For instance,clicking on the third li element reloads the browser with http://localhost:7000/#section-3 in the url.

jQuery get attibutes and values from all elements inside a class

I'm scraping a website where it has the following HTML structure
<div id="list" class="book-list">
<div id="stream_1" class="stream collapsed">
<h3 id="s-1" rel="1"><div><a name="st_1" class="st st_1">Version 1</a></div></h3>
<div class="volume last">
<h4 id="v-1-1">Volume 1<span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922893" class="new">
<span>
<a class="ch sts sts_1" target="_blank" href="link/1">vol.1 ch.1</a>
</span>
<i>Yesterday 08:27 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
<div id="stream_5" class="stream">
<h3 id="s-5" rel="5"><div><a name="st_5" class="st st_5">Version 2</a></div></h3>
<div class="volume last">
<h4 id="v-5-">Volume <i>[Null]</i><span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922873" class="new">
<span>
<a class="ch sts sts_5" target="_blank" href="links5/c1/1">ch.1</a>
</span>
<i>Yesterday 08:10 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
</div>
I want to use jQuery to get the links from the divs to get something like this
{
"vol.1 ch.1" : "link/1",
"ch.2" : "link/2"
}
As all the items i want has the class ch sts i wanted to get them with the selector, and trying to use each() but didn't work as it shows nodes...
Here's what how i'm trying:
$d('.ch').map(function(){
console.log('This: href',$(this).attr("href"));
}).get();
It is simpler than you thought. Since you've mentioned that you only want to parse links with ch sts classes, I changed the selector.
var map = {};
$(".ch.sts").each(function() {
map[$(this).text()] = $(this).attr("href");
});
console.log(map);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list" class="book-list">
<div id="stream_1" class="stream collapsed">
<h3 id="s-1" rel="1"><div><a name="st_1" class="st st_1">Version 1</a></div></h3>
<div class="volume last">
<h4 id="v-1-1">Volume 1<span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922893" class="new">
<span>
<a class="ch sts sts_1" target="_blank" href="link/1">vol.1 ch.1</a>
</span>
<i>Yesterday 08:27 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
<div id="stream_5" class="stream">
<h3 id="s-5" rel="5"><div><a name="st_5" class="st st_5">Version 2</a></div></h3>
<div class="volume last">
<h4 id="v-5-">Volume <i>[Null]</i><span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922873" class="new">
<span>
<a class="ch sts sts_5" target="_blank" href="links5/c1/1">ch.1</a>
</span>
<i>Yesterday 08:10 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
</div>
Get all the Elements with class name.
Get the text value and "href" attribute.
x = document.getElementsByClassName("ch sts");
for(i =0; i<x.length; i++) {
console.log(x[i].text +" "+ x[i].getAttribute("href"));
}

Why is jQuery repeating div during .insertAfter?

I have 3 li and the content is repeated after I execute an .insertAfter()
<ul class="course-list">
<li>
<div class="course-image">
<img src="url_of_photo" />
</div>
<div class="course-content">
<p class="post-title"><a title="" href="/courses/level-2-certificate-in-english/"> Level 2 Certificate In English</a>
</p>
<p class="post-meta post-meta-level">Level 2</p>
<p class="post-meta post-meta-boxcolor">light blue</p>
</div>
</li>
</ul>
I want to transfer class="course-image" below class="course-content"
When I execute:
$('.course-list .course-image').insertAfter('.course-list .course-content');
The result becomes like this:
<ul class="course-list">
<li>
<div class="course-content">
<p class="post-title"><a title="Level 2 Certificate In English For Business" href="/courses/level-2-certificate-in-english/"> Level 2 Certificate In English</a>
</p>
<p class="post-meta post-meta-level">Level 2</p>
<p class="post-meta post-meta-boxcolor">light blue</p>
</div>
<div class="course-image">
<img src="url_of_photo" />
</div>
<div class="course-image">
<img src="url_of_photo" />
</div>
</li>
</ul>
It happens to every li of that ul.
What is the proper query to move class="course-image" for each list without having to repeat on evey li?
Thanks!
You need to iterate and move
$('.course-list .course-image').each(function(){
$(this).insertAfter($(this).next())
});

Adding to browsers history on click

I'm using the plugin called Ascensor from http://kirkas.ch/ascensor
It's basically a tool that help me build a single page application.
However, I have a problem that I don't know how to solve.
All of my content will be listet inside my <div id="ascensorBuilding">
<div id="ascensorBuilding">
<div class="floor floor-1">
<span class="text">Floor 1</span>
</div>
<div class="floor floor-2">
<span class="text">Floor 2</span>
</div>
<div class="floor floor-3">
<span class="text">Floor 3</span>
</div>
<div class="floor floor-4">
<span class="text">Floor 4</span>
</div>
<div class="floor floor-5">
<span class="text">Floor 5</span>
</div>
<div class="floor floor-6">
<span class="text">Floor 6</span>
</div>
<div class="floor floor-7">
<span class="text">Floor 7</span>
</div>
</div>
And my floor links:
<nav>
<ul class="links-to-floor">
<li><a>Floor 1</a></li>
<li><a>Floor 2</a></li>
<li><a>Floor 3</a></li>
<li><a>Floor 4</a></li>
<li><a>Floor 5</a></li>
<li><a>Floor 6</a></li>
<li><a>Floor 7</a></li>
</ul>
</nav>
And I then use this script to change between the "pages"
var ascensor = $('#ascensorBuilding').ascensor({ascensorFloorName:["Home", "About", "HTML" , "Jquery" , "CSS", "Smartphone", "End"], direction: [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0]]});
var ascensorInstance = $('#ascensorBuilding').data('ascensor');
$(".links-to-floor li").click(function(event, index) {
ascensorInstance.scrollToFloor($(this).index());
});
$(".links-to-floor li:eq("+ ascensor.data("current-floor") +")").addClass("selected");
ascensor.on("scrollStart", function(event, floor){
$(".links-to-floor li").removeClass("selected");
$(".links-to-floor li:eq("+floor.to+")").addClass("selected");
});
As you can see I add a floorname to my url. So I will start on www.mysite.com/index.html#home and if I go to another page, it would be www.mysite.com/index.html#about for example.
And if I manually put www.mysite.com/index.html#about in the addressbar, I will also go to that specific page.
But my problem is that if I click around my floors, non of the pages are added to the browsers history. So if I decide to click on the browsers back button, I will go back the site I was on before entering my website.
How can I manage to add my click to the browsers history?
You can manipulate the Javascript history object yourself:
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries

Categories

Resources