JSFiddle - React, Tailwind, and code Playground
HTML
<button value="tab1View" class="tabButton current" id="tab1Tab">Tab 1</button>
<button value="tab2View" class="tabButton" id="tab2Tab">Tab 2</button>
<hr>
<div class="tabDiv" id="tab1View">This is tab 1
<br />There is a form on this tab. This form must be validated and submitted successfully before switching to tab 2.</div>
<div class="hidden tabDiv" id="tab2View">This is tab 2
<br/>The contents of this tab depend on the form in tab 1 having been successfully ssubmitted to the server.</div>
CSS
#tabs {
margin:0px;
padding:0px;
padding-bottom:-1px;
width:100%;
border-bottom:1px solid #C9C9C9;
margin-bottom:5px;
position:relative;
z-index:1;
}
.tabButton {
margin:0px;
margin-right:3px;
padding:5px;
border:1px solid #C9C9C9;
background-color:#EAEAEA;
background: linear-gradient(to top, #FFFFFF, #DBDBDB);
position:relative;
top:1px;
z-index: 2;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
button.tabButton:not(.current):hover {
background-color:#DFDFDF;
border-left-color: #878787;
border-top-color: #878787;
border-right-color: #878787;
}
.tabButton.current {
background-color:white;
border-bottom:1px solid white;
}
.tabBadge {
width:12px;
height:12px;
border:2px solid white;
padding:2px;
background-color:red;
color: white;
font-size: .75em;
position:relative;
left:-12px;
top:-10px;
text-align: center;
border-radius: 12px;
z-index:3;
}
.hidden {
display:none;
}
JavaScript
$(document).ready(function () {
$('.tabButton').click(changeTab);
//bind a "before show" function to tab 2
$('#tab2Tab').bind('beforeShow', tab2BeforeShow);
});
function changeTab() {
var jqButton = $(this);
if (jqButton.hasClass("current")) //don't do anything if switching to the current tab
return;
//run the "before show" function, if any.
var eventParams = {
promise: null
};
jqButton.trigger('beforeShow', eventParams);
function doShowTab(showTab) {
if (!showTab) //if no before show function, then showTab is null, not false
return; //if false, then don't show the tab.
$(".tabDiv").hide();
//run any "after hide" scripts bound to the current tab
$('.tabButton.current').trigger('afterHide');
var requestedDiv = jqButton.val(); //the "value" of the tab button is the ID of the tab content div
$("#" + requestedDiv).show(); //may show nothing, if no div exists for the current tab.
$(".tabButton").removeClass("current"); //remove the current class from all tab buttons, so it will only be applied to the new current tab button.
jqButton.addClass("current");
}
if (eventParams.promise) eventParams.promise.then(doShowTab);
else doShowTab(true);
}
function tab2BeforeShow(e, eventParams) {
// run some AJAX function here. In my case, this is a ajaxForm object submit.
// $('#SomeajaxFormObject').submit();
// The result of this AJAX function determines if this function should set
// the 'show' data of the tab to false, thereby preventing tab 2 from being shown
// See line 14.
// PROBLEM: this function returns immediately after calling the ajax function,
// and completing the rest of this function, but before the ajax success/failure callbacks.
// that would determine if the 'show' data should be set to false.
// Therefore the tab is ALWAYS shown, even if the result of the above submit is negative.
...