AngularJS - Hiding and Showing Element Without Use of JS/Script - angularjs

I have a set of headings (<h3>) that when clicked, they hide/show their corresponding sections.
I have achieved this by using ng-show/ng-hide and then calling a $scope variable isInactive/isActive.
What i would like to know, is if the same result can be achieved, without the need for using JS within $scope.isInactive and $scope.isActive and logic be placed in the HTML markup? Possibly with the us of ng-class?
HTML:
<div ng-app="">
<div ng-controller="EventController">
<div class="tabs">
<h3 class="" id="tab-{{$index}}-0"><a id="1" data="{{$index}}" ng-click="switch($event)">1 - 5 Years</a></h3>
<h3 class="inactive" id="tab-{{$index}}-1"><a id="2" data="{{$index}}" ng-click="switch($event)">6 - 10 Years</a></h3>
<h3 class="inactive" id="tab-{{$index}}-2"><a id="3" data="{{$index}}" ng-click="switch($event)">11 - 15 Years</a></h3>
<h3 class="inactive" id="tab-{{$index}}-3"><a id="4" data="{{$index}}" ng-click="switch($event)">16 - 20 Years</a></h3>
<div class="clear" data="{{$index}}" ng-hide="isInactive('#tab-'+{{$index}} + '-0')">1 - 5 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-1')">6 - 10 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-2')">11 - 15 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div class="clear" ng-show="isActive('#tab-'+{{$index}} + '-3')">16 - 20 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
</div>
</div>
</div>
JS:
function EventController($scope) {
$scope.
switch = function (e) {
var target = e.target || e.srcElement;
var elem = angular.element(target);
var parent = elem.parent();
var allHeadings = parent.parent().find("h3");
angular.forEach(allHeadings, function (aHeading) {
var child = angular.element(aHeading);
child.addClass("inactive");
});
parent.removeClass("inactive");
}
$scope.isInactive = function (e) {
var elem = angular.element(document.querySelector(e));
if (elem.hasClass("inactive")) {
return true;
} else {
return false;
}
};
$scope.isActive = function (e) {
var elem = angular.element(document.querySelector(e));
if (elem.hasClass("inactive")) {
return false;
} else {
return true;
}
};
}
My jsFiddle: http://jsfiddle.net/oampz/Wr79J/2/

Yes, you have correctly identified this the apt place for using ng-class.
It is possible to do only using HTML and a minimalistic controller: http://jsfiddle.net/Wr79J/4/
JS
function EventController($scope) {
$scope._activeTab = 1;
}
HTML
<div ng-app="">
<div ng-controller="EventController">
<div class="tabs">
<h3 ng-class="{ 'inactive': _activeTab !== 1, 'active': _activeTab == 1 }">
<a id="1" ng-click="_activeTab=1">1 - 5 Years</a></h3>
<!-- .... -->
<div class="clear" ng-show="_activeTab == 1">
1 - 5 Years Text - Lorem ipsum ...
</div>
</div>
Note: I think you were using {{$index}} from a scope this part of the template had inherited. I have left that untouched in the example.
Though this works, this code is not very maintainable. You may want to use more descriptive names for the tabs instead of 1, 2, 3, and 4.
You can get rid of the controller completely using an ng-init="_activeTabe = 1" on the container div, but it is not the correct use of ng-init.
Also, it is not considered good practise to manipulate the DOM in any way from the controller (I am looking at the addClass/removeClass in the code). If it is necessary, then one should use directives (e.g. ng-class) for the manipulation.

You can just set a variable to set the active tab.
<div class="tabs">
<h3 ng-click="range=1">1-5</h3>
<h3 ng-click="range=2">6-10</h3>
<div class="clear" ng-show="range==1">1 - 5 Years Text</div>
<div class="clear" ng-show="range==2">6 - 10 Years Text</div>
</div>

Here is an example - http://plnkr.co/edit/NTVPbOC5k7HKo88qp6vN?p=preview with no javascript code for the above logic.
<div>
<div>
<div class="tabs">
<h3 ng-init="active=1" ng-click="active=1" ng-class="{true:'active', false:'inactive'}[active==1]"><a >1 - 5 Years</a></h3>
<h3 ng-click="active=2" ng-class="{true:'active', false:'inactive'}[active==2]"><a >6 - 10 Years</a></h3>
<h3 ng-click="active=3" ng-class="{true:'active', false:'inactive'}[active==3]"><a >11 - 15 Years</a></h3>
<h3 ng-click="active=4" ng-class="{true:'active', false:'inactive'}[active==4]"><a >16 - 20 Years</a></h3>
<div ng-show="active==1">1 - 5 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div ng-show="active==2">6 - 10 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div ng-show="active==3">11 - 15 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
<br>
<div ng-show="active==4">16 - 20 Years Text - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</div>
</div>
</div>
</div>

