Creating fancy HTML buttons with images - javascript

I'm using a customized <img> element as a button on my site (with onclick for the form submit). The reason being I want the element to display one image when the button is up and another for when the button is down. I'm using onmousedown and onmouseup for that.
This is an AJAX-based site, and the submit is also AJAX-y. It is safe to assume that javascript is on.
Forms are being submitted by AJAX (via Prototype), so the regular <input type=button> is out of the question as it would cause a submit + page refresh (also, to my best understanding, it cannot be fully customized using images).
My question is: Should I expect any difficulties with the approach, and is there a better/easier way of generating customized buttons?
I am interested in usability and compatability issues: e.g. Accessability features (such as tab index) vs. support on all browsers (such as IE6).

Use a <button> or <input type="submit"/> with CSS background styles applied.
<html>
<head>
<style type="text/css">
.hoverable {
background: #FFFFFF url(path/to/background.png) top left no-repeat;
height: 32px; /* height and width match your background.png dimensions */
width: 64px;
}
.hoverable:hover {
background-image: url(path/to/background-hover.png);
}
</style>
</head>
<body>
<form>
...
<button type="submit" class="hoverable"></button>
<!-- or <input type="submit" class="hoverable"/> -->
<!-- or <button type="button" class="hoverable"></button> if you don't want submit behavior -->
</form>
</body>
</html>
Using a form input makes the most sense semantically, especially with your concerns about accessibility. People using accessibility tools probably aren't expecting to encounter a <div> or <img> and be expected to perform an input event on it (I could be wrong, I'm not entirely familiar with how such tools work).
The fact that the application is dynamic/ajaxy/etc. shouldn't be a barrier to you using the appropriate markup elements and using CSS to style it appropriately.
Edit:
Regarding the <input> not working: if you return false from whatever gets invoked when the button is clicked, it won't continue execution (i.e. submit the form). Example:
<button type="submit" onclick="handleClick();"></button>
...
function handleClick() {
// ajax call
return false;
}
On top of that, using a <button type="button"></button> shouldn't even submit the form at all. Some browsers default the type to "submit", so you'd want to explicitly define type="button" to make sure it's not treated as a submit.
Obviously, this will be different than your prototype code, but you get the picture; the gist of it is that the event handler needs to return false. And <button>/<input> can be styled just as well as an <img> or <div>.

You can improve these with CSS sprites, here's a good article explaining it: http://www.jaisenmathai.com/blog/2008/04/03/extremely-efficient-image-rollovers-using-css-sprites-and-no-javascript/
It's a css-only solution that uses 1 image for both the up & down states.

Related

How to programmatically click on a button - maybe Angular?

