Does JavaScript have any functionality for building URLs? - javascript

I have an index view of cards (e.g. playing cards) laid out in a BootStrap grid. Each card is in a div, and I have a jQuery click handler for each div, to open a details page for any card (card div) that is clicked. So the redirect from the index to detail view is all accomplished using this (rather smelly) JavaScript:
var showDetail = function (index) {
const newUrl = "#($"http://{Model.HostName}{Url.Action("Details", "Card")}/")" + index;
window.location = newUrl;
};
I don't like to depend on the Razor code nugget to give me the hostname and the url's path. Does JavaScript have any functionality that I can use to achieve the same as the above dodgy code?

You can create create an anchor on the fly and read its href property.
console.log($('<a>', {
"href": '/test/for/relative/url'
}).prop('href'))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
And, Also URL API can be used.

Related

If user came from previous page on site then this, else do this

What would be a viable way to accomplish the following:
A website has two pages; Parent page and Inside page. If user came to the Inside page directly by typing in the address or by following a link from a page other than Parent page, then show "foo". If user came to the Inside page from the parent page, then show "bar".
I would need this done in JS if possible. If not, PHP is a secondary choice.
You can get the page the user came from with document.referrer.
So you could implement your solution like this:
if (document.referrer === 'yoursite.com/parentpage') {
// do bar
} else {
// do foo
}
Please try this
This code in second page
jQuery(window).load(function() {
if (sessionStorage.getItem('dontLoad') == null) {
//show bar
}
else{
//show foo
}
});
This code in parent page
jQuery(window).load(function() {
sessionStorage.setItem('dontLoad','true')
});
with php:
There is a simple way is to create a mediator page which redirect to inner page after make a session / cookie.. then if you'll get session / cookie, you show foo & unset session.
if someone directly come from url, no session / cookie found & it show bar..
You can use the document.referrer but this is not always set. You could add a parameter to the URL on the parent page and then check for its existance in the child page
Link on the parent page:
<a href='myChildPage.html?fromParent=1'>My Child Page</a>
JS code on your child page:
var fromParent=false;
var Qs = location.search.substring(1);
var pairs = Qs.split("&");
for(var i = 0; i < pairs.length; i++){
var pos = pairs[i].indexOf('=');
if(pos!==-1){
var paramName = pairs[i].substring(0,pos);
if(paramName==='fromParent'){
fromParent=true;
break;
}
}
}
if(fromParent){
alert("From Parent");
}else{
alert("NOT From Parent");
}
This method isnt 100% foolproof either as users could type in the same URL as your parent page link. For better accuracy check the document.referrer first and if not set use the method i've outlined above
intelligent rendering with jQuery
After using #Rino Raj answer, i noticed it needed improvement.
In javascript, the load() or onload() event is most times much slower,
since it waits for all content and images to load before executing your attached functions.
While an event attached to jQuery’s ready() event is executed as soon as the DOM is fully loaded, or all markup content, JavaScript and CSS, but not images.
Let me explain this basing, on code.
When i used #Rino Raj's code, with load() event, it works but on the second/called page, the content appears before class="hide fade" is added (which I don't really want).
Then i refactored the code, using the ready() event, and yes,
the content that i intended to hide/fade doesn't appear at all.
Follow the code, below, to grasp the concept.
<!-- Parent/caller page -->
<script type="text/javascript">
$(document).ready(function() {
sessionStorage.setItem('dontLoad', 'true');
});
</script>
<!-- Second/called page -->
<script type="text/javascript">
$(document).ready(function() {
if(sessionStorage.getItem('dontLoad') == null) {
$("#more--content").removeClass("hide fade");
} else {
$("#more--content").addClass("hide fade");
}
});
</script>

multiple instanced dynamic javascript popup link

