Automatically selecting tab upon redirect - javascript

I am running a ruby on rails website and it currently supports javascript an jquery. I am using htmlslim, scss, and bootstrap.
I am wondering it if is possible to have a button or link that sends a user to another page, then automatically clicks on a tab on that page.
For instance I have a page with the following compiled html:
...
<div class="row">
<ul class="nav nav-tabs profile-tabs" id="userTabs">
<li class="active" id="userItems" role="presentation">
<a data-toggle="tab" href="#items" role="tab">
<span class="key">Items</span>
<span class="value">13</span>
</a>
</li>
<li role="presentation">
<a class="stand-card-activate" data-toggle="tab" href="#people" role="tab">
<span class="key">People</span>
<span class="value">3</span>
</a>
</li>
</ul>
</div>
...
This is a row with 2 tabs and the Items tab is the tab that is by default selected when the user visits the page.
Is there some way to make a button that can link to this page and have the People tab automatically selected?
Here is the same code in slim:
...
.row
ul#userTabs.nav.nav-tabs.profile-tabs
li#userItems.active[role="presentation"]
a(href="#items" role="tab" data-toggle="tab")
span.key Items
span.value = #user.items.count
li(role="presentation")
a.stand-card-activate(href="#people" role="tab" data-toggle="tab")
span.key people
span.value = #people_count
...
EDIT 2:
Code so far:
slim:
a.back-to-user-people-btn.pull-left(href=www.yourpage.com/#people) Back to People
JS:
var hash= window.location.hash;
if(hash.length > 0 ) {
$('a[role="tab"]').parent().removeClass('active');//remove the default active tab
$('a[href="'+hash+'"]').parent().addClass('active');
}
This jquery allows it to have the correct tab name highlighted and "active" but the contents of the items tab is still the content that the user sees.
EDIT 3: Show tab contents slim code
.tab-content
#items.tab-pane.fade.active.in.col-md-12(arialabelledby="items" role="tabpanel")
.card-container = render partial: 'partials/item', collection: #user[:items], as: :user_item, locals: {user: #user}
#people.tab-pane.fade.active.in.col-md-12(arialabelledby="people" role="tabpanel")

Try something like this
a link should look like : www.yourpage.com/#tabhrefid
When the page is loaded it will take the hash from the url and add the class active to the tab witch has the link with the same href
$(function(){
var hash= window.location.hash;
if(hash.length > 0 ) {
$('a[role="tab"]').parent().removeClass('active');//remove the default active tab
$('a[href="'+hash+'"]').parent().addClass('active');
$('.tab-pane').removeClass('active');
$(hash).addClass('active');
}
});

Related

How to open specific Bootstrap tab by clicking on a link

I'm trying to add a Bootstrap tab panel goes like this:
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#tabs-1" role="tab">First Panel</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#tabs-2" role="tab">Second Panel</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#tabs-3" role="tab">Third Panel</a>
</li>
</ul><!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="tabs-1" role="tabpanel">
<p>First Panel</p>
</div>
<div class="tab-pane" id="tabs-2" role="tabpanel">
<p>Second Panel</p>
</div>
<div class="tab-pane" id="tabs-3" role="tabpanel">
<p>Third Panel</p>
</div>
</div>
Now I need to give link to users to see the panes like this:
https://sitename.com/page#tabs-2
But this won't work because the tab-pane with an id of tabs-2 does not have the .active class.
However, if I try loading https://sitename.com/page#tabs-1 The page properly redirects me to tab-pane with an id of tabs-1 (because it has .active class by default)
So how can I redirect users to different tab panes correctly?
You don't really need to check the fragment to switch between those tabs.
1) Import jQuery from here or:
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
2) Add this part to your code.
<script>
$(document).ready(function () {
$('.nav-tabs a').click(function () {
$(this).tab('show');
});
});
</script>
I already started answering your old question before you deleted it, but here is it again.
I didn't understood what you were trying to achieve, so I just looked into the code and made my version, its not the best but it works.
This is an onClick event handler, it gets executed on a click in your nav and changes the active classes.
// onClick event handler, gets executed on click
$(".nav-link").on("click", (e) => {
// store clicked element
const listItem = e.target;
// get hash
const hash = e.target.hash;
// remove all active classes
$(".nav-link, .tab-pane").removeClass("active");
// add active class to list item and tab panes
$(listItem).add(hash).addClass("active");
});
This part gets executed when you reload your page. You need to change your HTML for this to work, so remove the active class from nav-link and give every link an additional class (tabs-1, tabs-2 and tabs-3).
// when page is reloaded
$(document).ready(() => {
// get current hash
const hashList = window.location.hash;
const hashItems = hashList.slice(1);
// remove all active classes
$(".nav-link, .tab-pane").removeClass("active");
// add active class to nav-link and pane
$(hashList).add(`.${hashItems}`).addClass("active");
});
Both snippets need to be included in your script tag of course, also you need to import jQuery, if not already happened.

