Novice question I guess:
The Scenario:
I have an asp.net page that contains 6 divs and 6 hyperlinks which are linked to javascript function:
function showdiv(divname)
{
hideallcontentdivs();
var targetdiv = document.getElementById(divname);
targetdiv.style.display="block";
}
var alldivs=new Array();
function hideallcontentdivs()
{
alldivs=document.getElementsByTagName("div");
for(var i=0; i<alldivs.length;i++)
{
if(alldivs[i].className=="content")
{
alldivs[i].style.display="none";
}
}
}
ImageButton:
<img alt="alternate_text" src="imagesource" border="0px" />
the divs have id's: item1, item2....item6 and the hyperlink specify to the javascript function the id of the div that needs to displayed.
The Problem:
Whenever I click on an hyperlink, the effect that I want is achieved but the page reloads too. Don't really know where I'm going wrong but if anyone could guide me in the right direction, I'll be very very thankful.
Just return false on click
onclick="showdiv('item1');return false;"
Update:I just point the issue :), you can return the false where ever you like.
onclick="return showdiv('item1');"
and say to showdiv() to return false
You should add return false to your onclick handler. This prevents the default behaviour of the link.
A better solution would be to use jQuery or some other library and attach the event to the element. They also contain special functions to prevent the default behaviour:
Html:
<a id="button1" href="#"><img alt="alternate_text" src="imagesource" /></a>
Javascript/jQuery:
$('#button1').click(function(event) {
$('div').hide(); // hides all divs
$('#div1').show(); // shows the div with the id 'div1'
event.preventDefault(); // prevents postback
});
always, return false :)
but i'd rather put it in the function
function showdiv(divname)
{
hideallcontentdivs();
var targetdiv = document.getElementById(divname);
targetdiv.style.display="block";
return false;
}
+1 for Aristos' answer, although if you refactor the return false; to the end of the showdiv function you want have to update all the links.
return false is the key, as the other answers have said.
Just to add my tuppence though: you don't really need to use an anchor here and imho it's not good semantic style. Just use a span or div instead, and then the problem goes away.
Related
I am trying to trigger the click event of an a tag using jQuery and have seen many other Stack Overflow posts about this, but can't figure out why my replications of any of them are not working. My HTML is shown here:
<c:url var="link" value="/hardwareItems" />
<a href="${link}" id="goToHardwareItems">Go
to items</a>
And then here is my jQuery/JS:
$("#form").on("submit", function() {
if (confirm("Add hardware items?")){
$("#goToHardwareItems").trigger('click');
}
else {
window.location.href = "/home";
}
});
What I have is not working though, but when I actually click on the link, I am indeed taken to the page. So the problem is that the event is simply not triggering, even though I am also getting into the if statement. What am I doing wrong?
You can read the value of href and redirect. You are already doing so.
$("#form").on("submit", function () {
// Determine where to go based on user's response
var link = confirm('Add hardware items?') ? $('#goToHardwareItems').attr('href') : '/home';
window.location.href = link;
});
To prevent answers like: 'is the JavaScript file loaded?' -> Yes, it is loaded, at the footer part of the page! I have checked that with a simple message to the console, which is displayed!
But:
I've got a page with a button:
<button id="portfolio-posts-btn">Load portfolio related blog posts</button>
And a file main.js:
var portfolioPostsBtn = document.getElementById('portfolio-posts-btn');
var portfolioPostsContainer = document.getElementById("portfolio-posts-container");
if (portfolioPostsBtn) {
portfolioPostsBtn.addEventListener("click", function () {
console.log("the button was clicked!");
});
}
The text the button was clicked! should be displayed in the console, but it stays empty!
Apparently, the button click is not recognized, and thus, the var portfolioPostsBtn is false, or NULL... -> the method addEventListener() is not fired ?
I don't see the cause for this; I checked the spelling, should I use single or double quotes? Please help?
Thank you!
I've had this happen to me before, since theres two ways to do this I just used the other.
The first is onclick="function()", this is used as an attribute inside the element. Ex:
function clicked(){
alert("button clicked");
}
<button onclick="clicked();">Press me</button>
exaplaination: When you add this attribute to this element and I do believe some others when the button is clicked the specified code inside the quotes of the attibute will run. It doesn't have to be a number, e.g. onclick="alert(12+4/2);". But this is more of HTML than JavaScript using this version
The other way is using what you've got which (to me) is a lot more difficult then it needs to be. Heres my example
var b = document.getElementById("btn");
b.addEventListener("click", blogged);
function blogged(){
alert("this post has been blogged");
}
<button id="btn">Blog it</button>
This side of things has more to do with JavaScript and Event listeners. But the problem with you're code is that you're putting the event listener after you call the if statement. Here's my solution
var portfolioPostsBtn = document.getElementById('portfolio-posts-btn');
portfolioPostsBtn.addEventListener("click", function(){
check();
});
function check(){
if(portfolioPostsBtn){
console.log("posted");
}
}
<button id="portfolio-posts-btn">press this to post<button>
Presumably you have made a decision not to use jQuery. You'll need to wrap your code in an event listener so that the code is executed when the DOM is ready.
document.addEventListener("DOMContentLoaded", function(event) {
var portfolioPostsBtn = document.getElementById("portfolio-posts-btn");
var portfolioPostsContainer = document.getElementById("portfolio-posts-container");
if (portfolioPostsBtn) {
portfolioPostsBtn.addEventListener("click", function () {
console.log("the button was clicked!");
});
}
});
The answer is found in the uploading of the file page-portfolio.php!
I found out that the id="portfolio-posts-btn", added later, was not updated - could be my mistake, or the SFTP upload extension in Brackets - I did not see an error message!
Anyway, the issue is solved!
One more question: "are there methods to check if an id exists?". That could make live easier!
All contributors, thank you for your answers!
I'm trying to make a button that will hide a specific -- and then replace it with another hidden . However, when I test the code, everything fires correctly except for the .removeClass which contains the "display: none."
Here is the code:
<script type="text/javascript">
$(document).ready(function(){
var webform = document.getElementById('block-webform-client-block-18');
var unmarriedbutton = document.getElementById('unmarried');
var buyingblock = document.getElementById('block-block-10');
$(unmarriedbutton).click(function () {
$(buyingblock).fadeOut('slow', function() {
$(this).replaceWith(function () {
$(webform).removeClass('hiddenbox')
});
});
});
});
</script>
The CSS on 'hiddenbox' is nothing more than "display: none.'
There is a with the id of unmarried, which when clicked fades out a div and replaces it with a hidden div that removes the class to reveal it. However, the last part doesn't fire -- everything else does and functions properly. When I look at in the console too, it shows no errors.
Can someone please tell me where the error is? Thanks!
Edit: I may be using the wrong function to replace the div with, so here's the site: http://drjohncurtis.com/happily-un-married. If you click the "download the book" button, the the div disappears and is replaced correctly with the div#block-webform-client-block-18. However, it remains hidden.
The function you pass to replaceWith has to return the content you want to replace it with. You have to actually return the content.
I don't know exactly what you're trying to accomplish, but you could use this if the goal is to replace it with the webform object:
$(this).replaceWith(function () {
return($(webform).removeClass('hiddenbox'));
});
NB, use jquery !
var webform = $('#block-webform-client-block-18');
var unmarriedbutton = $('#unmarried');
var buyingblock =$('#block-block-10');
unmarriedbutton.click(function () {
buyingblock.fadeOut('slow', function() {
$(this).replaceWith( webform.removeClass('hiddenbox'));
});
});
Was too fast, i believe it's the way you select your object (getelementbyid) then you create a jquery object from it... -> use jquery API
I would like to present images to my users, where they can select them. I need them to select a limited number, say 5, so:
The images are shown in a matrix, and the user can click them.
I thought:
function boom()
{
this.css('background-color','#fff');
this.data('clicked','yes');
// I should also make checks here to see how many were clicked already
}
$('img').click(boom);
// I thought this would connect all img's that were clicked upon to this function, where I can call the 'this' with the css function...
But it doesn't work as I thought it would...
Any help would do, thanks !
$(function(){
var clicked_img = 0;
$('img').click(function(){
$(this).css('background-color','#fff').data('clicked','yes');
clicked_img++;
});
});
EDIT: UPDATED CODE BELOW FOR NEW REQUEST, FOUND IN COMMENT THREAD:
Per your updated code request, if your HTML is this:
<img id="one" class="clicked" src="img/one.png" />
<img id="two" class="clicked" src="img/two.png" />
This JQuery has been fixed to work for you:
$('img.clicked').click(function(){
boom(this);
});
function boom(e) {
if($(e).data('clicked')=='yes') {
$(e).data('clicked','no').css('border','none');
}
else {
$(e).data('clicked','yes').css('border','3px solid #cccccc');
}
}
Working demo of the new code: http://jsfiddle.net/Vwye8/
Try assigning a variable to an annonymous function
var boom = function()
{
this.css('background-color','#fff');
this.data('clicked','yes');
// I should also make checks here to see how many were clicked already
}
and then calling the $('img').live("click",boom);
js fiddle here: http://jsfiddle.net/t7u6t/
On a page with Ajax event, I want to disable all actions until the Ajax call returns (to prevent issues with double-submit etc.)
I tried this by prepending return false; to the current onclick events when "locking" the page, and removing this later on when "unlocking" the page. However, the actions are not active any more after they are "unlocked" -- you just can't trigger them.
Why is this not working? See example page below. Any other idea to achieve my goal?
Example code:
both the link and the button are showing a JS alert; when pressing lock, then unlock the event handler is the same as it was before, but doesn't work...?!?
The code is meant to work with Trinidad in the end, but should work outside as well.
<html><head><title>Test</title>
<script type="text/javascript">
function lockPage()
{
document.body.style.cursor = 'wait';
lockElements(document.getElementsByTagName("a"));
lockElements(document.getElementsByTagName("input"));
if (typeof TrPage != "undefined")
{
TrPage.getInstance().getRequestQueue().addStateChangeListener(unlockPage);
}
}
function lockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.cursor = 'wait';
if (el[i].onclick)
{
var newEvent = 'return false;' + el[i].onclick;
alert(el[i].onclick + "\n\nlock -->\n\n" + newEvent);
el[i].onclick = newEvent;
}
}
}
function unlockPage(state)
{
if (typeof TrRequestQueue == "undefined" || state == TrRequestQueue.STATE_READY)
{
//alert("unlocking for state: " + state);
document.body.style.cursor = 'auto';
unlockElements(document.getElementsByTagName("a"));
unlockElements(document.getElementsByTagName("input"));
}
}
function unlockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.cursor = 'auto';
if (el[i].onclick && el[i].onclick.search(/^return false;/)==0)
{
var newEvent = el[i].onclick.substring(13);
alert(el[i].onclick + "\n\nunlock -->\n\n" + newEvent);
el[i].onclick = newEvent;
}
}
}
</script>
<style type="text/css">
</style>
</head>
<body>
<h1>Page lock/unlock test</h1>
<p>Use these actions to lock or unlock active elements on the page:
lock,
unlock.</p>
<p>And now some elements:</p>
<a onclick="alert('This is the action!');return false;" href="#">link action</a>
<input type="button" value="button action" onclick="alert('This is another action!')"/>
</body>
</html>
Thanks guys for your ideas and answers.
Now I see that I have mixed up Strings and functions, which obviously can't work ;(
I should have made clear that we use some Web FW and tag libraries (Trinidad) which create the event handling (and Ajax) code, hence I can't edit that directly or use synchronous Ajax etc.
Moreover, Ajax is only one scenario where this code should be executed. It's purpose is to prevent the user to double-submit a page/action, which is also relevant for non-Ajax pages where you could kind of doulbe-click on a button. I know that this is not really safe, and it's only meant to be a "convenience" thingy to avoid getting the navigation error page too often (we have server-side protection, of course).
So, will try the div overlay, probably.
Thanks again,
Christoph.
How about setting up a global var
actions_disabled = 0
increment when the AJAX call starts then decrement when it finishes. All your "action" handlers can then start with
if (actions_disabled) return false;
Much simpler than debugging self-modifying code!
Alternatively, to lock your controls you could set:
control.disabled="disabled"
which will have the bonus of greying them out, making it obvious to the user that they can't submit. To unlock, simply set:
control.disabled=""
NEW IDEA BASED ON COMMENTS (can't quote code in comments, it appears ...):
You can always just hang extra attributes off Javascript objects:
To lock, you could:
control.onclick_old = control.onclick
control.onclick = "return false;"
To unlock, you could:
control.onclick = control.onclick_old
I once achieved this goal by creating a DIV that covered the area I wanted disabled, setting its z-index higher than any of the other elements on the page, and then setting its opacity to 0. By default, this DIV was hidden by display: none, so that it wouldn't interfere with anything. However, when I wanted the area disabled, I just set its display to block.
Steve
AJAX. Asynchronous. Just make the HTTP request synchronous. Problem solved.
The problem with your code is a result of not coming to grips with types in javascript.
When you say:
var newEvent = 'return false;' + el[i].onclick
what this does is coerce el[i].onclick (which is a function) to a string, then concatenates it to the string 'return false;'. Then when you reassign it as so:
el[i].onclick = newEvent;
onclick which was previously a function is now a string.
Then you attempt to resurrect your old function from the string by taking a substring:
var newEvent = el[i].onclick.substring(13);
which is fine, except newEvent is still a string! So when you assign it back to onclick again, you are assigning the string representation of the original function, not the function itself.
You could use eval to evaluate the string and return the function, but please don't do that. There are a number of better ways to do this, as has been suggested by other commenters.
I would also question why you wish to use AJAX at all if you don't want to allow asynchronous requests.
Put lockPage() at top of activete() function, and unlockPage() at bottom of deactivate().
activate: function() {
function lockPage()
{
lockElements(document.getElementsByTagName("a"));
lockElements(document.getElementsByTagName("input"));
lockElements(document.getElementsByTagName("button"));
};
function lockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.pointerEvents="none";
}
};
lockPage();
// ...
},
deactivate: function() {
// ...
function unlockPage() {
unlockElements(document.getElementsByTagName("a"));
unlockElements(document.getElementsByTagName("input"));
unlockElements(document.getElementsByTagName("button"));
};
function unlockElements(el)
{
for (var i=0; i<el.length; i++)
{
el[i].style.pointerEvents="auto";
}
};
unlockPage();
},
Using a div overlay does not prevent a user from tab-ing into your page. Usually that is OK, since most users do not tab through a page anyhow.
If you use any keyboard shortcuts on your page, they will still be available, so separate handling will be needed for those.
Alse, I assume that clicking an element that can have focus (eg. an <a> tag), then pressing enter, would still cause a double submit.