router for routing purpose in my react app.
Mine routing is defined in given manner:
<Route path={food/:cuisine/:pageNo} component={foodList}
and my navBar have following navigation:
<Link to={"/food/italian/1"} activeClassName="active">Italian</Link>
<Link to={"/food/indian/1"} activeClassName="active">Indian</Link>
but when visit page no. 2("/food/indian/2") of that component then myActive class of navBar is not showing.
If there are any alternate method to solve this problem then it will be great.
Thanks.
PS: I don't want to put all conditions like because the app has more than 15 different cuisine
if(this.props.params.cuisine=="Indian){
//then add .active in my Link to class
}
=======
just use conditional javascript for given case.
like :
if(this.props.params.cuisine=="Indian){
//then add .active in my Link to class
}
it will work perfectly for you. activeClass will compare whole route path and if it's true then they will add class active.
Alternate option: If u can create a constant value using splice function of javascript to get ur suffix of url .
then create two variable.
for example:
var indianPrefix= "/food/indian/"+ urlSuffix;
var italianPrefix= "/food/italian/"+ urlSuffix;
then use:
<Link to={italianPrefix} activeClassName="active">Italian</Link>
<Link to={indianPrefix} activeClassName="active">Indian</Link>
bug: By using this method on clicking the tab you will be landing on the same page always.
Thanks.
Related
I'm trying to use media queries and javascript to make a dropdown menu for my page. I have the content i want to be in the menu in a <div> marked with a class, in this case. class="other-pages". My media query has 2 classes in it: .other-pages.closed and .other-pages.open. My goal is to use javascript to change the class once the media query is active to the closed class. Then make a button i have, change the class to the open version.
So here's what I have so far.
let menuContentBase = document.getElementsByClassName('.other-pages');
let mediaQueryMax = window.matchMedia('(max-width: 1080px)');
if (mediaQueryMax.matches) {
menuContentBase.classlist.remove('.other-pages');
menuContentBase.classlist.add('other-pages.closed');
}
When I load this into my browser and look in the debugger however it says menuContentBase.classlist is undefined.
Not entirely sure what to do from here.
Thank you for any advice/recommendations you may have.
Its a simple toggle
let element = document.querySelector(".mq-value")
element.addEventListener('click', (e)=>{
e.target.classList.contains('open') ?
e.target.classList.remove('open') :
e.target.classList.add('open')
})
.open{
color:red
}
<div class="mq-value open"> toggle </div>
I think the issue is in the class name. When it comes to document.getElementsByClassName, you don't need to put . before the class name. Replae this
let menuContentBase = document.getElementsByClassName('.other-pages');
with this
let menuContentBase = document.getElementsByClassName('other-pages');
If you want further information about this, you can refer https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Also, same for classList not classlist and the L must be uppercase.
if (mediaQueryMax.matches) {
menuContentBase.classList.remove('other-pages');
menuContentBase.classList.add('other-pages.closed');
}
Try this one and let me know if it's works or not. Thank you!
I have been working on a sveltekit application and recently ran into an issue with my main navigation menu. when the application is loaded or refreshed the current menu item that corresponds with the current URL is not set to active. (i.e. menu item 'Home' would have URL of '/') I had a hard time finding anything useful online demonstrating how to set this up, but I have a working solution and thought I'd document it for others. It is very simple at the moment.
I have a nav.json file where I define any menus within my application, making it easy to organize menus. I import that at the top of the file and store it in an array for use later.
import menuObj from '../nav/nav.json';
let sidebar = menuObj.menus[0].items;
onMount() is just getting the current path when the nav component is loaded, and only runs once for me.
then - using <svelte:window on:click={handlePageClick}/> we can listen to any clicks on the page.
In the handlePageClick(e) method we pass the on:click event. Using that event we can capture the current pathname of the URL. this allows us to check the pathname against our item.path which is defined in the nav.json file I've imported and extracted using the #each method in our html. On the <a> we can set the class to active if the items route matches the current path.
here is the full implementation
<script>
import menuObj from '../nav/nav.json';
import {onMount} from "svelte";
let path;
let sidebar = menuObj.menus[0].items;
onMount(() => {
path = window.location.pathname;
})
function handlePageClick(e) {
path = e.view.location.pathname;
}
</script>
<svelte:window on:click={handlePageClick}/>
<nav class="sidebar">
{#each sidebar as item, i}
<a href={item.route} id="sidebar-menu-item-{item.id}"
class={path === item.route ? "item active" : "item"}
>
<i id="sidebar-menu-item-{item.id}-i" class="{item.icon}"></i>
</a>
{/each}
</nav>
I haven't found any drawbacks to this yet. I will update this question if I find anything.
It's not really a question, but I will add an answer anyway because your method is not necessary, SvelteKit already has a built in system for this:
<script>
import { page } from '$app/stores';
</script>
<a href={item.route} class="item" class:active={$page.url.pathname == item.route}>
...
</a>
page is a store like object that among other things hold the current path, it will automatically be updated with the new path
as a bonus:
class:active is an easy shorthand, removing that ternary expression there.
I'm having some real trouble setting up a react router and would really appreciate some suggestions. I have an app with multiple pages, and i want the app to display the page i'm on in url and be able to go to specific page through url. But i just cant seem to get it working.
The route path is:
<Route path="/page/{:id}" component={Body} />
It's calling Body, which is my main Class component where most of the code and logic is. But most of the threads and tutorials i've seen use either useEffect or useParams, which can't be done in a class component.
The app is simple, all it does is change between pages and calls api on every page to get different text and button numbers.
So what i'm doing now is i have a Link tag wrapped around my buttons with page numbers <Link key={index} to={`/page/${links.label}`}>. Those buttons are in a seperate function component. And i see the change in url based on which page i'm on. But i want to set it up so i can type the url directly.
buttons:
const renderPageNumbers = apiPagingSliced.map((links, index ) => {
return <Link key={index} to={`/page/${links.label}`}>
<button key={index} id={links.label}
onClick={props.handleClick}
>{links.label}
</button>
</Link>
})
and it just seems very incomplete. I tried using useParams, but couldn't get it to work.
Add this into your Body Component so when id param change your page get update and update your localStorage too
componentDidUpdate(prevProps, prevState, snapshot){
if(prevProps){
if(prevProps.match.params.id !== this.props.match.params.id){
const id = this.props.match.params.id;
localStorage.setItem("currentPage", id)
this.setState ({
currentPage: id});
this.fetchApi(id);
}
}
}
I am using two buttons to toggle css classes that either show or hide a background. I would like to save the current state of each class in local storage and display (or not display) them when the user returns. I have made an attempt with the wrapping class in this jsFiddle, but I don't have it working yet:
http://jsfiddle.net/eqrk6fak/1/
Setting it like so:
$("#switch2").click(function() {
wrap.fadeToggle(600);
if($('div').hasClass(wrap)){
localStorage.setItem('background', wrap);
}
});
And then trying to get it when the user returns:
$(document).ready(function(){
var background = localStorage.getItem('background');
if(background !== ''){
$('#wraping').addClass(background);
}
});
Any help would be appreciated. Thanks!
The problem is in the following line:
$('div').hasClass(wrap)
Reviewing your JSFiddle code, at that point wrap is a jQuery result:
var wrap = $(".wraping");
According to the documentation, jquery.hasClass receives a className which should be a String.
is it possible to place a button in TabContainer header on the left side ?
I want to place it next to First Tab.
Thanks for help :)
You are going to have to create your own tab controller widget. The steps would be as follows:
Create MyTabController that extends dijit.layout.TabController
Create a template for MyTabController that has a place for the button
Update MyTabController javascript to create the button
You can use your new controller widget in one of two ways. If it were me, I'd also create my own tab container widget that extends dijit.layout.TabContainer and overrides the _makeController function to instantiate the new controller.
Alternatively, you could pass in the _makeController function when instantiating the TabContianer widget
var tc = new dijit.layout.TabContainer({
_makeController: function(srcNode) {
...
}
}, node);
You can look at the dijit.layout.TabContainer source to see what needs to be done in the _makeController function.