Highlight Button in Webpage If Login User Has not Clicked On

Looking for a way to highlight buttons that the User has not visited in case of changes the content of the views that are redirected when these buttons are clicked. The solution should be in the ASP.net MVC CSS framework.
<head>
<style type="text/css">
body{
overflow-x:scroll;
}
.auto-stylelay1 {
font-size: 18px;
text-align: left;
cursor: pointer;
}
</head>
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<li class="sidebar-brand" style="font-size: 22px">
<a href="#">
<strong>
</strong>
</a>
</li>
<b></b>
<p class="auto-style2"><strong>Hello #User.Identity.Name!</strong></p>
<li class="auto-stylelay1">#Html.ActionLink("Home", "Index", "Home")</li>
<li class="auto-stylelay1">#Html.ActionLink("Proof of Concept", "POC", "Home")</li>
<li class="auto-stylelay1">#Html.ActionLink("Reports", "report", "Home")</li>
<li class="auto-stylelay1">#Html.ActionLink("Links/Other Resources", "Links", "Home")</li>
<li class="auto-stylelay1">#Html.ActionLink("About", "About", "Home")</li>
<li class="auto-stylelay1">#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
I would like to change the layout style page buttons for the menu bar in case the user has not clicked. I have added a check to see where the user has browsed. As well as the date they have browsed in. But I am missing the code to do changes to the shared layout file per user.
I expect the button to be highlighted with some new content indicator. Basically I want to change class styles for the li html action links depending on whether the user visited this page or not. If the button is clicked I want to return the class to auto-stylelay1.
A possible solution would be to save it in the local storage.
First assign an id to each list item:
<li id="Home" class="auto-stylelay1">#Html.ActionLink("Home", "Index", "Home")</li>
<li id="POC" class="auto-stylelay1">#Html.ActionLink("Proof of Concept", "POC", "Home")</li>
<li id="Reports" class="auto-stylelay1">#Html.ActionLink("Reports", "report", "Home")</li>
If a button is clicked add it to an array and save it to the local storage:
$("a").on("click", function (e) {
e.preventDefault(); // stop following link
var retrievedDate = localStorage.getItem("buttonsClicked");
var buttonsClicked = JSON.parse(retrievedData);
var elementId = $(this).attr('id') // Get Id of element
buttonsClicked.push(elementId);
localStorage.setItem("buttonsClicked", JSON.stringify(buttonsClicked.push)); // save back
window.location = $(this).attr('href'); // now follow link
});
Now on view load you have to read and see which ones have been pressed:
$(document).ready(function() {
var retrievedDate = localStorage.getItem("buttonsClicked");
var buttonsClicked = JSON.parse(retrievedData);
// loop through array
buttonsClicked.each(function (index, value) {
$("#"+value).addClass("auto-stylelay1");
});
});
You can place the script inside the _Layout view.
Note: I haven't tested this. Let me know if it worked.

Is it possible to add links to bootstrap 4 nav-pills tab-panel from a different page?