I realize that this posting is possibly a repeat of this one:
Using Javascript to dynamically create links that trigger popup windows
But I'm not good enough at JavaScript to understand how to apply it to the context in which I'm trying to do it.
I'm creating a javascript snippet that could possibly be called multiple times from within a CMS (Umbraco ) that generates webpages.
An id (variable name: mediaid) is passed into this context and I want to dynamically create a link that has an onclick event to launch a popup. I take the ID passed into the context I'm working in (Umbraco calls them "macros") and append the id as a query string to a different URL (same domain) so that the resultant page can do some stuff with the id.
What I have works, but only for one instance on a page. I need a user to be able to insert multiple dynamic links on a page. Right now, the last link generated uses the onclick event for all instances on the page.
<script>
var linkWithQueryParam = 'http://www.mydomain.org/test2?yourkey=<xsl:value-of select="$mediaid" />';
var element = document.createElement("a");
element.id = '<xsl:value-of select="$mediaid" />';
element.href = '#';
element.onclick = function() {
setLink(linkWithQueryParam);
}
function setLink(value) {
window.open(value, 'player', 'width=775,height=520,location=0,directories=0,status=0,menubar=0');
}
document.body.appendChild(element);
element.appendChild(document.createTextNode('Listen To This Audio'));
</script>
So, for example, I have a template elsewhere, that calls this macro I created, twice:
<umbraco:Macro mediaid="4107" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>
<umbraco:Macro mediaid="26502" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>
The links are generated, but when I click on them, the link generated above in "linkWithQueryParam" is always whatever the last one was, for all links.
I thought maybe if I set the "id" attribute of the link to make it unique, it would work. But that doesn't work. How can I make the dynamically generated onclick event unique?
I ended up changing my approach and using an event delegate per unclenorton's response in this s.o. post
http://davidwalsh.name/event-delegate
I used a variation on the example to only disable the default link behavior, first checking to see that the link class is matched. This script relies on a named div that is available sitewide and is placed at the bottom of a master template so it is available:
<script>
document.getElementById("main").addEventListener("click", function(e) {
if(e.target)
{
if(e.target.nodeName == "A")
{
if(e.target.className == "miniplayer")
{
if(e.preventDefault) {
e.preventDefault();
}
else
{
e.returnValue = false;
}
var target = e.target;
var popupWindows = window.open(target.href, 'player', 'width=775,height=520,location=0,directories=0,status=0,menubar=0');
}
}
}
});
</script>
I then edited my user macro to simply place the class "miniplayer" on each link it creates and include the media id as a query parameter to another url which provides the media player. That other url resource then pulls the query param id out of the url and looks up the link to the media item. But the .js above launches the pop-up the way that I want.
One challenge I had was on how to dynamically assign the resultant media resource to the player (in this case, jPlayer). I found that if I write the media url to a hidden div, I can then just tell the jPlayer to read the value from it.
So I have a second macro which gets the query param and writes it to a hidden div:
<div style="display:none" id="audioUrl"><xsl:copy-of select="$mediaNode/audioUrl" /></div>
Finally, I adjust the jPlayer jQuery to read the url from the hidden div:
$(this).jPlayer('setMedia', {mp3: $("#audioUrl").text() }).jPlayer("play");
It doesn't seem like the best solution. I don't like passing the mediaid through the url, but it fulfills all my other requirements
The issue here is with globals and closures. The linkWithQueryParam variable is a global that is updated each time that script is added. When you click on the link it goes and fetches the url from the variable which is of course the last one.
You can fix this a few ways,
Wrap this code in an immediate anonymous function. This will reduce the scope of the variables to within the anonymous function.
Set the URL when the script is run instead of when the link is clicked.

How to scroll to a specifc element when there is already an # anchor on the url