Related

My Toggle/Click event re-renders entire component each time on click?

I have a toggle to show/hide a specific DIV and change the button text based on the current React Hook State. When I view the console log, every single time I click it re-renders the complete page again in Next.js. Not 100% sure if this is normal, But I don't think this should happen if you only toggle one element.
useEffect you can pass property to say whether a specific state is changed or not.
Is there a smarter way of toggling an element and changing its text on click? Without having to re-render the complete code but only the part that you are working with.
import { useEffect, useState } from "react";
import { NextPage } from "next";
import Head from "next/head";
import Link from "next/link";
import HeroModule from "#modules/HeroModule";
import VideoModule from "#modules/VideoModule";
import ImageModule from "#modules/ImageModule";
import SliderModule from "#modules/SliderModule";
import QuoteModule from "#modules/QuoteModule";
import PreFooterModule from "#modules/PreFooterModule";
import Footer from "#components/Footer";
import Comments from "#components/Comments";
const Article: NextPage = () => {
const btnClass = "bg-transparent";
const text = "Reactie plaatsen";
const [buttonActive, setButtonActive] = useState(btnClass);
const [buttonText, setButtonText] = useState(text);
const [openForm, setOpenForm] = useState(false);
const onToggleForm = () => {
setOpenForm(!openForm);
if (!openForm) {
setButtonText("Sluiten");
setButtonActive("bg-navyBlue text-white");
} else {
setButtonActive("bg-transparent text-navyBlue");
setButtonText(text);
}
};
return (
<>
<Head>
<title>Artikel Detail</title>
<meta name="author" content="" />
<meta name="description" content="Developed by Friends For Brands" />
<link rel="icon" href="/favicon.ico" />
</Head>
<HeroModule
title="De headline van deze tekstuele content"
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
/>
<div className="max-w-screen-xl px-6 pt-16 pb-12 mx-auto border-b-2 border-gray-300 lg:px-8 text-navyBlue ">
<div className="grid w-full grid-cols-12 gap-6">
<aside className=" lg:col-span-3 col-span-full">
<div className="grid grid-cols-12 lg:sticky lg:top-5 lg:block">
<div className="col-span-2 mb-4 avatar">
<div className="w-16 h-16 sm:h-20 sm:w-20 md:w-24 md:h-24 rounded-full ring ring-[#65c3c8] ring-offset-base-100 ring-offset-2">
<img src="https://i.pravatar.cc/300" alt="" />
</div>
</div>
<div className="col-span-8 leading-2">
<p className="font-bold">John Doe</p>
<p>Marketing Manager</p>
<p className="mt-2 md:mt-6">00/00/0000</p>
<p>Leestijd 10 minuten</p>
<div className="mt-6 card-actions">
<Link href="/tag/fashion" passHref>
<span className="text-[11px] font-semibold uppercase cursor-pointer badge badge-outline hover:bg-navyBlue hover:text-white">
Fashion
</span>
</Link>
<Link href="/tag/products" passHref>
<span className="text-[11px] font-semibold uppercase cursor-pointer badge badge-outline hover:bg-navyBlue hover:text-white">
Products
</span>
</Link>
</div>
</div>
</div>
</aside>
<main className="leading-relaxed col-span-full lg:col-span-9 md:text-normal">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</p>
<h2 className="mt-3 text-3xl md:text-4xl">Heading 2</h2>
<h3 className="mt-3 text-2xl md:text-3xl">Heading 3</h3>
<h4 className="mt-3 text-xl md:text-2xl">Heading 4</h4>
<ul className="pl-6 my-4 list-disc">
<li>Lorem ipsum dolor sit amet</li>
<li>
Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore
</li>
<li>Et dolore magna aliqua. Ut enim ad minim veniam</li>
<li>
Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.
</li>
</ul>
<h2 className="mt-6 text-3xl md:text-4xl">H2: Tussentitel</h2>
<ul className="pl-6 my-4 list-decimal">
<li>Lorem ipsum dolor sit amet</li>
<li>
Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore
</li>
<li>Et dolore magna aliqua. Ut enim ad minim veniam</li>
<li>
Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.
</li>
</ul>
<h5 className="font-bold">Tussentitel paragraaf</h5>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</p>
<h3 className="mt-6 text-2xl md:text-3xl">H3: Video Module</h3>
<VideoModule id="mkggXE5e2yk" platform="youtube" />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</p>
<h3 className="mt-6 text-2xl md:text-3xl">H3: Image Module</h3>
<ImageModule
url="https://images.pexels.com/photos/1193743/pexels-photo-1193743.jpeg"
caption="Photo of multicolored abstract painting"
alt="A Pexels image"
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</p>
<h3 className="mt-6 text-2xl md:text-3xl">H3: Slider Module</h3>
<SliderModule />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</p>
<h3 className="mt-6 text-2xl md:h2text-3xl">H3: Quote Module</h3>
<QuoteModule />
</main>
</div>
</div>
<div className="w-full max-w-4xl px-4 py-20 mx-auto">
<div className="flex gap-4">
<h2 className="text-4xl">Comment Module</h2>
<button
onClick={onToggleForm}
className={`items-center justify-center px-4 py-2 text-xs font-medium uppercase transition duration-150 ease-in-out ${buttonActive} border rounded-full shadow-sm cursor-pointer border-navyBlue place-self-start sm:mt-0 hover:border-transparent hover:bg-navyBlue hover:text-white`}
>
{buttonText}
</button>
</div>
{openForm && <p>OPEN</p>}
</div>
{/* <Comments isOpen={openForm} toggleForm={onToggleForm} /> */}
<PreFooterModule />
<Footer />
</>
);
};
export default Article;
You can wrap onToggleForm in useCallback to memoize it. Then that function won't be recreated with every render. Also, be aware that using react strict mode will purposely double render to help you catch any side effects (a good thing and only happens in debug). So you can temporarily remove the <React.StrictMode> tags and see if your console.logs() stop doubling up.

