JavaScript put variably into url, then use it if reloaded - javascript

We're working on a music page to list albums, songs and add lyrics.
We have a "View More" below each album, clicking that shows you the song list (using jquery, making a hidden div slide down). We'd like to add a variable to the URL if someone clicks it (or remove it if they "hide") the songs, so that it creates a permalink to that section. If someone passes that it'll automatically show that div open.
So a link should look something like this
http://www.greendayauthority.com/music/catalog.php#album=1039
or
http://www.greendayauthority.com/music.catalog.php?album=1039
(Could someone help me figure out the better way to use this? Between the "#" and "?"
We want to do the same thing for lyrics of individual songs. If someone clicks a song title, it adds another variable to the URL with the song ID.
So if someone clicks a song title it'll then be
http://www.greendayauthority.com/music/catalog.php?album=1039&song=3
We can handle all the code to make all the stuff appear on the page, but I don't know how to add a variable onto the page with javascript, so that if someone wants to link the lyrics to a specific song, they can share that link and when they visit, the proper divs will be shown.
Can someone help point me in the right direction? Any tips on a better way to do this are also welcome.
Thanks!

If you delimit it with a ?, it's a query string, the normal way to put variables onto a page. If you do it with #, it's the hash, and it refers to navigation within a page.
If you use the # you can navigate without refreshing the page. If you add an item to the query string from Javascript (location.href = blah?album=1039), the page will get reloaded. I don't think that's what you want.
In any case, when you click the link to expose the hidden div, don't change location.href. Just make your anchor tag navigate within the page, as in

Here's my try at it:
Required code:
var HashSearch = new function () {
var params;
this.set = function (key, value) {
params[key] = value;
this.push();
};
this.get = function (key, value) {
return params[key];
};
this.keyExists = function (key) {
return params.hasOwnProperty(key);
};
this.push= function () {
var hashBuilder = [], key, value;
for(key in params) if (params.hasOwnProperty(key)) {
key = encodeURIComponent(key), value = encodeURIComponent(params[key]);
hashBuilder.push(key + ( (value !== "undefined") ? '=' + value : "" ));
}
window.location.hash = hashBuilder.join("&");
};
(this.load = function (paramString) {
params = {}
var hashStr = paramString || window.location.hash, hashArray, keyVal
hashStr = hashStr.substring(1);
if (hashStr === "") return;
hashArray = hashStr.split('&');
for(var i = 0; i < hashArray.length; i++) {
keyVal = hashArray[i].split('=');
params[decodeURIComponent(keyVal[0])] = (typeof keyVal[1] != "undefined") ? decodeURIComponent(keyVal[1]) : keyVal[1];
}
})();
};
Init code:
$(function () {
showDiv();
$(".view-more-hash").live('click', function () {
HashSearch.load(this.hash);
showDiv();
});
});
function showDiv() {
if (HashSearch.keyExists('album')) {
var albumDiv = $("#album" + HashSearch.get('album')).show();
if (HashSearch.keyExists('song')) {
albumDiv.find("#album" + HashSearch.get('album') + "song" + HashSearch.get('song')).show()
}
}
}
Your links will look like:
View album
View song
Your content:
<a name="album=2"></a> // auto scroll to location.. not required
<div id="album2">
<div id="album2song3"></div>
</div>

Related

How to change a URL parameter on a link that has # as href and is submitted inside a form

I'm working on a drupal module and it gets images from an API, adds selectable search-filters and generates pagination. If I go to e.g. the 7th pagination page and add a filter that only spans 3 pages it will result in not showing anything at all.
Solution: on upon adding a filter, go back to the 1st page. Now is my problem that that page is an url parameter and the links made by the filter are set to href='#' so basically this page yes.
So I try to debug the javascript that handles the on click:
$('#blabla .filter-url').click(function(e) {
e.preventDefault();
var link = $(e.currentTarget);
console.log(link);
var filter_key = link.data('filter-key');
var filter_value = link.data('filter-value');
// var active = link.hasClass('active');
var filters_input = $('#blabla input[name="filters"]');
var current_filters = JSON.parse(filters_input.val() || '{}');
current_filters.filters = current_filters.filters || [];
var exists = ($.grep(current_filters.filters, function(e, i){
return e.key == filter_key;
}).length);
if (exists) {
//Remove current filter from list
current_filters.filters = $.grep(current_filters.filters, function(e, i){
return e.key != filter_key;
});
link.removeClass('active');
}
// Add current filter to list
current_filters.filters.push({
key: filter_key,
value: filter_value,
});
link.addClass('active');
filters_input.val(JSON.stringify(current_filters));
$('#formname').submit();
});
the link object:
The link object has a {0, context and length} object in which both 0 and context contain multiple instances of the url, which one should I edit?
I just want to manipulate the URL / get parameter page=xxx to be page=0, so it goes back to the 1st page. How to achieve this?
I was searching in the wrong place. At the end of the onclick-function it submits the form. I had to change the action of this form like this:
var old_form_action = $('#formname').attr('action');
var new_form_action = old_form_action.replace(/(page=)[^\&]+/, '$1' + '0');
$('#formname').attr('action', new_form_action);

Remove value from a var

I am having some problems removing parts of a var.
function hotBarClick() {
var likeCount = 0;
$.each(companies, function (key, value) {
if (value.liked) {
likeCount++;
}
if (value.liked && value.alreadyliked ==false) {
var content = value.getHtmlLogo();
matchesHtml.add(content);
this.alreadyliked = true;
}
if (value.liked == false && value.alreadyliked == true) {
var discontent = value.getHtmlLogo();
matchesHtml.remove(discontent);
this.alreadyliked = false;
}
});
I am making a app based on html and javascript. You can like/dislike companies in the neighbourhood. If you liked 5 companies or touch the "hotbar" you will see a slider(owl-carousel) with the logos of the companies you liked.
My problem is that if you liked a company first and then dislike it, i cant remove the images from the slider, that were previously shown.
var matcheshtml is the var containing this infomation. You can see that in my code i add stuff by matcheshtml.add() but i cant seem to use the .remove() method here?
How do i remove the good part?
BTW: i think discontent contains the correct value

Javascript / jQuery get all url parameters and add/change one

I have the following url
http://www.domain.com?page=options&tab=general
I want to be able to get to the tab parameter and change it e.g
I have two tabs General & Styles and when I click on styles, I want a hidden field(that has this url as a value) to change so that it reads the same url but with the tabs parameter changed to styles. So it would look like this
http://www.domain.com?page=options&tab=styles
However, this url may not have the parameter tab when the page is loaded so i need to be able to add a parameter to the url query string.
There will be many more tabs so I cannot just replace the text general with styles
Anyone know?
Thanks
var s = "http://www.domain.com?page=options&tab=general"
var queryString = s.substring(s.lastIndexOf("?") + 1);
var newQueryString = $.map(queryString.split("&"), function(pair) {
var p = pair.split("=");
if (p[1] == "general") {
p[1] = "styles";
return p.join("=");
} else {
return pair;
}
}).join("&");

jquery bbq remove hash b from url

im new to jquery bbq, i've figured out most of the setup so far but i have a little issue. heres the setup.
one page with main nav links on the right
each nav link click will change the body content of the page to its corresponding data (showing and hiding divs) (with bbq)
one of the links shows a div with another set of links that when clicked will set hash B in the url
so first link click
domain.com/dir/#A=page1
second link click
domain.com/dir/#A=page1&B=set1
if i press the back button it goes back to the previous A hash, however the B hash remains in the url.
is there a way to remove the B peram when not on the specific page?
$(window).bind('hashchange', function(e) {
var state = $.bbq.getState('p');
var graphState = $.bbq.getState('n');
var base_title = '{/literal}{$smarty.const.SITE_TITLE}{literal} | Dashboard | ';
$('.profile-nav a').each(function() {
if (!state) {
$('.profile-nav a').each(function() {
$('#' + this.id).removeClass('live active');
document.title = base_title + 'Message Center';
});
$('#m').addClass('live active');
} else if (state == this.id) {
$('#' + this.id).addClass('live active');
document.title = base_title + $(this).text();
} else {
$('#' + this.id).removeClass('live active');
}
});
if (!state) {
$('.tab-content').fadeOut('fast');
$('.message-content').fadeIn('slow');
} else {
$('.tab-content').fadeOut('fast');
clicked = $('#' + state).attr('rel').split(' ')[0];
$('.' + clicked).fadeIn('slow');
}
if (state == 'r') {
if (graphState) {
$('.nick-breakdown').fadeOut('fast');
$('#' + graphState).fadeIn('slow');
document.title = base_title + 'Reports | ' + $('#' + graphState).attr('rel');
} else {
$('.item-breakdown').fadeOut('fast');
$('.nick-breakdown').fadeIn('slow');
document.title = base_title + 'Reports';
}
}
});​
I've accomplished the same thing using jsbbq.pushState with merge_mode = 2 instead of just setting the # on the anchor.
Check out the docs here: http://benalman.com/code/projects/jquery-bbq/docs/files/jquery-ba-bbq-js.html#jQuery.bbq.pushState
merge_mode(Number) : Merge behavior defaults to 0 if merge_mode is not
specified (unless a hash string beginning with # is specified, in
which case merge behavior defaults to 2), and is as-follows:
0: params in the params argument will override any params in the current state.
1: any params in the current state will override params in the params argument.
2: params argument will completely replace current state.
So if your link looks like:
mysite.com#A=page1&B=page2 you could call
$.bbq.pushState({'A' : 'pageXYZ'}, 2);
And your doc location would then be:
mysite.com#A=pageXYZ
I got a way easier approach, no plugins needed:
Copy over current hashparameters to a dummy URL AS searchParameters. Now you can treat the hash parameters like search-parameters, edit them with all the functionality of searchparameters (developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) and copy them back afterwards AS hasparameters,
E.g Simple function that set and updates parameters, you could also use '.delete()' instead of '.set' to delete the parameter:
function setOrUpdateHashParameter( hashParameterName, hashParameterValue ) {
let theURL = new URL('https://dummy.com'); // create dummy url
theURL.search = window.location.hash.substring(1); // copy current hash-parameters without the '#' AS search-parameters
theURL.searchParams.set( hashParameterName, hashParameterValue ); // set or update value with the searchParams-API
window.location.hash = theURL.searchParams; // Write back as hashparameters
}
If anyone knows how to format these post properly, feel free to edit it, thanks!

Use stored properties when creating an HTML Sidebar

Using a sidebar, I get user input and save it as a script property. Next time the sidebar is loaded, I'd like to check if the saved property exists. If so, display it instead of the text entry box.
I know to use:
google.script.run.withSuccessHandler().myFunction()
Honestly, I have tried so many different things at this point. Any help would be greatly appreciated.
This is what I have tried, I want to load values in the sidebar if they exist. If they do not I want it load a text entry box, that is what it does by default.
Edit - Adding Code
function loadSidebarValues() {
if (dateText != 'ErrorStuff') {
var div = document.getElementById('dateValue');
div.innerHTML = dateText;
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = "";
$('#dateText').val(
PropertiesService.getScriptProperties().getProperty('dateColumn')
);
} else {
var div = document.getElementById('sidebarValues');
div.innerHTML = "";
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = 'There was an error.';
}
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'dateColumn': 'dateText',
});
Logger.log("date: " + userProperties.getProperty('dateColumn'));
}
function onLoad(){
if (PropertiesService.getScriptProperties().getProperty('dateColumn') != null) {
loadSidebarValues();
};
}
You can write server code to retrieve UserProperties value, then run the HTML script to get that value as instructed in File-open dialogs
section in this guide
What they do:
getOAuthToken in Code.gs
Call that function in Picker.html by this code:
function getOAuthToken() {
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();
}
createPicker method from withSuccessHandler take token value from getOAuthToken in first step.
You can use the same pattern for your own case.

Categories