I have a web site on based on SkelJS that currently loads a different part of the webpage by appending an #anchor to the url like this:
Note that #blog loads the blog page, the scroll is at the top. Inside the Blog page I need to scroll to a certain article. How can I use two anchors so that something like #blog#article_x would work? I suppose I have to look for a workaround since anchoring 2 ids makes no sense, is there a work around?
Additional notes:
Note that if a change #blog to #article_x it actually goes to the desired article however if someone shares the link it won't go to the article because it will look for #article_x on the homepage, where it does not exists.
Here is a demo of the template I'm using (http://html5up.net/uploads/demos/astral/#) note how the #anchor loads the desired page.
You can use a hash that contains both page and element. Then split and then do your page load then scroll, i.e. #blog,someelement
//on page load or wherever you detect the hash
$(function(){
var hash = window.location.hash;
var ele = null;
//Detect if there is a splitable hash
if(hash.indexOf(",") != -1){
var parts = hash.split(",");
hash = parts[0];
ele = jQuery("#"+parts[1]);
}
//whatever function you do to load the blog page
loadPage(hash,ele);
});
function loadPage(page,ele){
//do page loading
$("#page").load("http://someurl.com",function(){
//if there was no second part to the hash
//this will be skipped
if(ele){
$("html,body").animate({
scrollTop: ele.offset().top
},1000);
}
});
}
JSfiddle Demo
Considering the ID of the element that you want to scroll to is myelement you can use below jquery code to smoothly scroll to it.
$("html,body").animate({scrollTop : $("#myelement").offset().top},1000);
We can scroll to specific div when it has id or class
var $id=window.location.href.split('#')[1];
$('html, body').scrollTop($("#"+$id).offset().top)

Passing multiple values in Javascript OnClick, using those values in specific ways

