addClass only if cookie exists else hide - javascript

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).

Related

jQuery (JavaScript): Knowing navigated ID on Document Load from different page

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.

Node js setup an Anchor [duplicate]

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");
}
}

Execute javascript inside the target of an Ajax Call Drag and Drop Shopping Cart without Server language

Well i wanna create an Ajax Drag and Drop Shopping cart using only javascript and ajax. Currently i'm using the example in this page as a stepping stone. Right now it's only with local jquery and it works fine but i want to make the cart work with ajax calls. Note that i do not want to use a server side language( like php, rubby, asp etc), only html and javascript.
My initial thought was that at the $(".basket").droppable i should add an ajax call to another html page containing the "server logic" in javascript, execute in that file all the necessary steps( like reading the get variables (product name, product id and quantity), set a cookie and then return an ok response back. When the server got the "ok" response it should "reload" the cart div with the updated info stored inside the cookie.
If this was with php i would know how to do it. The problem is that as far as i know, you can execute javascript once it reaches the DOM, but how can you execute that js from inside the page that isbeing called upon ? ( thanks to Amadan for the correction)
I've thought about loading the script using $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ).. but the problem with that is that the url GET variables i want to pass to the "server script" do not exist in that page.
I havent implemented all the functionality yet as i am stuck in how to first achieve javascript execution inside an ajax target page.
Below is a very basic form of my logic so far
// read GET variables
var product = getQueryVariable("product");
var id = getQueryVariable("id");
var quantity= getQueryVariable("quantity");
//To DO
//--- here eill go all the logic regarding cookie handling
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
alert('Query Variable ' + variable + ' not found');
}
Any help regarding this matter will be appreciated.
Note: Logic in simple words:
1)have an html page with products+cart
2)Have an "addtocart.html" with the "Cart Server Logic"( being the target of the ajax call when an item is dropped into the product.)
If you have some other idea on this, please enlighten me :)
thanks in advance
Foot Note-1:
if i try loading the scipt using
$("#response").load("ajax/addtocart.html?"+ $.param({
product: product,
id: id,
quantity:quantity
})
);
i get the alert about not being able to find the url parameters( something that i thing is normal as because the content is being loaded into the initial page, from which the request is started, there are no get parameters in the url in the first place)
The problem is that as far as i know, you cannot execute javascript contained in the target of an ajax call, as that page never reaches the browser interpreter.
This is either incorrect or misleading. The browser will execute any JavaScript that enters DOM. Thus, you can use $.load to load content and execute code at the same time. Alternately, you can use hacked JSONP to both execute code and also provide content as a JSON document.
EDIT: Yes, you can't get to the AJAX parameters from JavaScript. Why do you want to? Do you have a good reason for it, or is it an XY problem?
The way I'd do it is this:
$('#response').load(url, data, function() {
onAddedToCart(product, id, quantity);
});
and wrap your JS code in your HTML into the onAddedToCart function.
Depending on what exactly you're doing, it could be simplified even further, but this should be enough to cover your use case.

How to override variable parameter loaded from another script

I have a script that loads the code dynamically. It is kind of a search engine. When I press a search button, the action gets triggered and a new page opens with many parameters.
I want to override one of the parameters generated with the script in the new URL. JS code is quite big and hard to read, but I have found the important part in the Firebug DOM editor.
This is the pattern of the URL generated when you perform the search:
http://www.example.com/...?ParameterOne=123&ParameterTwo=Two&ThisParameter=Sth&ParameterFour=Four...
What I want to edit is "ThisParameter" and change its value. This is the part edited in the DOM that does what I want:
Foobar = {
_options: [],
...
var options = {"ParameterOne":123,"ParameterTwo":"Two","ThisParameter":"ABC","ParameterFour":Four,...}
...
And this is the output of "ThisParameter" when you choose "Copy path" in Firebug's DOM tab:
_options[0].ThisParameter
I am wondering it this is possible at all. What makes me think that it is, is the fact that I can change this parameter in Firebug and it works perfectly. So, if Firebug can edit it, there should be a way to influence it with another script.
Looking forward to any suggestions, thank you in advance!
Since you cannot edit the dynamic script you have the following options:
You have to try to give the script the correct input and hope it uses your value.
Add a script to the results page which will read the url and arguments, change it and redirect, as we discussed here. (If you put everything in functions it should not conflict with the dynamic script if the functions are uniquely named.)
You could try adding something like this jQuery code to the page with the search button:
$('input[name=search_button_name]').click(function(e) {
e.preventDefault();
var form_search = $('#search_form_id');
$('<input>').attr({
type: 'hidden',
name: 'ThisParameter',
value: 'SomethingElse'
}).appendTo(form_search);
f.submit();
});
You can override any js function and method, or wrap you code around it. The easiest thing would be to look at the code you get and once it gets loaded, you re-declare a method with your own functionality.
I you are trying to replace a parameter in a specific jquery request, you can even wrap around the jquerys ajax method:
var jquery_ajax = $.ajax
$.ajax = function(options){
// parse only a specific occurence
if(options.url.indexOf("example.com") > -1) {
// change the url/params object - depending on where the parameter is
options.params.ThisParameter = "My Custom value"
}
// call the original jquery ajax function
jquery_ajax(options);
}
But it would be a lot cleaner to override the method that builds the ajax request rather than the ajax request itself.
I would investigate further on the scope of the variable options (var options), is it global? i.e. if you type 'options' in the Firebug console, does it display its properties?
If so, you could then access it via your own script and change is value, e.g.
options.ThisParameter = 'my-own-value';
You might hook your script to the click event of the search button.
I hope this helps, it could be more specific maybe if you have some sample code somewhere.

How do I apply events and effects to elements generated through Ajax request with no specific id?

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.

Categories

Resources