4

Below is a script to upload images and save them to the DB.

On one page of the website, there's a table and inside each <li></li>, there is an upload icon where users can add one image.

The issue is the image upload only works for the "highest" empty <li> on the table.

Here, "highest" means the latest <li> saved in the DB (table is sorted by TIME DESC).

For instance, if I want to upload an image to a random <li></li> on the page, once I select an image, nothing happens. But if I select the "highest" empty (empty = no image saved in DB) <li></li>, it works like a charm.

HTML:

<li id="entry<?php echo $recipe_id ?>">
  <div class="addimage_icon" id="upload<?php echo $recipe_id; ?>">
    <form id="upload_icon" action="upload_extra.php" method="POST" 
     enctype="multipart/form-data"> 
       <input  class="upload" id="file" type="file" style="display:none" />   
       <input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>"/>
       <img class="upload_icon" src="/upload_icon.png">
    </form>
  </div>
</li>

JAVASCRIPT (upload gets triggered as soon as one image is chosen):

<script>
   $('.upload_icon').click(function(){
       $(this).parent().find('.upload').click();
   });

    document.getElementById("file").onchange = function() {
    document.getElementById("upload_icon").submit();
}
</script>

PHP:

<?php 
include "includes/connnect.php";
$id = $_SESSION['id'];
$recipe_id = mysql_real_escape_string($_POST['recipe_id']);

if ($_SERVER["REQUEST_METHOD"] == "POST") {

$recipe_id= $_POST['recipe_id'];

//get image attributes

$add = query("UPDATE cookbook SET recipe_pic = '".$location."' WHERE recipe_id =  
'$recipe_id'");

header(Location:"home.php");

}
?>

What's going here ?

Caro_deb
  • 279
  • 1
  • 8
  • 25
  • 2
    `getElementById("file")` => if they _all_ have that `id`... imagine _which_ element get's the bind. Prefer general selectors, like `input.upload[type=file]` for jQuery, and a relative submit (`this.form.submit()`) – Wrikken Sep 24 '13 at 00:01
  • Thanks! I've tried but now i can't select images anymore, Do you mind adding an answer and showing me an example? – Caro_deb Sep 24 '13 at 00:15
  • Put something up on http://jsfiddle.net/ and I'll see what I can fiddle in tomorrow. – Wrikken Sep 24 '13 at 00:17
  • @Wrikken See fiddle: it's now possible to browse and choose an image, but they don't get saved to the DB anymore. http://jsfiddle.net/vGUNW/ – Caro_deb Sep 24 '13 at 03:47
  • 1
    I see no effort in there to implement my suggestion. Are you trying to get me to just give you the code rather then to help you create the code yourself? – Wrikken Sep 24 '13 at 12:03
  • Indeed, for this particular case, i'm looking for a straight up answer so if you want to help and write one, i'll be glad to accept your answer. Thx – Caro_deb Sep 24 '13 at 21:34
  • 1
    This is not _"let's get a patsy to write to code for me"_ site. I would _help_ you to write one, however, if I need to write one _for you_, you'd have to pay me (and no, I'm not available a.t.m.). Good luck finding some other schmuck, I no longer feel inclined to spend my own time on someone who is just out to get others to do the work they were hired to do. – Wrikken Sep 24 '13 at 21:38

5 Answers5

4

There are many, many problems with your question. First of all the HTML you've posted is invalid. I suspect that your Javascript code has a problem with such invalid HTML. However, the following code has not (for your HTML code duplicated once for demonstration purposes):

NodeList.prototype.forEach = Array.prototype.forEach;
document.querySelectorAll('input[type="file"]').forEach(function (file) {
    var click = function() {
        file.click();
    };
    var change = function() {
        console.log('change:', file.value);
    };
    file.form.querySelector('img').addEventListener('click', click);
    file.addEventListener('change', change);
});

http://jsfiddle.net/eBLL5/

All you need is to assign the correct listeners to the correct elements, as you can see, I do not use any ID values because they are duplicated.

I can use as well duplicate IDs in case you think this is not an argument, this is demonstrated in a related answer:

I hope this helps you to get the feets again on the ground so that you can continue to validate the HTML and clean up a little bit.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • Firefox needs a little more help with your invalid HTML, so if you like to test it, it requires a little addition to your CSS: http://jsfiddle.net/3QDyW/ - Just noticed that, it's nothing complicated. – hakre Oct 01 '13 at 10:57
3