I have a service page that using bootstrap 4's pills .nav-pills navigation (this is not the main navigation navbar), which is working very well. My challenge is that i want to be able to click on a link on the home page that should open the targeted tab-panel on the service page. Haven't been able to find a way for almost a week now. How can i achieve this?
Service.html
<div class="nav flex-column nav-pills col-md-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<ul class="list-group list-unstyled">
<li class="nav-item">
<a class="nav-link list-group-item" id="v-pills-manpower-tab" data-toggle="pill" href="#v-pills-manpower" role="tab" aria-controls="v-pills-manpower" aria-selected="false">Manpower Supply</a>
</li>
</ul>
</div>
<div class="tab-content col-md-8" id="v-pills-tabContent">
<div class="tab-pane fade" id="v-pills-manpower" role="tabpanel" aria-labelledby="v-pills-manpower-tab">
<h5>Man Power Supply</h5>
</div>
Home.html
<a href="services.html#v-pills-manpower" data-toggle="tab" >
My code in home.html doesn't work but that's one of my many attempts.
On the home page, configure data attributes to help. I've added data-tab-name to the anchor and it defines the desired, selected tab for the service page.
When the page loads, it re-configures the onclick of the link so that the tab name can be stored in localStorage before redirecting the user to the service page.
Home.html
<a href="services.html" data-tab-name="v-pills-manpower" data-toggle="tab" >
<script type="text/javascript">
window.onload = function() {
document.querySelectorAll('[data-toggle="tab"]').forEach(function(item, index){
item.addEventListener('click', function(e){
e.preventDefault();
localStorage.selectedTabName = item.getAttribute('data-tab-name');
window.location.href = item.href;
});
});
};
</script>
When the service page loads, the javascript looks for the saved tab name in localStorage, identifies that tab and then makes it the active tab by applying the "active" class to the appropriate element.
Service.html
<script type="text/javascript">
window.onload = function() {
document.querySelectorAll('.nav-link').forEach(function(item, index){
var isActive = (item.className.indexOf('active')>-1);
if (item.id==localStorage.selectedTabName) {
if (!isActive) {
item.className += ' active';
}
item.setAttribute('aria-selected', 'true');
} else {
item.setAttribute('aria-selected', 'false');
if (isActive) {
item.className = item.className.replace('active', '');
}
}
});
};
</script>

How to keep tab active after postback ASP.Net Core