I'm trying to click on a html button programmatically.
Looking at the page source - I see
<div class="submitBtns">
<button class="btn btn-primary primaryBtn" type="button">Search</button>
</div>
I don't think this is standard html - maybe an extension.
I can get to the button object - but calling obj.click() on it doesn't work.
The document also has this header - maybe that'll identify the document type - also has a lot of class names starting with ng- prefix.
<meta http-equiv="X-UA-Compatible" content="IE=edge">
More info...this is a third party web-page and I'm injecting javascript into it.
I entered something into an INPUT field and then would like to simulate a button press.
Pure javascript.
Created a Sample Demo in Stackblitz for Reference
In Angular, we can get access to any HTML elements using #ViewChild &ElementRef. We also have to add an unique identifier by prefixing # in the HTML element that you want to access programmatically.
In HTML:
<button class="btn btn-primary primaryBtn" #search type="button">Search</button>
In TS:
import { Component, ViewChild, ElementRef } from '#angular/core';
.
.
export class YourComponent{
.
.
#ViewChild('search') search: ElementRef;
.
.
.
. // In your function
this.subContent.nativeElement.click();
}
JavaScript Option
If you want to do this with pure JavaScript you could add an ID to the button and do this:
document.getElementById("myButton").click();
jQuery Option
If I were to do this with jQuery I would write this piece of code:
<script>
$(document).ready(function() {
$('.submitBtns button').click();
});
</script>
Now the problem with this is that if you have several forms on your page it would click all of the buttons that are identified using the $('.submitBtns button').click(); selector. You could probably add an ID to this button if you have access to the code. And just change it to:
<script>
$(document).ready(function() {
$('#myButton').click();
});
</script>
If you require to simulate a click to trigger events related to the click, but not actually click the button, you could use $("#myButton").trigger("click");.
I am assuming that the only JavaScript you are familiar with is what you've read from a browser extension source. There are a few fundamental steps you neglected to mention. Moreover the possibilities you had mentioned were scattered to say the least:
I don't think this is standard html...
It's very standard and valid, flawless HTML.
I can get to the button object - but calling obj.click() on it doesn't work...
It isn't very clear as how obj was obtained from obj.click().
There are other scattered snippets of info... ng-* classes are Angular -- you are correct. The <meta> has no relevance to the issue at hand.
More info...this is a third party web-page and I'm injecting JavaScript into it.
I entered something into an INPUT field and then would like to simulate a button press.
This is normally not possible unless you have editing privileges to said third-party site. I believe browser extensions can do so but it doesn't actually edit the site itself it's just what the browser is rendering just for the user.
Demo
Note: details are commented in demo -- also, I loaded a Bootstrap 4 because I was bored. Bootstrap of course is not required and is purely optional.
// Reference the button
const btn = document.querySelector('.searchButton');
/*
- Register the click event to button
- When clicked the handler function flipStatus() is called
*/
btn.onclick = flipStatus;
/*
- Event handler function passes the event object
- event.target always references the elements that the user
clicked.
- .classList.toggle('active') will add class .active if the
button doesn't have it and remove class .active if the
button has the class .active
*/
function flipStatus(event) {
event.target.classList.toggle('active');
}
/*
- Programatically click the button -- if successful, the
button text should be: "Searching..."
- If clicked by user afterwards the button text should be:
"Search"
*/
btn.click();
.input-group.input-group {
width: 85vw;
margin: 15px auto;
}
.active.active::after {
content: 'ing...';
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" rel="stylesheet" crossorigin="anonymous">
<section class="input-group input-group-lg">
<input class="searchTerms form-control" type="search" placeholder="Enter search terms...">
<section class="input-group-append">
<button class="searchButton btn btn-lg btn-primary" type="submit">Search</button>
</section>
</section>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>

toggle() div element with submitting form data

this is my problem:
After submitting a form I want to see some data from a database (MySQL) for the selected object in a div-element. This element was set to “display:none” when the page starts.
If the user clicks a button the <div> should become visible and the data should be seen. With another click the <div> should become invisible again. To achieve this I use the jQuery function toggle().
If I use an input-element with “type=submit” the form is submitted and I get the data due to the php statements in the <div>. But unfortunately the <div> will disappear immediately. I guess the submit is starting the page again by default and therefore the <div> is set to “display:none” again.
If I use a button-element instead I am able to toggle the <div> but the form is not submitted, the $_POST is not filled and therefore I did not get any data from the database for the object. The idea was to use the name of the object to set a value for an $id variable to start the SQL-statement.
I tried to keep the source code very short and therefore I did not program the database related statements here. This is not the problem – I am able to get data for the object when I used a normal submit and no toggle function for the <div>.
As you can see in the source code I tried it with three variations of input types. But none of it works like I want it to work.
I know that everything would be easy using another extra page to show the data. But I want to realize it with the <div>.
How can I solve this situation?
Here is my source code:
<!DOCTYPE html>
<html>
<head>
<style>
#wbtogdiv {
width:30%;
height:100px;
border:6px solid green;
display:none;
}
</style>
<script language="JavaScript" src="jquery-1.11.2.js"></script>
<script language="JavaScript">$(document).ready(function(){$("#btn").click(function(){$("#wbtogdiv").fadeToggle(20);return true;});});</script>
</head>
<body style="color:#FF004C;">
<!-- I tried also with this
action="<?php $_SERVER['PHP_SELF']?>"
but of course then the page is fired again and the <div> is not visible due to the
CSS-->
<form method="post">
<input type="text" name="customer">
<input type="submit" id="btn" value="submit:Toggle div green">
<!--
<input type="submit" id="btn" value="submit:Toggle div green">
<input type="button" id="btn" value="input button: Toggle div green">
<button type="button" id="btn">Button: Toggle div green</button>
-->
</form>
<div id="wbtogdiv">KASTEN: <?php echo print_r($_POST)?></div>
</body>
</html>
By default, a button element will submit a form, however, you overrode that behavior by setting type="button". (A tad counterintuitive, I agree.)
Since you're already using jQuery, you can take advantage of its built-in AJAX support and override the default form submission behavior. That's an approach that degrades gracefully: if a user is running in an environment that doesn't execute JavaScript, they will submit the form using default browser behavior and still see the results. (You would tweak your CSS to make your div visible by default in that case, and use JS to hide it during page load.) DEMO jsFiddle
var $form = $('form');
var $resultDiv = $('#wbtogdiv');
$resultDiv.hide();
var successHandler = function(data, textStatus, jqXhr) {
$resultDiv.html(data);
$resultDiv.fadeToggle(200);
};
$form.submit(function(ev) {
ev.preventDefault();
if (! $resultDiv.is(':visible')) {
$.post(
'/path/to/your/script',
$form.serialize(),
successHandler
);
} else {
$resultDiv.fadeToggle(200);
}
});
(Also, since this is a test post, it's possible you aren't doing this in your actual code, but for heaven's sake, be extremely careful about a script that reveals information about its internal working to a user, or a script that echoes user-supplied content, unescaped, back to a web page. These are the first steps toward a fairly major security hole.)
You can try this :
Do not use display: none; in CSS and instead do it by JQuery.
<style>
#wbtogdiv {
width:30%;
height:100px;
border:6px solid green;
}
</style>
And this is what you do :
<div id="wbtogdiv" form-submitted = "no">KASTEN: <?php echo print_r($_POST)?></div>
<script>
$(document).ready(function(){
if($('#wbtogdiv').attr('form-submitted') == "no") {
$('#wbtogdiv').hide();
}
});
$(document).ready(function(){
$("#btn").submit(function(event){
$("#wbtogdiv").fadeToggle(20);
return true;
$("#wbtogdiv").attr('form-submitted', "yes");
});
});
</script>