It appears that your html form has
<input type="hidden" value="<?php echo $recipe_id; ?>"/>

However, the input field name attribute is not present so the post data stream will not have a definition for $_POST["recipe_id"] field. The undefined value is likely being interpreted by your script as 0 and so only the top or "highest" li image is updated.

If you alter the input field thus:

<input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>"/>

You may have better results...

M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118
sparq
  • 41
  • 2
  • Thanks! It was a mistake when I copy/pasted my code. In my source file, i have the name attribute. So i guess the error doesn't come from that. I'll add it back in my question though, thx for catching that, +1 – Caro_deb Sep 24 '13 at 01:26
1

Just change this part :

document.getElementById("file").onchange = function() {
   document.getElementById("upload_icon").submit();
}

With :

$("#file").change(function(){$(this).parents("form").get(0).submit();})
foxdanni
  • 199
  • 1
  • 19
0

In your HTML, you have:

<form id="upload_icon" action="upload_extra.php" method="POST" 
  enctype="multipart/form-data">

Then your Javascript mentions:

document.getElementById("file").onchange = function() {
  document.getElementById("upload_icon").submit();
}

According to some specifications (HTML4, HTML5), there shouldn't be same IDs on multiple elements. So, when you use an iteration, avoid printing ids without appending something unique on them, like:

<form id="upload_icon<?php print $recipe_id; ?>"
  action="upload_extra.php" method="POST" enctype="multipart/form-data">

Your Javascript can be turned into something like the following. (please mind that you need to call this function after the page is loaded)

function afterPageLoad() {
  var buttons = document.getElementsByClassName("upload");
  for (i = 0; i < buttons.length; i++) {
    buttons[i].onchange = function() {
      this.form.submit();
    }
  }
}

Now, if your PHP code has stopped working, we would need to see that, too, at the part you omitted by writing

//get image attributes

where the $location variable is initiated.

mavrosxristoforos
  • 3,573
  • 2
  • 25
  • 40
  • Thanks for your answer ! If i use your Javascript as is, nothing happens when i click on the upload icon: the pop up window to browse files doesn't show anymore. The 2 lines of Javascript i was using before allowed to browse and upload in one click. Any ideas how to fix this? – Caro_deb Sep 26 '13 at 20:03
  • I never said that you can copy/paste my Javascript. I clearly mention that you need to "call this function after the page is loaded", which would interpret to something like http://jsfiddle.net/vGUNW/8/ – mavrosxristoforos Sep 27 '13 at 03:03
0

In JavaScript provided its submitting the form by finding the element by ID, As in the HTML code the IDs are repeating (not a standard method, IDS can't repeat but class can) so the browser will always submit the last (highest) form only, that's why when adding image to highest row its working and in between its not.

Please check this code out

 <script>
$(document).ready(function() 
{
    id = '';
   $('.upload_icon').click(function(){
        id = $(this).attr('id');
       $(this).parent().find('#file'+id).click();
   });

    $(".upload").change(function () {
        $('#upload_icon'+id).submit();
    });
});
</script>
<style>
.upload_icon {
    cursor:pointer;
}
</style>
<ul>
<?php for($recipe_id=1;$recipe_id<10;$recipe_id++): ?>
<li id="entry<?php echo $recipe_id ?>">
    <div class="addimage_icon" id="upload<?php echo $recipe_id; ?>">
        <form action="upload.php" method="POST" enctype="multipart/form-data" id="upload_icon<?php echo $recipe_id; ?>">
            <input class="upload" id="file<?php echo $recipe_id; ?>" type="file" name="image" style="display:none"/>
            <input type="hidden" name="recipe_id" value="<?php echo $recipe_id; ?>" />
            <img class="upload_icon" src="https://cdn2.iconfinder.com/data/icons/picons-basic-2/57/basic2-036_cloud_upload-128.png" id="<?php echo $recipe_id; ?>">
        </form>
    </div>
</li>
<?php endfor; ?>
</li>

In the HTMl code I have provided have different IDs for each forms (used the $recipe_id as suffix), when ever click event on the upload icon is fired it will check which upload icon is clicked by its attribute Id and then the respective input type file value is changed by finding the element by Id (used the same $recipe_id as suffix here also). On input type change event also same logic is used to fire the respective form.

Hari Swaminathan
  • 616
  • 1
  • 13
  • 27