I have a View that contains a set of tabs each rendering a different partial view. After reading the documentation and W3Schools samples of these bootstrap tabs, I am unable to work out a way that makes the active tab remain active on Postback. All of the examples I've seen are using older versions of .Net and don't apply either.
Here is my code.
My controller action:
public IActionResult DisplayCharts(DashboardChartsByMonthModel model)
{
//...do stuff
model.MonthOrQuarterChart = monthChart;
model.UserChart = userChart;
return View(model);
}
Within the view #Scripts section:
<script>
$(function(){
var hash = window.location.hash;
hash && $('ul.nav a[href="' + hash + '"]').tab('show');
$('.nav-tabs a').click(function (e) {
$(this).tab('show');
var scrollmem = $('body').scrollTop() || $('html').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scrollmem);
});
});
</script>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab',
function(e) {
switch ($(e.target).attr('href')) {
case '#tab1':
drawMonthAndQuarterChart();
break;
case '#tab2':
drawUserChart();
break;
}
});
</script>
Within the body:
<ul class="nav nav-tabs" role="tablist" id="myTabs">
<li class="nav-item">
<a class="nav-link active" id="tab1-tab" data-toggle="tab" href="#tab1" role="tab" aria-controls="tab1" aria-selected="true">By Month & Quarter</a>
</li>
<li class="nav-item">
<a class="nav-link" id="tab2-tab" data-toggle="tab" href="#tab2" role="tab" aria-controls="tab2" aria-selected="false">By Leasing / Billing Rep</a>
</li>
<div class="tab-content" id="myTabContent">
<div class="tab-pane active" id="tab1" role="tabpanel" aria-labelledby="tab1-tab">
<form method="post">
...model fields, etc.
<button type="submit" class="btn btn-success">Submit</button>
<div id="chart_monthandquarter_div"></div>
</form>
<div class="tab-pane" id="tab2" role="tabpanel" aria-labelledby="tab2-tab">
<form method="post">
....
</form>
And the same would go on for tab 2, tab 3, etc. Each tab has its own form with its own button that submits the model and when the page reloads after submit, I can swap between both tabs and see my charts rendering just fine however it keeps making the first tab active any time I post.
One of the several things I've tried was working out some of the older examples with a hidden field that I've seen some people use but I was unable to get that to work.
So with the code presented, how can I make it so that the current tab that you are viewing when you click submit is the one that's active on postback?
When user submits a form, you should follow the P-R-G pattern. So after saving, you should return a redirect response which issue a totally new GET request to load the page from scratch.
When issuing the redirect response, you can add a querystring speciific to the tab you want to select. For example, for the below sample markup, you can send the href value without the # as the querystring value and in the view read this querystring value and set to a js variable. In the document ready event, you can explicitly enable the tab you want with that.
<ul class="nav nav-tabs" role="tablist" id="myTabs">
<li role="presentation" class="active">Home</li>
<li role="presentation">Profile</li>
<li role="presentation">Messages</li>
<li role="presentation">Settings</li>
</ul>
And in your HttpPost action
public IActionResult UpdateProfile(YourViewModel model)
{
// to do :Save
return RedirectToAction("Index", new { t = "profile" });
}
And in the view, you inject IHttpContextAccessor implementation so that we can access Request and then querystrings
#inject IHttpContextAccessor HttpContextAccessor
<!-- your code for the tabs goes here-->
<script>
$(function() {
var t = '#HttpContextAccessor.HttpContext.Request.Query["t"]';
if (t.length) {
$('#myTabs a[href="#' + t + '"]').tab('show');
}
});
</script>

Link to Jquery Tab does not work

I am working on a L5 project and i am using a Jquery tab for one of its pages. I have a little menu for reaching tab contents without clicking just tabs.
<div id="aracislem" class="panel-collapse collapse">
<div class="panel-body">
<ul>
<li>Araç Arama </li>
<li>Araç Kayıt </li>
<li>İstatistik </li>
<li>Araç Takibi </li>
</ul>
</div>
</div>
Any my tab is
<script type="text/javascript">
$(document).ready(function () {
$('#tab-container').tabs({
active: $.cookie('activetab'),
activate: function (event, ui) {
$.cookie('activetab', ui.newTab.index(), {
expires: 10
});
}
});
});
</script>
<div id="tab-container" class='tab-container'>
<ul>
<li class='tab'>Araç Arama</li>
<li class='tab'>Araç Kayıt</li>
<li class='tab'>İstatistik</li>
<li class='tab'>Araç Takip</li>
</ul>
<div class='panel-container'>
<div id="aracaramatab">
Araç Arama
</div>
<div id="arackayittab">
Araç Kayıt
</div>
<div id="istatistiktab">
İstatistik
</div>
<div id="aractakiptab">
Araç Takip
</div>
</div>
</div>
When i clik to menu links i cant reach to necessary tab, link changes in the browser but does not redirect to tab also when i click to tabs, content changes but links do not change. Anybody knows what am i doing wrong ?
Check this DEMO : http://jsfiddle.net/yeyene/mktgnp3e/1/
Your problem is when you click link and after going to link (it will redirect a different page?), want to active the tab, right?
So get the url first, then get the hash, then do the active tab step.
JQUERY
$(document).ready(function () {
$("#tab-container").tabs({});
// for testing purpose
var url = "http://localhost/pages/aracislemler#arackayittab";
// use this script for getting url
//var url = window.location.href;
var hash = url.substring(url.indexOf('#'));
// trigger click to tab with url hash name
$('#tab-container a[href='+hash+']').trigger('click');
});
*Use the line var url = window.location.href; for your app, then take out the current url getting test variable.

Categories