2

When a form has multiple image inputs and the server side uses their names and/or values to distinguish which one was clicked, it works perfectly in FireFox. However, people often write the whole thing before finding out that HTML specifies that nothing has to be sent, and thus some browsers are not sending it.

It's not about sending any random object, but sending a pair as input_name=input_value. The best worst-case scenario example here would be what I've encountered: A list of elements all in one form and all accompanied by buttons with name="delete" value="<item_id>"

What can I do to fix this problem?

wattostudios
  • 8,666
  • 13
  • 43
  • 57
naugtur
  • 16,827
  • 5
  • 70
  • 113
  • I have had the same problem http://stackoverflow.com/questions/3139491/request-params-request-form-not-working-in-internet-explorer Your answer saved me. God bless you. – Syed Salman Akbar Jun 29 '10 at 14:43
  • IE is awesome. If you do `` IE will post the Y coordinate of the image that you clicked on! – teynon May 14 '13 at 17:07

5 Answers5

5

Per the HTML spec, clicking on an IMAGE input will return the parameters:

name.x=x-value and name.y=y-value where "name" is the value of the name attribute

with x-value and y-value corresponding to the click position.

Sure, the server code to deal with this will be a little annoying, but you could just check all the query parameter keys with a regular expression:

/^(.*)\.[xy]$/

to search for the IMAGE input keys to determine which IMAGE was clicked.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
  • This is what I put in my answer in the link to a half-solution. The question is about name AND value. If it wasn't it would be a duplicate question – naugtur Mar 01 '10 at 16:24
  • @naugtur: might want to further clarify your question then. At the moment it says "names and/*or* values" and you talk about detecting which image was clicked... which the way I read it, means that this answer is perfectly correct (and the "right" way to do it per the html spec - plus it will work without javascript). – Alconja Mar 01 '10 at 22:45
  • @naugatur: it's worth noting that there's a one-to-one mapping between 'name' and 'value'. Depending on your application, it may be sufficient to capture the 'name' from the query-string and use that to infer the 'value' on the server, since the 'value' is not user changeable. Yes... there are some problems with this approach if you have a generic handler for these forms (and so inferring a value from a name is inappropriate)... but it may be appropriate for *some* applications – Dancrumb Mar 02 '10 at 16:31
  • 1
    If you want to distinguish between inputs, you can given them unique names, i.e. `name="foo" value="bar"` becomes `name="foo_bar" value="bar"`. You can then do something on the server along the lines of `foreach my $key (keys %params) { if ($key =~ /^foo_(.+)\.y$/) { $value = $1; } }` – Quentin Mar 03 '10 at 09:53
3

I tried with this sample:

<form action="#" method="GET">
  <input type="text" name="t" value="Text here"><br>
  <input type="image" name="a" value="1" src="http://sstatic.net/so/img/logo.png"><br>
  <input type="image" name="b" value="2" src="http://www.gravatar.com/avatar/c541838c5795886fd1b264330b305a1d?s=32&d=identicon&r=PG"><br>
</form>

And I get the following urls:

  • FF 3.6: x.html?t=Text+here&b.x=19&b.y=17&b=2#
  • IE 8: x.html?t=Text+here&b.x=22&b.y=18
  • IE 7: x.html?t=Text+here&a.x=185&a.y=51
  • Opera 10: x.html?t=Text+here&a.x=107&a.y=53#
  • Chrome: x.html?t=Text+here&b.x=20&b.y=17&b=2#

So it seems that all the browsers are sending something image related, even if it isn't the image name directly. Since you need to scan for all the image names that you expect to see you can just scan for imagename.x instead. This seems to be how the spec indicates it should work.

