I am working on a Bootstrap, jQuery project where I'm applying scrolling animations and functionality to the HTML.
When I am loading an HTML document, I want to know if the user navigated to "this" document with an ID or resource specified at the end of the URL, like so:
http://domain.example/page#section
Essentially, I want to execute jQuery code relatively to whether somebody navigates to the document having specified no ID at the end of the URL, or having specified one. I would assume that if this is possible, it would be done in $(document.ready()).
I find this pretty easy to do if I'm navigating to a resource on the same page, but in this instance where I'm navigating from a different page, I'm stuck and I would really appreciate a response whether this is possible or not.
While this is a relatively similar question to that of this, of which this answer describes a simple answer of checking whether or not a hash fragment exists:
if(window.location.hash) {
// Fragment exists
} else {
// Fragment doesn't exist
}
I realise, you may well want to check for different hash fragments, so I've added upon the answer to get this:
var hash = window.location.hash.replace('#','');
if(hash == "section") {
// Fragment exists and is equal to section
} else {
// Fragment doesn't exist
}
This checks for a hash fragment in the URL, if it exists and is equal to #section the if statement returns true.
Related
I know on client side (javascript) you can use windows.location.hash but could not find anyway to access from the server side. I'm using asp.net.
We had a situation where we needed to persist the URL hash across ASP.Net post backs. As the browser does not send the hash to the server by default, the only way to do it is to use some Javascript:
When the form submits, grab the hash (window.location.hash) and store it in a server-side hidden input field Put this in a DIV with an id of "urlhash" so we can find it easily later.
On the server you can use this value if you need to do something with it. You can even change it if you need to.
On page load on the client, check the value of this this hidden field. You will want to find it by the DIV it is contained in as the auto-generated ID won't be known. Yes, you could do some trickery here with .ClientID but we found it simpler to just use the wrapper DIV as it allows all this Javascript to live in an external file and be used in a generic fashion.
If the hidden input field has a valid value, set that as the URL hash (window.location.hash again) and/or perform other actions.
We used jQuery to simplify the selecting of the field, etc ... all in all it ends up being a few jQuery calls, one to save the value, and another to restore it.
Before submit:
$("form").submit(function() {
$("input", "#urlhash").val(window.location.hash);
});
On page load:
var hashVal = $("input", "#urlhash").val();
if (IsHashValid(hashVal)) {
window.location.hash = hashVal;
}
IsHashValid() can check for "undefined" or other things you don't want to handle.
Also, make sure you use $(document).ready() appropriately, of course.
[RFC 2396][1] section 4.1:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
(emphasis added)
[1]: https://www.rfc-editor.org/rfc/rfc2396#section-4
That's because the browser doesn't transmit that part to the server, sorry.
Probably the only choice is to read it on the client side and transfer it manually to the server (GET/POST/AJAX).
Regards
Artur
You may see also how to play with back button and browser history
at Malcan
Just to rule out the possibility you aren't actually trying to see the fragment on a GET/POST and actually want to know how to access that part of a URI object you have within your server-side code, it is under Uri.Fragment (MSDN docs).
Possible solution for GET requests:
New Link format: http://example.com/yourDirectory?hash=video01
Call this function toward top of controller or http://example.com/yourDirectory/index.php:
function redirect()
{
if (!empty($_GET['hash'])) {
/** Sanitize & Validate $_GET['hash']
If valid return string
If invalid: return empty or false
******************************************************/
$validHash = sanitizeAndValidateHashFunction($_GET['hash']);
if (!empty($validHash)) {
$url = './#' . $validHash;
} else {
$url = '/your404page.php';
}
header("Location: $url");
}
}
I'm trying to make a voting system that will check when user has voted and then change the html item css from "Vote" to "Thank you" and the background color to "green".
Now this works great, but I need to make the option when user refreshes the page to check if cookie exists (the cookie is already set = variable is voteCookie('id')) and then apply the class="exists". If it doesn't exist hide that class. That class would say "Thanks for voting", nothing else.
jQuery:
$(window).ready(function() {
var voteId = $('.gallery-item a');
$(voteId).on('click', function() {
$(this).text('Thank you!');
$(this).css('background-color', 'green');
});
});
You can do that (it's made easier with the jQuery cookie plugin), but it's not the correct use case for cookies. Cookies get sent from the client to the server with every HTTP request; if you're not using that information on every HTTP request, that's just completely unnecessary data transfer.
Consider local storage instead, which is supported by virtually all browsers, even IE8:
$(document).ready(function() {
var voteLink = $('.gallery-item a');
if (localStorage.getItem("voted")) {
voteLink.text('Thank you for voting').addClass('voted');
} else {
voteLink.one('click', function() {
localStorage.setItem("voted", "yes");
$(this).text('Thank you!');
voteLink.addClass('voted');
// If you wanted to do something with *just* the elements that weren't
// clicked, you could do:
// voteLink.not(this).addClass('unused-vote');
// ...or similar
});
}
});
...but if you want to use cookies, with the jQuery cookie plugin, you just change the getItem line to if ($.cookie('voted')) and the setItem line to $.cookie('voted', 'yes');
I made a few other changes above as well:
I used document rather than window with ready - the documentation only talks about document, not window. (That said, I generally prefer not to use ready at all; instead, I just ensure scripts are at the end of the HTML, just before the closing </body> tag.)
I called the variable voteLink rather than voteId since it's a jQuery object containing an a element, not an ID.
I changed $(voteId) to voteLink because the object is already a jQuery object, no need to pass it through $() again.
I changed the direct style manipulation to a class you add, for better separation of logic and styling.
I added that same class when they've already voted.
I used one rather than on so that we remove the click handler on the first click.
Obviously, this just has the client code. I assume there's a server piece that validates votes and such (since you can't trust anything the client sends or stores for you).
I need to redirect to another page onClick of submit and call a function making an ajax call. This is what I have :
$('#submitButton').click(function() {
window.location.href = "otherPage";
displayData();
});
Also, Another way I tried is to set the form fields on otherPage by using
var elem = window.document.getElementById(field);
elem.value = "new-value";
so that I could call the eventhandler of a submit button present on otherPage, but it doesn't work. Please let me know where I am wrong.
I'm not sure if there is a neat way to achieve this, but you can add a hash in your url you redirect to, then just simply check if the hash exists, execute function and remove hash.
Here are some handy URLs:
Location.Hash - information about this function and how to use it.
Removing hash from url without a page refresh - This was a bit of an issue, as window.location.href = ''; removes everything after the hash.
A hash (as Arko Elsenaar said) or a querystring parameter added to the target URL would allow you to detect what to do once there.
The hash makes it a bit easier while the querystring is cleaner if you want to pass more information.
For instance on the first page: window.location.href = "other/page.html#displayData";
On the second page:
if (window.location.hash === '#displayData') {displayData();}
Another way could be to use the HTML5 Storage API, if and only if the 2 pages are on the same domain.
1st page would do, before the redirection:
localStorage.displayData = true
And the 2nd:
if (localStorage.displayData) {displayData();}
However in this case you'll need to clean up the localStorage.displayData value when used, otherwise it will stay there forever and your second page would always find it set to true.
delete localStorage.displayData
All in all, the hash method seems best here.
I'm trying to check a page (on the same domain) for a specific string and then execute something accordingly. How can I go about this in JavaScript (with jQuery loaded)?
A (maybe too much) simplified schematic:
url = "pageToLoad.php"
if(StringOnPage(url) == TRUE){
// Do a bunch of stuff
}else{
// Do nothing
}
Now how would I construct StringOnPage() ideally? I made several attempts with jQuery's .load and .ajax, I even tried to load it into a hidden container. There must be a way to load the page into a string and check for an expression or something without all the html hacks.
The page is just an HTML populated file. Basically I need to find a text in a DOM element.
Load the page via AJAX as a plain string and then simply check if the string you are looking for is somewhere in the string you got from your AJAX call:
$.get(url, function(data) {
if(data.indexOf('whatever') != -1) {
// do a bunch of stuff
}
}, 'text');
Of course you could also use 'html' instead of 'text'; then data is a jQuery object containing the DOM of the page you just loaded.
I am making a forum and I want it to run like a desktop application, so I do not refresh the page. For lack of a better method without another complete Ajax request I receive the number of pages of data available in an Ajax request. I need to display this data (as I have at ethoma.com/testhome.php -- I set the page size to 1 for testing) but I also need to add event handlers to each individual number displayed to trigger an event that will change the color of the text and trigger an Ajax call to get the page number specified. The challenge for me is that there could be 500 pages (of course then I wouldn't be able to display every page number). For those who don't want to view the code via my site, here is the important parts of it:
function getPosts()
{
var queryString = "category=" + category + "&page=" + page + "&order=" + order;
$.ajax(
{
url: 'getposts.php',
data: queryString,
success: function(data)
{
var oldHtmlTemp;
var dataArray = data.split("%^&$;");
numpage = dataArray[0];
$('#postcontainer').html(dataArray[1]);
$('#enterpage').html('');
if (numpage != 0)
{
for(var i=1;i<=numpage;i++)
{
oldHtmlTemp = $('#enterpage').html();
$('#enterpage').html(oldHtmlTemp + " " + i);
}
oldHtmlTemp = $('#enterpage').html();
$('#enterpage').html(oldHtmlTemp + " ");
}
else
{
$('#enterpage').html('No results for this query');
}
}
});
}
If you are wondering what the .split() is doing, the php doc returns the number of pages seperated by that weird string that I designated. I decided it would be the easiest way to put the number of pages within the rest of the post text.
Anyway how would I add event handlers to these individual numbers?
I have a quick follow-up question, this code isn't working for some weird reason. It adds an event handler to the next page and previous page buttons, but also error checks to make sure you aren't trying to hit page -1.
$("#nextpage").click(function()
{
if (page < numpage -1)
{
page++;
getPosts();
alert(page);
}
});
$("#prevpage").click(function()
{
if (page >= 1);
{
page--;
getPosts();
alert(page);
}
});
Alerts are for debugging. Also worth noting is that when page = 0, you get page 1. What I mean is, I am counting from 0 1 2, but the user sees 1 2 3.
Thanks to anyone who views/answers this post.
I will refer to the last question first.
I didn't understand the followup question as you didn't specify what exactly is not working.
I am guessing you are overriding your "next","prev" while dynamically loading new HTML.
To resolve this, take a look in the "live" jquery method.
What it does is exactly like assigning "click" (like you did) but it re-evaluates the selector on each event. So the new elements will still be included.
I believe the "live" method will work on the first question as well.
Simply wrap each number with some "span" identified by a unique "class". and add something like this :
$(".pagination-number").live("click",function(){
$(".pagination-number").attr("color:black"); // remove previous click color
$(this).attr("color:red"); // mark currently clicked number
.... // load the content
})
When I write an HTML that loads dynamically, I always assign the Javascript to that HTML.
This way - I reevaluate the JS when the new HTML is loaded.
For example - my returned html looks something like
<div class="highlight"> some content here </div>
<script> $(".highlight").effect("highlight",{},300)</script>
The benefit it gives me is that I assign the behavior to the data. (just like in OOP).
I don't need to rewrite the behavior for each time I load the HTML. (in this example to highlight the text).
It will be highlighted each time I load the HTML because the script is evaluated.
You should consider using this design pattern as it will :
Concentrate all your code into a single place
This design pattern overcomes scenarios in which you override a dom object. ( for example, the old HTML has a #prev button, and the new html also has a #prev button. The code will always refer to the most recent dom element hence the behavior will be consistent.