Firefox - hiding focus highlight when not on an input control

We have a requirement whereby a page can consist of a form with several sections. Sections can be added or removed. After the user chooses to add a section the form is submitted and a new page returned with the new section added. The browser should scroll to the top of the new section. This is fine and I have a generic jquery "scroll to anchor" solution working. However, in addition to simply setting window.location(), I also need to ensure that for keyboard users, hitting tab will take them to the next field after the anchor point. I'm using the solution to this question to do this.
This works fine in IE 8/9 but in firefox(15), I'm seeing a little focus square being rendered where the anchor tag is. I would like to suppress this, I tried setting display:none but of course this stops the scroll working. I tried to create a fiddle but jsFiddle doesn't demonstrate the problem as the fddle site itself is interfering with the focus setting - but the same code in the same browser running locally does.
here's a reduced version of my code that demonstrates the problem.
<html>
<head>
<title>test scroll</title>
</head>
<body>
<form>
<div>Blah</div>
<div>
<label for="a">Section 1: <input id="a" type="text" /></label>
</div>
<a id="scrollToAnchorSection2"></a>
<div>
<label for="b">Section 2: <input id="b" type="text" /></label>
</div>
</form>
</body>
</html>
and my jquery
$(document).ready(function() {
/* Find any "scroll to anchors" that have been set */
var anchors = $('[id*=scrollToAnchor]:first');
if (anchors.length == 1) {
window.location = "#" + anchors.attr("id");
// Set tab position
anchors.attr("tabindex", -1).focus();
}
});
and css
div {
margin-left:5em;
}
As requested...
the Blur function takes care of the input lost focus.
$('input').blur(function (){...})? isn't this what you need?
The jquery documentation has this interesting comment.
"The blur event is sent to an element when it loses focus. Originally, this event was only applicable to form elements, such as . In recent browsers, the domain of the event has been extended to include all element types."

