Change href to anchor on same page - javascript

This is probably an easy question but I couldn't figure it out: I am trying to change a href to a variable using JavaScript/jQuery. I am using the Bootstrap Collapse Plugin. My code looks basically like this:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<h2>Collapsible Panel</h2>
<p>Click on the collapsible panel to open and close it.</p>
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1">Collapsible panel</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">Panel Body</div>
<div class="panel-footer">Panel Footer</div>
</div>
</div>
</div>
</div>
however panels are created dynamically and at some point, I have to change the ids and hrefs. E.g.:
...
to
...
If I use Javascript
var link = newId();
//newId is part of the plugin, but is based on the previous href
element.href = "#" + link;
the html changes into
...
(which is the full address of the page, with the anchor)
and it does not work anymore. However hardcoding it like this would work:
element.href = "#361cd655-ad54-4cd5-aeb7-a3da9553c1e9";
I've tried quite a few things but I always get similar results.

I can figure out that newId() most likely involves the previous href attribute because if you were to have an anchor element:
<a href='page'></a>
Even though it is a relative URL, the code
document.getElementsByTagName("a")[0].href
would return the full URL (eg. https://serveradmin.xyz/page)
A possible solution is instead of getting the current href, when changing it, also have a variable set to the new value. For example:
var linkHref = 1;
document.getElementsByTagName("a")[0].href = linkHref;
//when you next want to change it, don't get the current href, instead, use the link variable
linkHref++;
document.getElementsByTagName("a")[0].href = linkHref;
Alternatively, you could do this:
function getRelativeHref(href) {
return href.replace(window.location.href + "#", "");
}
If the href parameter was https://stackoverflow.com/posts/51951100/edit#test then it would return #test.

I think you have some problems in your newId function. You need something like that:
btn.addEventListener("click", () =>
Array.from(
document.querySelectorAll('a'),
a => a.href = "#" + newId())
)
function newId () {
return Math.random().toString(36); // simple random string.
};
...
<button id="btn">Change!</button>

Related

Change/increase variable-value for load-url in onclick fuction

I have a load more button on my page
<a class="btn btn-link border-top px-3 mt-5" role="button" id="reveal">Load more</a></p>
And an onclick function that loads content inside this div:
<div id="ajax-content" class="row m-0">
</div>
The script works and loads more content every time I click the button:
<script>
$('#reveal').on('click', function() {
$('#ajax-content').load('/wp-content/themes/template/ajax-news.php?offset=4');
$('#ajax-content').attr('id', '#ajax-contented');
})
</script>
But I need the offset-variable to increase by 4 every time I click it, so the content that loads is not the same. Hope anyone can point me to the right direction to make this work.
To achieve this you could use a data attribute on the a element which you increment by 4 on each successive click event:
$('#reveal').on('click', function(e) {
e.preventDefault();
let offset = ($(this).data('offset') || 0) + 4;
//$('#ajax-content').load('/wp-content/themes/heidner/ajax-aktuelt.php?offset=' + offset);
$('#ajax-content').html(offset);
$(this).data('offset', offset);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Last flere saker</p>
<div id="ajax-content" class="row m-0"></div>
This would also be possible with a global variable, but they are bad practice and should be avoided where possible.
In addition, note that changing id attributes at runtime is also not good practice. In this case it would stop the repeated clicks from updating the content. As such I removed that line.

Using js onclick on one button to inject link into another

I have two buttons, both without links, and want to add a link to one when the other is clicked. How can I make one button with an onclick give a link attribute to something else on the page? If not a button, maybe a div?
The following is my current code:
<div class="container">
<div class="jumbotron" style="background-color:#000000 !important;">
<img id="myImage" src="images/closed.png" style="width:100%">
<p id="texthere"></p>
<div class="container">
<div class="row">
<div class="col">
<button onclick="document.getElementById('myImage').src='images/open.png'" class="btn btn-primary active btn-block">Open Eyes</button>
</div>
<div class="col">
<button onclick="document.getElementById('myImage').src='images/closed.png'"class="btn btn-primary active btn-block">Close eyes</button>
</div>
</div>
</div>
Thank you in advance for your help.
*Edited to clarify and pose as a question.
I think you may be confused about how HTML links work. HTML has the a tag for elements that a user can click to go to a different URL. The (worse) alternative is to use an onclick handler to redirect the user by setting the value of window.location.
To make a button that creates a link on the page, put a script tag at the bottom of the body that attaches a listener to a button that, when called, places a link on the page.
<script type="text/javascript">
var button = document.getElementById('my-button'); // This button has to exist.
button.addEventListener('click', function() {
var link = document.createElement('a');
link.href = 'google.com'; // Or wherever you want the link to point.
document.body.appendChild(link);
});
</script>
While there are many ways to do what you want, without knowing what programming skills you have and what you want to see on the screen, perhaps this sort of structure would help you. Replace your current onclick handlers on the BUTTONs:
<button id="open" class="btn btn-primary active btn-block">Open Eyes</button>
<button id="close" class="btn btn-primary active btn-block">Close eyes</button>
<script>
document.getElementById("open").addEventListener("click", function() {
changeState('open');
});
document.getElementById("close").addEventListener("click", function() {
changeState('closed')
});
function changeState(state) {
document.getElementById("myImage").src = 'images/' + state + '.png';
var new_para = document.createElement("p");
var new_link = document.createElement("a");
new_link.setAttribute("href", "https://www.google.com/search?" + state);
var new_link_text = document.createTextNode("Search for '" + state + "'");
new_link.appendChild(new_link_text);
new_para.appendChild(new_link);
document.body.appendChild(new_para);
}
</script>

Issues with find() when inserting html dynamically using jquery

I have a modal with a grid of buttons representing different html components. When one of the buttons is pressed, some html is supposed to be injected into the page once the modal closes. However, I'm having trouble targeting the specific column where the html is to be injected. Here's my code:
<div class="row" id="newRow">
<div class="col-md-12 column">
<button class="btn addElement" href="#" data-toggle="modal" data-target="#add-element"><i class="fa fa-plus fa-3x add-item"></i></button>
</div>
</div>
And in my js file I have some code to assign an id to the column div (since there could potentially be many columns with this addElement button) that looks like this:
...
$(this).parent().next().children().find('.column').assignId();
...
Up to this point, everything works well. I'm having no trouble getting the column a unique id (defined in my assignId() function).
As I mentioned, the addElement button gets clicked, opening a modal which is when this code is executed:
$(document).on('click', 'button.addElement', function (e) {
e.preventDefault();
$('#add-element').modal('show').draggable();
var col = $('button.addElement').parent();
// debugging in the browser verifies that the colId
// successfully stores the id attribute for the column
var colId = col.attr('id');
addElements(colId);
});
...
function addElements(colId) {
$('#insert-paragraph').on('click', function () {
var html_content = '<div class="box" data-type="paragraph">...</div>';
$("#newRow").find("#"+colId).html(html_content)
$('#add-element').modal('hide');
});
}
It's on this line: $("#newRow").find(colId).html(html_content); that I'm having the issue. My guess is that the formatting for find(...) is wrong and that I can't just insert a variable like that, but I've tried a few different things and nothing seems to be working.
Any help is very much appreciated.
Thanks!
UPDATE:
#juvian suggested writing a few of the variables' values to the console:
console.log(colId);
console.log($("#newRow")).length;
console.log($("#newRow").find("#"+colId).length);
console.log($("#newRow").find("#"+colId).html());
I logged these values twice. First, just before passing colId into the addElements function and in the addElements function immediately after $(#newRow").find("#"+colId).html(html_content); The results of those two tests are as follows:
Values prior to running addElements:
console.log(colId); = 8153-1076-641d-3840
console.log($("#newRow")).length; = Object[div#newRow.row.clearfix]
console.log($("#newRow").find("#"+colId).length); = 1
console.log($("#newRow").find("#"+colId).html()); = <button class="btn addElement"...>...</button>
Values after the insert-paragraph button is pressed:
console.log(colId); = 8153-1076-641d-3840
console.log($("#newRow")).length; = Object[div#newRow.row.clearfix]
console.log($("#newRow").find("#"+colId).length); = 1
console.log($("#newRow").find("#"+colId).html()); = <div class="box box-element" data-type="paragraph">...</div>
Interestingly enough, it appears like everything is working like I'd expect it to, however, when it's all said and done, the addElement button remains and the page still renders this:
<div id="newRow" class="row clearfix">
<div id="32aa-ab91-f50d-c3b3" class="col-md-12 column ui-sortable">
<button class="btn addElement" data-target="#add-element" data-toggle="modal" href="#">
<i class="fa fa-plus fa-3x add-item"></i>
</button>
</div>
</div>
.find as most jquery functions, takes a css selector as parametre. Unfortunately, colId is just a string, so it matches no elements (unless colId is html, span or something like that)
You are just missing adding the id selector at the beginning to do an id match:
.find("#"+colId)
I guess The parent of button is a div here which has no id.
var col = $('button.addElement').parent();
thus var colId is getting no value.give that div an id and it should be fine.

Find sibling with Javascript and Hammer.js

I have made a simple system which detects double taps. I want to show a heart icon when someone double taps on an image, just like on Instagram.
This is what my code looks right now:
var elements = document.getElementsByClassName('snap_img');
[].slice.call(elements).forEach(function(element) {
var hammertime = new Hammer(element),
img_src = element.getAttribute('src');
hammertime.on('doubletap', function(event) {
alert(img_src); // this is to test if doubletap works
// Some javascript to show the heart icon
});
});
This is what the HTML looks like:
<div class="snap_item">
<div class="snap_item_following_info">
<img class="snap_item_following_img" src="res/stat/img/user/profile/small/1.fw.png" alt="#JohnDoe" />
<a class="snap_item_following_name" href="#">#JohnDoe</a>
<div class="snap_too">
</div>
</div>
<img class="snap_img" src="res/stat/img/user/snap/43/2.fw.png" alt="#ErolSimsir" />
<div class="like_heart"></div>
<div class="snap_info">
<div class="snap_text">
LA is the shit...
<a class="snap_text_hashtah" href="#">#LA_city_trip</a>
</div>
<div class="snap_sub_info">
<span class="snap_time">56 minutes ago</span>
<div class="like inactive_like">
<div class="like_icon"></div>
<div class="like_no_active">5477</div>
</div>
</div>
</div>
</div>
So when the element 'snap_img' is double tapped, I need to get the element 'like_heart' which is one line below the snap_img element. How do I get that sibling element and fade it in with JQuery?
Like this
[].slice.call(elements).forEach(function(element) {
var hammertime = new Hammer(element),
img_src = element.getAttribute('src');
hammertime.on('doubletap', function(event) {
alert(img_src); // this is to test if doubletap works
$(element).next().text('♥').hide().fadeIn();
});
});
P.S. I've added that heart text, since the sibling was empty.
On the event handler, i would do $(element).parent().find('.like_heart').fadeIn(); So the code is not dependant on the element ordering.
(To clarify to selector: take the parent element which is the div.snap_item and find an element with class like-heart inside it)

Dynamic div content + retain last viewed div on browser backward

I am using dynamic div content and toggling between them on clicks, works well but is there a way to retain the last viewed div when the user clicks forward and backward on his browser? Thanks.
<script>
$(".settings").click(function() {
var id = this.id;
if ($("." + $(this).attr('rel')).css('display') == 'none') {
$('.n_tab').hide();
$('.p_tab').hide();
($("." + $(this).attr('rel')).show());
}
});
</script>
<div class="settings" rel="n_tab">
<div class="title info_2_Title">
Notifications</div>
</div>
<div class="settings" rel="p_tab">
<div class="title info_2_Title">
Privacy</div>
</div>
<div id="MasterContainer">
<div class="n_tab" style="display: none;"> the N DIV </div>
<div class="p_tab" style="display: none;"> the P DIV </div>
</div>
Try using a library like history.js to set that up. Internally it will use the pushState API, or fall back to url fragments if the browser doesn't support that.
You could try adding an id to each tab and appending that in an object or array each time a div is selected.
Define an array history = []; outside the click event and in your click event something like
history.push($(this).id);
If you wanted to keep more detailed data you could use a json object and append to it.
Thanks for the help guys, but after fiddling ard with History.js, I still couldn't get it to work, in the end I used a cookie to store the state and then check it when the page with dynamic div loads.
$(function() {
var x = $.cookie('tab_cookie');
($(x).show());
if (x == '.m_tab') {
var btn = document.getElementById('<%= btnLoadm.ClientID %>');
if (btn) btn.click();
}
});

Categories