While I've done some Javascript coding, I consider myself a more novice, Frankenstein-type coder, basically cutting and pasting with trial and error to see if I can get something to work...just a heads up on my honest assessment of my experience level.
I've got a unique thing I'm developing for, and hoping to get some help with Javascript. Here's what I'm trying / need to do: for a webpage based kiosk presentation, I'm using one HTML webpage, but with multiple sections whose visibility toggles on/off based on a Javascript I currently have that works fine. (I don't want to / can't use regular HTML pages with links because of how it ends up running).
The only problem with the above issue is that there's no easy way to create a 'back' or 'previous page' link for an end page that may have multiple ways to get to it. It won't 'know' where the user came from.
So here's what I'd like to do: pass 2 variables through my OnClick javascript function, the DIV name that needs to toggle on/off ... AND a 2nd variable of the current visible DIV name so that the next DIV that toggles on can 'remember' what the previous (and now invisible) DIV was so that there can be an accurate 'back' button.
Here's some sample code:
Each DIV section that turns on an off is setup like this:
<div id="sectionName" class="content">
</div>
These DIVs have buttons/links that are setup like this:
These run a Javacript:
function toggleVisibility(selectedTab) {
var content = document.getElementsByClassName('content');
for(var i=0; i<content.length; i++) {
if(content[i].id == selectedTab) {
content[i].style.display = 'block';
} else {
content[i].style.display = 'none';
}
}
}
So what I'm hoping is that there is a way to do something like this:
So that when that is clicked, the next DIV that turns on could also include a Javascript generated link based on that passed variable, something like:
Previous<br>Menu
I'm aware that Javascript toggling of DIVs on and off may not allow the generation of a dynamic Javascript link like the one I'm describing above, so I'm throwing this out there for some help from other, far more experienced programmers. Ideally, I'd like to try and fit everything into what I've created so far, so I don't have to start over from scratch. Any ideas?
Please reference this sample page:
www.gs3creative.com/test/
You could use location hashes (mypage.html#mydivid) and then use history.back() to handle 'back' navigation.
To stitch up the div's showing on the correct hash value....
var oldHash = '';
// fires when the hash changes
function hash_changed() {
var hash = location.hash.replace('#', ''); // get the div ID
var div = document.getElementById(hash); // find the content div on the page
var allDivs = document.getElementByClassName('content'); // get all of the content divs
// hide all the content divs
for (var i = 0; i < allDivs.length; i++) {
var thisDiv = allDivs[i];
thisDiv.style.display = 'none';
}
// only show the right one
div.style.display = 'block';
}
// this triggers the event
setInterval(function() {
// if the hash has changed, fire the function
if (oldHash != location.hash) {
oldHash = location.hash;
hash_changed();
}
}, 100); // call every 100 ms so that there is no lag
So if you set the navigation to 'mypage.html#sectionName' it would hide all other div's of the class 'content' and then only show the div with the ID of 'sectionName'.
An easy solution for me would be to render two content pages on a HTML page and show and hide content when needed from a onlick handler via javascript in your CSS add a class:
function showDiv() {
document.getElementById("theObject").className = "visible";
}
CSS:
// Switch between the content adding the classes and removing the old class
.visible{
display:none;
}
.show{
display:block;
}
Another solution using sessions "php" via javascript to hold the variables with in statements.
<?php if (session_status() == PHP_SESSION_NONE) {
session_start();
$_SESSION['user_is where_variable'] = "im on page div 1";
}
This could also be done through js anyways.
javascript have a conditional statement using your $_SESSION vars;
if (variable == "im on page div 1" ){
// your functions
}else if ( variable == "im on page div 1"){
// another function
}
Create your click handler to update the variables in the session.

jQuery action only once / custom URLs

I have a very basic jQuery script that slides a title from bottom to top after the page loads. The problem I'm having now is that I need to make this title to only slide if the user is on the 'main page'. If the user then clicks on any sub-pages I need the title to remain to the top of the page.
Example: wordpress website with a few pages on which I have galleries. When a user enters a page -> animate title. When the user is browsing the gallery -> static title.
This is the jQuery script:
jQuery(document).ready(function () {
jQuery(".animate").addClass("move");
});
You can see the website in question here.
// later edit: Thanks everyone for helping! I forgot to mention that I have multiple URLs, there are multiple pages. Is there a way I can get the "current URL" of the page and then append to it the extra bit which will always be the same i.e. /?pid=xx ?
Example: I need to animate the title on pages with this format:
mywebpage/custom_name/
Then, on pages with this format, I need to keep the title static:
mywebpage/custom_name/?pid=xx
Following the answers bellow I made this script:
if(window.location.href == 'http://www.noahd.net/demo-upwall/residential/rooftop-garden/'){
jQuery(document).ready(function () {
jQuery(".animate").addClass("move");
});
} else {
jQuery(document).ready(function () {
jQuery(".portfolio-title-wrap").removeClass("animate").addClass("top");
});
}
This script works only for the /residential/rooftop-garden/ page. Under residential I have another 10 pages. And then I have another 6 pages starting from root, like /commercial/ or /objects which also have 6-10 sub-pages.
How can I adapt the above script to work on those pages and sub-pages but not on the sub-sub-pages?
You can decide behavior of your page based on url.
code:
if(window.location.href== mainapplicationurl){
// slide code
}
else{
// put title on top
}
After edit of question. you can decide pages based of count of '/' in url( will work only if url format is consistent).
var count = window.location.href.split("/").length;
jQuery(document).ready(function () {
if( count < 7 ){
jQuery(".animate").addClass("move");
} else {
jQuery(".portfolio-title-wrap").removeClass("animate").addClass("top");
}
});
Wordpress labels pages with unique classes so you can target an specific page like this:
jQuery(document).ready(function () {
jQuery(".page-id-32 .animate").addClass("move");
});
You can do it different ways. For example you can load your slide title stuff only when you are on specific page using wordpress conditions.
Or you can do what you want from client-side. For example, your pages have different title tags, and main page has - Upwall Studio and you can check:
if ($('title').text() === 'Upwall Studio') {
//slide youre title here
}
Or you can check if user on a specific url via window.location.href:
if (window.location.href === 'http://www.noahd.net/demo-upwall/') {
//slide youre title here
}

Categories

Resources