Changes made to HTML output (ASP.Net) using JavaScript immediately undone

I have a page on which a list of properties is displayed (i.e houses). This list is made up using CSS. So I've built a second CSS class, which makes the properties/houses align properly in 2 columns. Until now I did this by pressing a button, posting back, and outputting different html (basicly the same, but with other Css class references).
Now I found this question on SO and I implemented a basic scenario. A div with the class "yellow" is written to the html page, and a button changes this class to "red". This happens, but the div immediately changes back to class "yellow".
I'm a very very beginner in JS but not a beginning programmer. This would be a great addition to my site, but I can't find a proper answer. I apologize if this question is redundant.
<script type="text/javascript">
function changeView() {
document.getElementById("box").className = " red";
}
Grtz, thanks in advance, Christophe,
By default a button element is of type 'submit' - which will cause your browser to post back to the server.
Try changing the type to button instead.
<input type="button" ....
More info on the difference here... Difference between <input type='button' /> and <input type='submit' />
If your button causes a postback (possibly a server control with an asp: tag), the javascript changes you made will be lost as by default an asp button submits a page to the server as a result of which your page reloads.
If all you need to change the class of a div make it a simple html button like
<input type="button" onclick="changeView()" value="Change" />

Confused about forms and the submit button

I have a form like the following:
<html>
<head>
<title>My Page</title>
</head>
<body>
<form name="myform" action="http://www.abcdefg.com/my.cgi" method="POST">
<div align="center">
<br><br>
<br><input type="submit" value="ABC" tabindex=0><br>
<br><input type="button" value="cancel"><br>
</div>
</form>
</body>
</html>
I would like the form to submit when the ENTER button is pressed and would also like the submit button to have have some color around it to show that it's default.
But it seems that I have to click the tab button to make the submit have blue around it as the default.
Is there some way to make it that the submit button is always the default and always shoes a blue circle around it to indicate this?
Also what if I have other input fields on the same html page but outside of the default. What I need is for the form to always submit when I press enter no matter where I am on that page. Is there some way to do this?
The submit should always be the default — whilst the form is focused, which is difficult here because you have no real input fields. What does this form actually do?
Further than that, don't override browsers' default UI behaviour: you'll just confuse your users.
For your enter-anywhere-submit, I would do it with jQuery. A lil bit of searching led me to this:
Submitting a form on 'Enter' with jQuery?
On forms, only the currently focused element has the blue outline, and this is typically a platform dependent feature.
That being said, you can customize that outline with a little bit of CSS to make the form look consistent across browsers:
form *:focus {
outline:2px solid blue;
}
Now, to make the submit button always show that outline, I would give it a class of "default":
<input type="submit" value="ABC" tabindex="0" class="default">
Then change the above CSS to include that class:
form *:focus, input.default {
outline:2px solid blue;
}
As for submitting the form on hitting enter: so long as an element in the form has focus, hitting enter will submit the form by default. If you want that to happen if the form doesn't have focus, you will need to use a little bit of JavaScript, but I don't recommend it, because as Tomalak says in his answer, you shouldn't change the browser's default behavior.
If you use Jquery you could attach an event handler to the tag HTML (or the document itself). Since events bubble up the DOM, this would intrecept it even if it is outside the form. Then, if the key pressed is RETURN, you submit the form.
$(document).keyup(function(event){
if (event.keyCode == 13){
$('form[name=myform]').submit();
}
});

Categories

Resources