So,
I'm trying to come up with a way to dynamically load content into multiple tabs, where each tab can contain anywhere from one to several elements (reports).
Currently, the reports are loaded on page load with jQuery $.load. I'm using Bootstrap and bootstrap tabs. I found a site that teaches how to load multiple tabs, but not specifically what I need to do. That site is here: http://www.mightywebdeveloper.com/coding/bootstrap-2-tabs-jquery-load-content/
In contrast, each tab is set up more like this:
<div id="tab1">
<div id="report1"></div>
<div id="report2"></div>
</div>
I cannot use the top-level div to load the content, because it will potentially have multiple children. I need to loop through the div's, use regex to parse the ID, and load each report when the tabs are changed.
I haven't yet figured out the regex expression, but it should be fairly simple - the element id will be something like this : "#be78f5aa3-25". This is an alphanumeric 9-character dbid, followed by a hypen, followed by a 1-3 digit integer (not starting in 0). Then I need to split those two strings into separate variables and inject them into an API call.
Anyone looking to load multiple pages into bootstrap tabs may find this of use. I was able to get it working using some regex (specific to my application), placing div's within the tab-pane container's that had an Element Id which could be used to create the report I wanted to load into the container using $.load. I also added a few things for persistent tabs when the user went to another page and then used the back button, and another condition to load the content in the first tab if there was no hash in the URL.
I'm sure it could be cleaned up, but you get the gist..
$(function() {
"use strict";
var baseURL, $navbox;
baseURL = window.location.protocol + "//" + window.location.hostname + "/db/";
$navbox = $("#myTabs");
$navbox.bind("show", function(e) {
var contentID, pattern, selectDiv;
pattern = /#(\Btab|tab\B)?(\Bdropdown|dropdown\B)?([1-9]{1}[0-9]*)/i;
contentID = e.target.toString().match(pattern)[0];
selectDiv = contentID + " > div";
return $(selectDiv).each(function() {
var parts = this.id.match(/(##enter regex here)/);
if (parts) {
$(this).load(baseURL + parts[0]);
return;
}
return $("#myTabs").tab();
});
});
if (window.location.hash) {
$('#myTabs').find('a[href="'+window.location.hash+'"]').tab('show');
}
else {
var elemID = "#"+$('[class^="tab-pane active"]').attr('id') + " > div";
$(elemID).each(function() {
var parts = this.id.match(/(##enter regex here)/);
$(this).load(baseURL + parts[0]);
return $("#myTabs").tab();
});
}
});
$('#myTabs a').click(function (e) {
e.preventDefault();
var bob = jQuery(this).attr("href");
bob = jQuery.trim(bob);
if(bob == "" || bob == "javascript:void(0)") {
return;
}
else {
window.location.hash = $(this).attr('href');
$(this).tab('show');
}
});
Related
I have a significant amount of external links on my website in this format:
website.com/product/[variable]
I need these links to somehow pass through “myaffiliatelink.com” before being redirected to website.com/product/[variable].
Is this possible using .htaccess or Javascript?
I looked into using .htaccess, but seems I would need to do this individually. Is there a way to set a rule such that any external link using "website.com/product/[variable]" should pass through "myaffiliatelink.com" first?
// catch every click on the page
document.addEventListener("click", e => {
const target = e.target;
if (target.tagName === 'A' && target.href.indexOf("website.com") !== -1) {
// prevent the <a> tag from navigating
e.preventDefault();
const lastSlash = target.href.lastIndexOf('/');
if (lastSlash > 0) {
const variable = target.href.substring(lastSlash + 1);
// use the commented code below, or a window.open
//location.href = "https://myaffiliatelink.com/"+variable;
// for demonstration
console.log("https://myaffiliatelink.com/" + variable);
}
}
})
Product
<p>should pass through "myaffiliatelink.com"</p>
I am new at AJAX and JQuery and trying to use them in the part of my website. Basically the website that I have, has this kind of design and currently it is functional (Sorry for my poor paint work :)
The items in the website are created by user. This means item number is not constant but can be fetched by db query.
Each item has a unique URL and currently when you click an item, all page is refreshing. I want to change the system to let the user have a chance to navigate quickly between these items by only chaning middle content area as shown above. However I also want to have a unique URL to each item. I mean if the item has a name like "stack overflow", I want the item to have a URL kind of dev.com/#stack-overflow or similar.
I don't mind about the "#" that may come from AJAX.
In similar topics I have seen people hold constant names for items. For instance
<a href="#ajax"> but my items are not constant.
WHAT I HAVE TRIED
Whats my idea is; while fetching all item's links, I'm holding links in $link variable and using it in <a href="#<?php echo $link; ?>">.
Inside $link it is not actual URL. it is for instance a name like "stack-overflow" as I ve given example above. Until this part there is no problem.
PROBLEM
In this topic a friend suggested this kind of code as an idea and I ve changed it for my purpose.
<script>
$(document).ready(function() {
var router = {
"<?php echo $link ?> ": "http://localhost/ajax_tut/link_process.php"
};
$(window).on("hashchange", function() {
var route = router[location.hash];
if (route === undefined) {
return;
} else {
$(".content-right").load("" + route + " #ortadaki_baslik");
}
});
});
</script>
I'm trying to post the value of $link to the link_process.php and at link_process.php I will get the value of $link and arrange neccessary page content to show.
The questions are;
- How should I change this code to do that?
- I couldnt see someone doing similar to take as an example solve this
issue. Is this the right way to solve this situation?
- Do you guys have a better solution or suggestion for my case?
Thanks in advance.
WHEN your server side AJAX call handler [PHP script - handling AJAX requests at server side] is constant and you are passing item_id/link as GET parameter...
For example:
localhost/ajax_tut/link_process.php?item_id=stack-overflow OR
localhost/ajax_tut/link_process.php?item_id=stack-exchange
Then you can use following code.
<script>
$(document).ready(function() {
var ajax_handler = "localhost/ajax_tut/link_process.php?item_id=";
$(window).on("hashchange", function() {
var route = location.hash;
if (route === undefined) {
return;
} else {
route = route.slice(1); //Removing hash character
$(".content-right").load( ajax_handler + route );
}
});
});
</script>
WHEN you are passing item_id/link as URL part and not parameter...
For example:
localhost/ajax_tut/stack-overflow.php OR
localhost/ajax_tut/stack-exchange.php
Then you can use following code.
<script>
$(document).ready(function() {
var ajax_handler = "localhost/ajax_tut/";
$(window).on("hashchange", function() {
var route = location.hash;
if (route === undefined) {
return;
} else {
route = route.slice(1); //Removing hash character
$(".content-right").load( ajax_handler + route + ".php");
}
});
});
</script>
WHEN Your server side AJAX handler script url is not constant and varies for different items...
For example: localhost/ajax_tut/link_process.php?item_id=stack-overflow OR localhost/ajax_tut/fetch_item.php?item_id=stack-exchange OR localhost/ajax_tut/stack-exchange.php
Then I suggest to change PHP script which is generating item's links placed on left hand side.
<?php
foreach($links as $link){
// Make sure that you are populating route parameter correctly
echo '<a href="'.$link['item_id'].'" route="'.$link['full_ajax_handler_route_url_path'].'" >'.$link['title'].'</a>';
}
?>
Here is Javascript
<script>
$(document).ready(function() {
var ajax_handler = "localhost/ajax_tut/"; //Base url or path
$(window).on("hashchange", function() {
var route = location.hash;
if (route === undefined) {
return;
} else {
route = route.slice(1); //Removing hash character
route = $('a [href="'+.slice(1)+'"]').attr('route'); //Fetching ajax URL
$(".content-right").load( ajax_handler + route ); //Here you need to design your url based on need
}
});
});
</script>
www.baxter.com source page, shows most of the href links starting with the word baxter, like this -
href="/baxter/corporate.page?">About Baxter<
So the way I can construct an absolute url from the above is by combining the base url, www.baxter.com and the relative url /baxter/corporate.page?giving me www.baxter.com/baxter/corporate.page? which results in 404, cause the actual url is www.baxter.com/corporate.page?
I know how to generally parse relative URLs in PHP but is there a way to sense and remove words from relative urls like these?
Also mouseover on About Baxter on www.baxter.com web page displays the correct url, www.baxter.com/corporate.page? at bottom left of the page - where is this coming from? can it be accessed?
Will deeply appreciate any help/pointers...
EDIT on Nov 7:
In main.js, they are removing /baxter:
var fixer = function() {
var init = function() {
var digitasFinder = /(proto)|(cms-)|(teamsite-)/
, baxterFinder = /(\/baxter\/)/
, $allAnchors = $("a")
, $allForms = $("form");
digitasFinder.test(location.host) || ($allAnchors.each(function() {
var $this = $(this)
, actualHref = $this.attr("href");
if (baxterFinder.test(actualHref)) {
var newHref = actualHref.replace(baxterFinder, "/");
$this.attr("href", newHref)
}
}
),
$allForms.each(function() {
var $this = $(this)
, actualAction = $this.attr("action");
if (baxterFinder.test(actualAction)) {
var newAction = actualAction.replace(baxterFinder, "/");
$this.attr("action", newAction)
}
}
))
}
;
return {
init: init
}
}
Looks like some JavaScript executed on page load is modifying the hrefs of the links.
You could try duplicating the effects of the JS code (ie. remove '/baxter' from the links), or for a more generic solution, you could use a headless browser to execute the JS code and then evaluate the resulting DOM. Look into the Mink project for a PHP-based solution.
I'm trying to create a tabbed area within my page. The tabs navigate hidden areas with out leaving the page. I also want to be able to link to an area with in the page. It's working except when you click the menu as well as revealing the hidden area it's rewriting the URL with only the tab extension and therefor breaking the link of the URL. So someone trying to share the link would not know the format..
I'm using this code https://css-tricks.com/examples/OrganicTabsReplaceState which I see no problem with.
You can see a live demo with my issue here: http://bit.ly/1IP1ST4
Clicking the tab is removing:
/products/eurorack-modules/waveform-modifiers/reactive-shaper/
And replacing it with ?tab=mytabname
It should be simply adding it. I'm struggling to work out why..?
If you inspect the source of the first link you provided, you will see that the tabs contain links like this:
Featured
That's an in-page link. You should use #'s for in page links. The reason the whole url is being replaced is because it's interpreting the href as a new url to go to. #'s look inside the current page.
This version of organictabs.jquery.js got it working in the end seemed to be an issue with the way it treated the URL.. Maybe this will help someone else.
// IIFE
(function($) {
// Define Plugin
$.organicTabs = function(el, options) {
// JavaScript native version of this
var base = this;
// jQuery version of this
base.$el = $(el);
// Navigation for current selector passed to plugin
base.$nav = base.$el.find(".nav");
// Returns the fragment identifier of the given URL
function getFragmentIdentifier(url) {
if(url && url.match && url.match(/#(.*)/)) {
return RegExp.$1;
}
}
// Remove the query string from the url
function noQueryString(url) {
if(url && url.match && url.match(/^([^\?]*)\??/)) {
return RegExp.$1;
}
}
// Runs once when plugin called
base.init = function() {
// Pull in arguments
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix (hmmm, re-look at this, screen readers still run JS)
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
// When navigation tab is clicked...
base.$nav.delegate("a", "click", function(e) {
// no hash links
e.preventDefault();
// Figure out current list via CSS class
var curList = getFragmentIdentifier(base.$el.find("a.current").attr("href")),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = getFragmentIdentifier($newList.attr("href")),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
}, base.options.speed);
// Remove highlighting - Add to just-clicked tab
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
// Change window location to add URL params
if (window.history && history.pushState) {
// NOTE: doesn't take into account existing params
history.replaceState("", "", noQueryString(window.location.href) + "?" + base.options.param + "=" + listID);
}
});
}
});
var queryString = {};
window.location.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
if (queryString[base.options.param]) {
var tab = $("a[href='#" + queryString[base.options.param] + "']");
tab
.closest(".nav")
.find("a")
.removeClass("current")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#" + queryString[base.options.param]).show();
};
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300,
"param": "tab"
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
I'm trying to set up a website that loads pages through ajax calls replacing the current contents of with the ajax response. I'm putting a # and a page name at the end of my URLs so that people can book mark pages.
www.examplesite.com#home
www.examplesite.com#examples
www.examplesite.com#examples/example1
www.examplesite.com#examples/example2
I'm new to jQuery and to a lesser extent JavaScript but I'm trying to get a different page animation when I go to a page that is stored in a sub folder. fadeIn() works fine on both pages and pages in sub-folders however I can't get .slideDown() or .animate() to work at all. Here is an extract from my code:
<script>
//All pages are stored in a folder called 'pages' or a subfolder of 'pages'
$(document).ready(function(){
var myUrl = $(location).attr('href');
var noPage = myUrl.indexOf('#');
if(noPage == -1) {
location.hash = 'home';
}
window.onhashchange = function() {
pageChange();
}
function pageChange() {
var myUrl = $(location).attr('href');
var page = myUrl.substring(myUrl.indexOf('#') + 1, myUrl.length);
$.get('pages/' + page + '.html', function(pageHtml) {
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).slideDown(400);
} else {
$('.main').hide().html(pageHtml).fadeIn(400);
}
});
};
pageChange();
});
</script>
If I'm approaching this from completely the wrong direction and that's why it's not working do feel free to point me in the correct direction by giving me an example of how it should work.
Got it!
I was using the css min-height property with a couple of my divs so that the page would expand automatically with the content if there was a lot on the page. If I remove the min-height property and replace it with a fixed height .slideDown() works fine.
Here are some links for more info if anyone else has the same issue:
http://www.only10types.com/2011/09/jquery-slidedown-doesnt-work-on.html
http://docs.jquery.com/Tutorials:Getting_Around_The_Minimum_Height_Glitch
I would take this...
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).slideDown(400);
} else {
$('.main').hide().html(pageHtml).fadeIn(400);
}
And rearrange it to make sure your if statement is correct
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).fadeIn(400);
} else {
$('.main').hide().html(pageHtml).slideDown(400);
}
If it now slides instead of fades, the if statement is corrupt
What about this ? Does this work ?
var main_div=$('.main');
main_div.hide();
$.get('pages/' + page + '.html', function(pageHtml) {
if (page.indexOf('/') != -1) {
main_div.html(pageHtml)
} else {
main_div.html(pageHtml)
}
});
main_div.slideDown(400);
maybe something in the CSS must be blocking it ? try disabling the CSS for the main class and try again ?