Can I make an svg image button?
Asked Answered
C

7

24

Is there any way of making a POST request when an svg image is clicked?

My best attempt so far looks like:

<form action="/test-button" method="POST">
   <input name="Submit" type="submit" value="Submit" /> 
   <svg  >
     <rect width="100" height="100" >
   </svg> 
</form>

Which is a black rectangle with a submit button next to it.

I want to allow people to choose between several images, so this may be an ok solution, but is there any way of making an image which, when clicked, will fire off a POST?

Extra points for not using javascript.

Cromagnon answered 30/11, 2012 at 17:14 Comment(0)
C
27

Warning: This is a little hacky, but as far as I know it's 100% legit, and doesn't need javascript.

Since the label element can also be used to control it's associated input, you could try something like this:

<form action="/test-button" method="POST">
  <label>
   <input type="submit" name="image" value="one">
   <svg><rect width="100" height="100"></rect></svg> 
  </label>
  <label>
   <input type="submit" name="image" value="two">
   <svg><rect width="100" height="100"></rect></svg> 
  </label>
</form>
 ​

Then hide the submit buttons with CSS. You can put anything in the label that you want.

When you click on whatever's in the label, it will trigger the submit button inside it and submit the form, with the button's value in the POST array.

There is also an <input type="image">, but that's for an entirely different purpose (tracking coordinates of where it was clicked).

Cappella answered 30/11, 2012 at 17:29 Comment(7)
This is neat! Thanks Wesley!Cromagnon
I'm intrigued by the <input type="image"> thing. How do I get that image to be an inline svg rather than a separate file?Cromagnon
You'd have to use src to link to an svg file in order to use that. I'm pretty sure it's not what you want, since those input types have a very specific purpose (tracking coordinates of click). You might also want to go with a simple <input type="radio"> setup and a single submit button, but it's an extra click for the user.Cappella
This appears to work brilliantly in Chrome, but not in Firefox or Epiphany. Is that expected or have I done something wrong?Cromagnon
Not sure, it works for me in every browser I tried including IE and Firefox. Try this: jsfiddle.net/XKZJc/1Cappella
That works fine in all three. So I must have screwed something up somehow in my actual app. Sorry to mess you about!Cromagnon
In fact it turns out that Firefox and epiphany are sensitive to the exact order of the elements in a way that Chrome isn't. But after messing about I've got it working now in all three. Thanks!Cromagnon
M
18

This seems like a great use case for the <button> element.

<form action="/test-button" method="POST">
   <button>
      <svg>
         <rect width="100" height="100" >
      </svg>
   </button>
</form>

Clicking the button element performs the exact same job as input[type="submit"], so you can replace the input entirely. If you go this route, you may also consider putting a text label inside the button and/or a title inside the svg for accessibility purposes.

Mudlark answered 11/7, 2016 at 16:19 Comment(2)
This is great. Is there a way of using different SVGs for different pseudo-classes? e.g., :hover, :activeAcceleration
Possibly! I imagine you can render multiple SVGs inside the button and show/hide them on state change using CSS. But that’s a bit of markup bloat - if all you’re trying to do is make minor changes to the SVG (such as change the color), you could simply style the SVG’s fill property like button:hover svg { fill: red; }.Mudlark
A
4

It's quite impossible without JS, but you can use JS to do it. Attached an onclick() and just use: document.getElementById('formID').submit();.

HTML:

<form action="/test-button" method="POST" id="submittingForm">
   <input name="Submit" type="submit" value="Submit" /> 
   <svg onclick="submitForm();">
     <rect width="100" height="100" >
   </svg> 
</form>

and JS (goes within your <head></head> tags):

<script type="text/javascript">
    function submitForm()
    {
        document.getElementById("submittingForm").submit();
    }
</script>
Auden answered 30/11, 2012 at 17:17 Comment(2)
Ok, but I know nothing of javascript. How do I attach this thing?Cromagnon
Well, you already have the answer above, but if you ever want to use JS (which you should, as it's very versatile), I've edited my answer with the code.Auden
C
4

This, maybe:

<form action="/test-button" method="POST">
    <input type="image" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIi8+PC9zdmc+">
</form>

Jsfiddle: http://jsfiddle.net/Xawuv/

Cerargyrite answered 30/11, 2012 at 17:36 Comment(2)
Note that base64 encoding can increase the size of the SVG unnecessarily - you can instead keep it as UTF-8 and just embed the SVG. <input type="image" src='data:image/svg+xml;utf8,<svg>...</svg>'>. This has the added bonus of requiring one less step when creating this SVG button. css-tricks.com/probably-dont-base64-svgCiborium
This works all the way down to IE 9 and in the modern versions of Firefox I've tried. Thank you.Ondrej
I
2

This is a simple button with a lightning inside the box.

 <svg x="167" y="8" cursor="pointer" width="30" height="30"   visibility="visible" >
                <g id="Flash">
                    <g fill="#FFCC00"  stroke="#D57300" stroke-width="2" >
                        <path stroke-linecap="round" d="m 10.311873 9.0776039 9.400261 -7.988867 -0.05562 6.2501137 -2.224914 0.093987 -0.05562 5.5452134 11.402682 -0.04699 -18.522406 16.024725 0.05562 -6.015145 2.169291 -0.09398 -0.05562 -5.874165 -11.51392928 0.04699 z"/>
                    </g>
                </g>    
                <rect width="30" height="30"  opacity="0"  fill="transparent"    fill="url(#Flash)" id="Flash_Button"  onclick="Flash(evt);" />     
    </svg>

and here is the script for the fucntion when you click

function Flash(){
// post whatever you want inside here

}

The problem when you create a button and inside it has lines and when you put to the parent element the onclick you don't click all the svg element but you click separately and all children inside. so you need to create a rect inside the svg with the width and the height of the parent element and hide it, and after put there the onclick!

Indopacific answered 12/7, 2013 at 21:40 Comment(0)
D
0

Some answers forgot to make the input hidden. This should work perfectly:

Just copy paste.

<label class="cursor: pointer;">
    <input type="submit" name="mysubmit" value="val1" style="display: none;">
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 
fill="currentColor" class="bi bi-arrow-down-up" viewBox="0 0 16 16">
        <path fill-rule="evenodd" d="M11.5 15a.5.5 0 0 0 
         .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 
         4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5zm-7-14a.5.5 0 0 1 
         .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4- 
         4a.5.5 0 0 1 .708-.708L4 1 
         3.293V1.5a.5.5 0 0 1 .5-.5z"/>
    </svg>
</label>


            
Darindaring answered 5/1, 2022 at 3:37 Comment(1)
I believe the name of the property on the label tag is style. Right now it says class.Scission
R
0

Simply add onClick to svg

<svg onClick={addAddress}>
.....
</svg>
Revolutionize answered 8/10, 2023 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.