I want to submit a simple form, but instead of using a button, I want to do it through a link. Since I'm not using JSF, I cannot use the h:commandLink component. I do not know how to do it in plain JSP/HTML. Any ideas?
There are two ways.
Use CSS to style the button to look like a link.
<input type="submit" value="link" class="link">
with for example
.link {
margin: 0;
border: 0;
background: none;
overflow: visible;
color: blue;
cursor: pointer;
}
Or, use JavaScript to grab the form and submit it.
<form id="formid">
link
</form>
It only won't work in browsers with JS disabled. It's however what JSF h:commandLink is doing under the covers (JSF components just generates plain HTML/CSS/JS after all, the webbrowser doesn't understand anything else).
Related
I have a standard "Contact Form 7" Send File as Attachment Form on wordpress:
<label>UPLOAD FILE
[file uploadedfile]
</label>
I am already searched stackoverflow etc etc etc.
After 2hrs I gave up :(
How can I change the Color of the background and the font size easily?
If I get in touch with the file form control directly it will blast up like a giant. This is not useful for computers and never responsiv für mobile.
And as a second question.
Is it possible to format the "No file selected" differently from the "Search computer (Durchsuchen)"?
Although it's difficult to style a file input itself due to browser compatibility, you can instead apply styling to its label to achieve the same result.
Take a look at this example input:
<label for="fileInput">
Upload file
</label>
<input id="fileInput" type="file">
Because the label is directly linked to the input, it will open the file browser once you click on either the label or the input. Since that's the case, you can hide the input itself and only display the label.
<style>
input[type="file"] {
display: none;
}
</style>
Now that you're left with only the label, you can apply styling to the element to make it look more like a button instead of a label. Take a look at this basic example of CSS you could use to style the label.
<style>
label[for="fileInput"] {
border: 1px solid black;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
</style>
Here's what you'll end up with after hiding the input and add styling to the label. Of course, this is just a basic example, but there are almost no limits to what you can achieve through CSS, so you could style the label any way you'd like.
Putting it all together, the final code for this implementation will look something like the following:
input[type="file"] {
display: none;
}
label[for="fileInput"] {
border: 1px solid black;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
<!doctype html>
<html>
<head>
<title>File upload styling</title>
</head>
<body>
<form method="post">
<label for="fileInput">
Upload file
</label>
<input id="fileInput" type="file">
</form>
</body>
</html>
Since you're using WordPress, you'll just end up putting the CSS in your theme styles, but the implementation should be almost identical as to what it would be with a static HTML site.
I'm trying to replace checkbox/radio inputs with icons. For this, I need to hide the original checkbox/radio. The problem is, I also want the form to properly support keyboard input, i.e. let the input remain focusable by Tab key and selectable using Spacebar. Since I'm hiding the input, it cannot be focused, so instead, I'm trying to make its <label> focusable.
This documentation and various other sources led me to believe I can do that using tabindex attribute (corresponding to HTMLElement.tabIndex property). However, when I try to assign tabindex to my label, it remains as unfocused as ever, however much I try to Tab to it.
Why doesn't tabindex make the label focusable?
The following snippet demonstrates the issue. If you focus the input with your mouse and try focusing the label using Tab, it doesn't work (it focuses the following <span> with tabindex instead).
document.getElementById('checkbox').addEventListener('change', function (event) {
document.getElementById('val').innerHTML = event.target.checked;
});
<div>
<input type="text" value="input">
</div>
<div>
<label tabindex="0">
<input type="checkbox" id="checkbox" style="display:none;">
checkbox: <span id="val">false</span>
</label>
</div>
<span tabindex="0">span with tabindex</span>
(The JavaScript code just allows to see that clicking on the label properly (un)checks the checkbox.)
Why doesn't tabindex make the label focusable?
Short Answer:
Label is focusable.
TabIndex won't make any difference.
Welcome to the world of browser/agent inconsistencies.
tl;dr;
The label (Ref) element is very much focusable. Its DOM Interface is HTMLLabelElement which derives from HTMLElement (Ref) which in turn implements GlobalEventHandlers (Ref) and hence exposes the focus() method and onfocus event handler.
The reason you are unable to get hold of proper specification / reference document for labels focus behaviour, is because you might have been looking at HTML5 Specs. Interestingly, HTML5 refs do not state anything relating to that, which adds to the confusion.
This is mentioned in the HTML 4.01 Ref here: http://www.w3.org/TR/html401/interact/forms.html#h-17.9.1
Specifically near the end of section 17.9.1 and just before 17.10:
When a LABEL element receives focus, it passes the focus on to its
associated control.
Also, elsewhere (I am unable to get hold of that part of the ref) I have read that it depends on the implementing agent. (Don't take my word for that, am not too sure).
However, what it means is that when you focus a label (or a label received a focus), that focus is passed on to its associated labeleable control. This will not result in two different focuses, but one focus on the input (in your case a checkbox). Because of this behaviour, tabindex property cannot play a role.
There is also a test suite by W3C for website accessibility (WAAG) here: http://www.w3.org/WAI/UA/TS/html401/cp0102/0102-ONFOCUS-ONBLUR-LABEL.html which, discusses the implementation of onfocus and onblur for a label. Ideally a keyboard or an assistive technology that emulates the keyboard should implement this. But...
This is where the browser inconsistencies play their role.
This can be demonstrated by this example. Check the following snippet in different browsers. (I have tested it against IE-11, GC-39 and FF-34. All of them behave differently.)
Click the button "Focus Label"
It should focus the label, then pass the focus and highlight its associated checkbox outline in blue.
Chrome-v39 works. IE-v11 it doesn't (somehow html and body do respond to :focus). FF-v34 it works.
Talking about browser inconsistencies, try using the "access key" L. Some browsers will focus the checkbox whereas some will click it i.e. pass the action to it.
Here is a fiddle to test it: http://jsfiddle.net/abhitalks/ff0xds4z/2/
Here is a snippet:
label = $("label").first();
$("#btn").on("click", function() {
label.focus();
});
* { margin: 8px; }
.highlight { background-color: yellow; }
:focus {
outline: 2px solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="txt" type="text" value="input" /><br />
<label for="chk" accesskey="L">Checkbox: </label>
<input id="chk" type="checkbox" /><br />
<input id="btn" type="button" value="Focus Label" />
Hope that clears up your doubts.
.
Your problem:
Now focussing (sic) on your original problem of not being able to focus a label, because you want to style a checkbox differently by placing an icon kind of thing in its place.
In order to do that, one option for you is to not hide it completely by doing a display:none;. Rather, make it 1x1 pixel and shove it under your icon. This way it will still receive focus naturally and yet be effectively hidden.
For example, if your icons are a checkmark and a cross, then change the position of the checkbox and make the icons out of ::before or ::after pseudo-elements on the label. That will cause the checkbox to still receive focus, and make the icon respond to that. That will give the apparent illusion of the icon taking the focus.
Demo Fiddle: http://jsfiddle.net/abhitalks/v0vxcw77/
Snippet:
div.chkGroup { position: relative; }
input#chk {
position: absolute;
width: 1px; height: 1px;
margin: 0; margin-top: 4px; outline: none;
border: 1px solid transparent; background-color: transparent;
}
label::before {
content: '\2714';
position: relative;
width: 18px; height: 18px;
background-color: #fff;
margin-right: 8px; padding: 2px;
display: inline-block;
border: 1px solid transparent;
}
input#chk:checked + label::before {
content: '\2716';
}
input#chk:focus + label::before {
border: 1px solid #00f;
}
<input id="txt" type="text" value="input" /><br /><br />
<div class="chkGroup">
<input id="chk" type="checkbox" />
<label for="chk" accesskey="L">Checkbox</label>
</div>
.
Since this old post is one of the top google results for html label tabindex I want to add my very simple working solution. As #Abhitalks mentioned in the accepted answer, the focus of a label is passed to it's associated control. So to bypass this behavior, just add a tabindex to the label and use event.preventDefault() in a focus EventListener.
#Heretic Monkey kind of had the right idea in his answer but you don't need a wrapper element to achieve this. You will, however, need to manually forward any required keystrokes (like spacebar) through.
For example:
'use strict';
let field = document.getElementById('hidden-file-chooser');
let label = document.querySelector('label[for=hidden-file-chooser]');
// prevent focus passing
label.addEventListener('focus', event => {
event.preventDefault();
});
// activate using spacebar
label.addEventListener('keyup', event => {
if (event.keyCode == 32) {
field.click();
}
});
#hidden-file-chooser {
display: none;
}
input[type=text] {
display: block;
width: 20rem;
padding: 0.5rem;
}
label[for=hidden-file-chooser] {
display: inline-block;
background: deepskyblue;
margin: 1rem;
padding: 0.5rem 1rem;
border: 0;
border-radius: 0.2rem;
box-shadow: 0 0 0.5rem 0 rgba(0,0,0,0.7);
cursor: pointer;
}
<input type="text" placeholder="Click here and start tabbing through ...">
<input id="hidden-file-chooser" type="file">
<label for="hidden-file-chooser" tabindex="0"> Select a File </label>
<input type="text" placeholder="... then shift+tab to go back.">
P.S: I used input[type=file] in my example because that's what I was working on when I ran across this issue. The same principles apply to any input type.
Edit: The following was a misreading of the spec:
Looking that the full
specification,
you'll see that there is something called tabindex focus
flag,
which defines if the tabindex attribute will actually make the field
"tabbable". The label element is missing from that list of suggested
elements.
But then again, so is the span element, so go figure :).
That said, yYou can make the label text focusable by wrapping the whole thing in an another element, or using some JavaScript to force the issue. Unfortunately, wrapping (here in an anchor) can men a fair amount of extra work in CSS and JS to get working like a normal label element.
document.getElementById('checkbox').addEventListener('change', function(event) {
document.getElementById('val').innerHTML = event.target.checked;
});
document.getElementsByClassName('label')[0].addEventListener('click', function(event) {
event.target.getElementsByTagName('label')[0].click();
event.preventDefault();
});
document.getElementsByClassName('label')[0].addEventListener('keypress', function(event) {
if ((event.key || event.which || event.keyCode) === 32) {
event.target.getElementsByTagName('label')[0].click();
event.preventDefault();
}
});
.label,
.label:visited,
.label:hover,
.label:active {
text-decoration: none;
color: black;
}
<div>
<input type="text" value="input">
</div>
<div>
<a class="label" href="#">
<label tabindex="0">
<input type="checkbox" id="checkbox" style="display:none;">checkbox: <span id="val">false</span>
</label>
</a>
</div>
<span tabindex="0">span with tabindex</span>
As previous posters said:
Label focus always goes directly to the input element.
Quite an annoyance if somebody has fancy (but fake) checkboxes, hiding the original ones, with an actual focus for keyboard navigation nowhere to be seen.
best solution I can think of: javascript.
Style-away the actual focus, in favor of a fake one:
input[type=checkbox]:focus {
outline: none;
}
.pseudo-focus {
outline: 2px solid blue;
}
and watch for changes on the (in many scenarios visibly hidden) original checkbox:
$('input[type=checkbox')
.focus( function() {
$(this).closest('label').addClass('pseudo-focus');
})
.blur( function() {
$(this).closest('label').removeClass('pseudo-focus');
});
Full jsfiddle here.
For input type radio or checkbox:
opacity: 0;
height: 0;
width: 0;
min-height: 0;
line-height: 0;
margin: 0;
padding: 0;
border: 0 none;
and the Js above does the trick sweetly.
I 'crafted' this piece of jQuery + html to accomplish the following:
There is a placeholder image that user can click, which causes a file selection dialog to open. Once a file is selected, the corresponding multipart form is uploaded to the server. I am trying to imitate AJAX behavior for this file upload, so I also use an invisible iframe to receive server response.
Let me present the code first, so it would be easier to explain the problem
jQuery("#myInput").change(function () { // Submit form upon file selection
// alert("myInput.val() = " + $('#myInput').val()); // alert 1
$('#form1').submit();
// alert("myInput.val() = " + $('#myInput').val()); // alert 2
});
<form id="form1" action="/do_upload.php" method="post" enctype="multipart/form-data" target="target_frame">
<input id="myInput" type="file" name="userfile" /><br>
</form>
<img src="/img/placeholder.png" onclick="$('#myInput').click();" >
<iframe id="target_frame" name="target_frame" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>
The code works perfectly on new Chrome/Firefox/Safari. (Interestingly it even works if I set visibility: hidden; on myInput. So apparently that's not much of a security concern). However both IE 9 and 10 show the same behavior: clicking the image brings up the dialog successfully, the file path is correctly set in "alert 1", but it is gone in "alert 2", and the form doesn't get submitted. On the other hand, clicking directly on the browse button of myInput properly brings up the dialog and submits the form.
I am absolutely confused by how this behavior can even be possible! Any suggestions on how to fight off the annoying IE would be greatly appreciated :)
I believe it is a safety feature of IE. it won't allow you to access the name attribute of the file input if using another trigger.
You must click the file input for IE and not use another trigger.
Edit: A workaround IE clears input[type="file"] on submit
I decided to go with the method of overlaying a transparent file element over my image. My inspiration came from this page: https://coderwall.com/p/uer3ow. Here is my HTML and CSS that were required:
.file_loader {
position: relative;
overflow: hidden;
border: solid gray 1px;
margin: auto;
width: 300px;
height: 400px;
}
.file_loader .hidden_file {
display: block;
background: white;
font-size: 80px;
height: 100%;
width: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
.placeholder {
height: 100%;
width: 100%;
}
<div class="file_loader">
<img src="/img/placeholder.png" id="placeholder1" class="placeholder" >
<form id="form1" action="/do_upload.php" method="post" enctype="multipart/form-data" target="target_frame">
<input id="myInput" class="hidden_file" type="file" name="userfile" /><br>
</form>
</div>
As you can see the height and width of the "file_loader" class enforce the dimensions of the placeholder image and of the transparent input=file element overlay. There is one thing in this CSS that is truly brilliant, and it came from that link. I'm talking about setting the very large font-size for file element. It is key for making it work in IE, because it happens to make the "Browse" button so gigantic that it fills the whole placeholder. Without changing the font-size, in IE you would end up with only part of the image being able to bring up file dialog (the rest would be a transparent text field). I'll point out that in Chrome/Firefox/Safari this font-size trick is unnecessary, as the whole file element is clickable there.
I am using the Webshims library for polyfilling the validation of a HTML5 form. The problem is that in order for the validation to kick in I have to use an input submit button. This is something that I wish to avoid, since I have a css-styled "linkbutton" for the purpose of saving the form:
<a href="#" id="myLink" class="submit">
<em> </em><span>Save form</span>
</a>
When clicking the "linkbutton" the form submits fine, but the validation never occurs. I use jQuery to submit the form when clicking the link:
$('myLink').click(function(e) {
$('myForm').submit();
});
Is it possible to someway force the validation to occur the same way as when submitting the form with a input submit button?
Webshims implements the form validation API as specified by HTML5. You can read the following bugreport and my answer to it: https://github.com/aFarkas/webshim/issues/103#issuecomment-4298458
Here is a short "workaround" for your problem:
//configure webshims to use customized bubbles
$.webshims.setOptions('forms', {
replaceValidationUI: true
});
//start polyfilling forms feature
$.webshims.polyfill('forms');
$(function(){
$('myLink').click(function(e) {
if($('myForm').checkValidity()){
$('myForm').submit();
}
});
});
But to make this clear, the best way is to use submit buttons. To get submit buttons styled, here is a simple button reset, which should work x-browser:
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input.btn-reset,
button.btn-reset {
overflow: visible;
display: inline-block;
border: none;
padding: 0;
background: transparent;
-webkit-appearance: none;
color: #000;
font-family: arial,helvetica,sans-serif;
cursor: pointer;
}
I have a button in my webpage with below code -
HTML:
<button type="submit" class="checkout-button" id="checkout-button" name="checkout-button"></button>
CSS:
.checkout-button{
width: 130px;
height: 35px;
background: url('../poc2/images/checkout.png') no-repeat;
border: none;
vertical-align: top;
margin-left:35px;
cursor:pointer;
}
Now, the button works fine as I can click on it and have my corresponding php code run; the pointer turns into the hand symbol letting the user clearly know that it is clickable and that its a button.
What I would like to do is to modify the behavior of this button based on some conditions. Example pseudocode:
if flag=1:
/* enable the button, and let the user click it and run the php code */
else:
/* display this button, but don't let any actions take place if the user clicks on it; */
How do I code this enable-disable logic for the button? Basically, I want the button to work as a button under normal situations; and just as a picture without any hyperlink under certain other situations.
You can either do this without JavaScript (requires a page refresh) or with JavaScript and have no refresh.
Simply use the disabled attribute:
<button type="submit" class="checkout-button" id="checkout-button" name="checkout-button" disabled="disabled"></button>
And create a css style for it, if necessary. The example below shows a JavaScript solution. If the variable disableButton is set to true, the button will be disabled, else it can be clicked:
const disableButton = true; //change this value to false and the button will be clickable
const button = document.getElementById('checkout-button');
if (disableButton) button.disabled = "disabled";
.checkout-button {
width: 130px;
height: 35px;
background: #333;
border: none;
vertical-align: top;
margin-left: 35px;
cursor: pointer;
color: #fff;
}
.checkout-button:disabled {
background: #999;
color: #555;
cursor: not-allowed;
}
<button type="submit" class="checkout-button" id="checkout-button" name="checkout-button">submit</button>
You can do it either by modifying the attribute or by adding/removing a class.
Modifying attribute
You will want to switch between <button disabled="true"> and <button disabled="false">
With javascript, it could look like this:
if flag=1:
document.getElementById("your-btn").disabled = true;
else:
document.getElementById("your-btn").disabled = false;
And with jquery, like this:
if flag=1:
$('#your-btn').prop('disabled', true);
else:
$('#your-btn').prop('disabled', false);
Adding/removing class
Add the following css:
.btn-disabled{
cursor: not-allowed;
pointer-events: none;
}
And add/remove a class to the button.
With jquery:
if flag=1:
$('#your-btn').addClass('btn-disabled');
else:
$('#your-btn').removeClass('btn-disabled');
If you don't want jquery, but pure javascript, here is how to do it.
If your circumstance allows you could just remove the content in the action attribute from the form tag. Therefor when a user clicks submit, no action is taken.