Mr. Shiny and New 安宇
  • 13,822
  • 6
  • 44
  • 64
  • I bolded the important fact that it's not about sending something. Moreover - I link to an external solution that says image.x and image.y are posted. – naugtur Mar 01 '10 at 22:36
  • @naugtur: The spec doesn't work the way you want it to. The simplest thing for you to do is to code your app according to the spec. Which button is clicked is easily detected by looking at the parameter list. You can fake it with javascript but it's simpler if you don't. – Mr. Shiny and New 安宇 Mar 02 '10 at 15:59
  • I'm starting to wish I hadn't posted it... This question is all about a hack that I found to easily fix up applications that someone did for FF only, and now they call You to make it work elsewhere. I wanted to share it, as I didn't find any value-sending solution when I needed and the problem was posted in lots of places. I really don't need that question posted here. I posted it after solving just to help people out. – naugtur Mar 03 '10 at 09:07
2

Using the type="image" is problematic because the ability to pass a value is disabled for some stupid lack of reason. Anyways & although it's not as customizable & thus as pretty, you can still use you images so long as they are part of a type="button".

<button type="submit" name="someName" value="someValue"><img src="someImage.png" alt="SomeAlternateText"></button>
Augusto
  • 779
  • 5
  • 18
BoyBlueSky
  • 529
  • 4
  • 4
2

The problem was half solved up to now: like here

But it didn't allow to get the value!

The correct answer is:

$('input[type=image]')
.unbind('mousedown')
.mousedown(function(){ 
  $(this).after('<input type="hidden" name="'+$(this).attr('name')+'" value="'+$(this).attr('value')+'" />'); 
});

This code creates a hidden duplicate of the input when user starts clicking it. The unbind('mousedown') is to secure it happens once even if You put the code in multiple places in a weird application and it might be called more than once.

I recommend putting it in $(document).ready();

naugtur
  • 16,827
  • 5
  • 70
  • 113
  • I hope this saves some people a lot of rewriting someone else's code. – naugtur Mar 01 '10 at 16:17
  • 1
    This breaks if JavaScript is not available. – Quentin Mar 03 '10 at 09:49
  • Oh please... When javascript is disabled it changes nothing and nothing breaks. I set up the question and answered it at once. Just wanted to post a solution for people with that same kind of problem, as it was nowhere mentioned in discussions on this topic. Now You people made me want to delete it. Does it bother You that I try to help people dealing with ill-designed application interfaces like one I am dealing with? – naugtur Mar 03 '10 at 10:09
  • 2
    Oh please. The JS isn't a cosmetic enhancement. It isn't a usability enhancement. The whole point of it is to add data to a form submission that the (badly written) server side script requires and isn't sent, by default, by all browsers. If it doesn't run, the data isn't sent to the server, and it doesn't work. That is "something" and "broken". – Quentin Mar 03 '10 at 13:04
  • You didn't answer the question at the end, but it looks like the answer is yes. If so - vote to delete my answer and I will vote too. I don't have any need to keep this solution here. – naugtur Mar 03 '10 at 13:42
  • 1
    Don't understand the downvotes here. This is indeed a good solution to the problem. +1 I will note that the issue only rears it's head in Internet Explorer. – Domenic D. Apr 15 '13 at 02:42
2

I think I am/was having a similar problem. I wanted to click on an thumbnail and have it enlarged on a different page. I was trying to do this with PHP alone but I finally had to use the tag with the . Worked great for FF3 and safari but the INPUT IMAGE values did not post for IE9 or FF9. My work around was to put each image in its own form and then also use a hidden input to send the needed data.

<table>
   <tr>
     <td>
        <form method="post" class="form_photo">
            <input type="image" name="img_photo" value="does nothing in IE9 or FF9" />
            <input type="hidden" name="photo" value="nameoftheimage.jpg" />
        </form>
        <form method="post" class="form_photo">
           <input ...>
           <input ...>
        </form>
        <form> ...
  </td>
</tr>

Then I discovered the forms displayed vertical, making it very odd. CSS to the rescue.

.form_photo { display:inline; }

seems to have solved the vertical problem. Now the user can click on the thumbnail and the value now passes in all the browsers I have access to testing.