Using React Hooks to filter the posts by date before mapping through the posts - How to?

I am using React Hooks and have a dummy content array of comments which I am mapping through to display it. Now, I am directly mapping through that array, but I would like filter => map before returning the output.
The hook from main file:
const [articleComments, setArticleComments] = useState([
{
name: "John Doe",
publishedAt: "22.03.2022",
image: "https://i.pravatar.cc/300",
post: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
},
{
name: "Jane Doe",
publishedAt: "03.01.2022",
image: "https://i.pravatar.cc/301",
post: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
},
{
name: "Jack Doe",
publishedAt: "17.03.2022",
image: "https://i.pravatar.cc/302",
post: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
},
]);
Comments.tsx:
const Comments = () => (
<div className="w-full px-4 pb-16 pr-4 mx-auto mt-5 md:pt-2 md:max-w-4xl">
<div className="flex flex-col gap-8 leading-relaxed text-md text-navyBlue">
{articleComments.length > 0 &&
articleComments.map(({ image, name, publishedAt, post }: any) => (
<div key={name} className="grid grid-cols-12 gap-4">
<div className="col-span-2 md:col-span-1 avatar">
<div className="w-12 h-12 rounded-full ring ring-[#65c3c8] ring-offset-2">
<img src={image} alt="" />
</div>
</div>
<div className="relative md:-mt-2 col-span-full md:col-span-11">
<h4 className="font-bold">{name}</h4>
<time>{publishedAt}</time>
<p className="mt-2">{post}</p>
</div>
</div>
))}
</div>
</div>
);
export default Comments;

What is the best way to present long texts with titles and subtitles?

I am having a bit of an impasse here about my small project.
I am working on an easy application where people can click on topic titles and read instructions on different topics. I have a long text file that goes like this:
How deep is the ocean
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Facts about dinasours
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
What is the best way to store this data and retrieve in my screen? Should I keep them in seperate txt files, save in database, or define in a file as a const and call with a function? Which one would work faster, properly, and securely?
Thank you for any answer in advance.

How to show message after a while in angular

I use from ng-class for div because I want to show message after a while when if is true but delay opacity dose not work . what do yo do ?
this is html
<div class="list" ng-show="item.collapsed == true" ng-class="{'panel-details':item.collapsed == true}">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
</div>
this is css
.list {
opacity: 0;
transition: opacity 1s ease-in !important;
}
.panel-details {
opacity: 1;
}
try this
setTimeout(function(){
$('#list').fadeIn(500);
}, 5000);
And do not use opacity but rather the display property

AngularJS - Sliding Effect On ng-click

I have created a simple ng-click function that hides and shows a DIV.
However, rather and simply appearing and disappearing, does angular have the ability to give a sliding effect?
Here's a plunkr: http://plnkr.co/edit/jbHidL3oOQvi4RBCkJIF?p=preview
HTML:
<div class="grid-wrap">
<div class="grid-col one-third">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
Show the slidy section
</div>
<div class="grid-col two-thirds" ng-show="showMe">
My hidden section that i want to slide out
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis irure dolor in repr</p>
</div>
</div>
You should have a good read about ng-animate (it have to be injected into your app - something a lot of ppl forget) then you can take a look here
http://www.nganimate.org/angularjs/ng-switch/slider-css3-transition-animation
a well designed examples of what ng-animate can do
Google CDN angularjs-animate.min.js

Resources