2

I have the following code which displays the image previews. But when I select new images or say when I change images then on change the previously selected images preview should be removed and only new images should show up in the preview. But its not happening. Currently, if I select 3 images then the preview shows up. But when I select more images then the preview adds up to the previous images.

Also please tell me how can I get values of <img id="imgs"> to insert in the database rather than the values from <input type="file" name="files[]" multiple="multiple" id="file-5">. Please help.

HTML:

  <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" id="newstatus" runat="server" enctype="multipart/form-data">
        <textarea name="status" class="textarea newstatuscontent" placeholder="What are you thinking?"></textarea>
        <input type="file" name="files[]" multiple="multiple" id="file-5"><br />
        <img id="imgs"><br />
        <input type="submit" name="post" value="Post" class="post-btn" id="submit" />
    </form>

Jquery:

$(document).ready(function(){
     $("#file-5").on('change',function() {
     var fileList = this.files;
     for(var i = 0; i < fileList.length; i++){
          var t = window.URL || window.webkitURL;
          var objectUrl = t.createObjectURL(fileList[i]);
          $('.removeimg').fadeIn();
          $('#imgs').append('<!--span class="img_'+i+'" onclick="del('+i+')" style="cursor:pointer; margin-right: 3px;"><b>x</b></span--><img class="img_'+i+'" src="' + objectUrl + '" width="150" height="150" style="margin-right: 3px;">');
          j = i+1;
          if(j % 3 == 0)
          {
            $('#imgs').append('<br>');
          }
        }
    });
});

Ajax code used in insert the data into the database:

$(function() {
    $("#submit").click(function() {
        $(this).val("Please wait...");

        var textcontent = $(".newstatuscontent").val();
        /*if(media == ''){*/
            if(textcontent == ''){
                $('.cap_status').html("Status cannot be empty. Please write something.").addClass('cap_status_error').fadeIn(500).delay(3000).fadeOut(500);
                $("#submit").val("Post");
            }else{
        /*}else{*/
                $.ajax({
                    type: "POST",
                    url: "post-status.php",
                    data: {content:textcontent},
                    cache: true,
                    success: function(html){
                        $("#shownewstatus").after(html);
                        $(".newstatuscontent").val('');
                        $("#submit").val("Post");
                    }  
                });
            }
        //}
        return false;
    });
});
  • You need to reset the file input http://stackoverflow.com/questions/829571/clearing-an-html-file-upload-field-via-javascript – mplungjan Nov 21 '16 at 06:57

2 Answers2

0

The img element is not a container. You should use a div element instead like this:

<div id="imgs"></div>

Then to have all images removed whenever the user selects new images, simple use jQuery empty (before the for loop) on your container div#imgs to remove all the images it contains:

$('#imgs').empty();

A full working example:

function del(index) {
    $('div.img_'+index).remove();
    updateFiles();
}

function updateFiles() {
    var fileIndexes = $('#imgs > div').map(function() {
        return $(this).data('index');
    }).get().join(",");
    $('#files_selected').val(fileIndexes);
}

$(document).ready(function() {
    $("#file-5").on('change', function() {
        var fileList = this.files;
        $('#imgs').empty();
        for (var i = 0; i < fileList.length; i++) {
            var t = window.URL || window.webkitURL;
            var objectUrl = t.createObjectURL(fileList[i]);
            $('.removeimg').fadeIn();
            $('#imgs').append('<div data-index="' + i + '" class="img_' + i + '"><span class="img_' + i + '" onclick="del(' + i + ')" style="cursor:pointer; margin-right: 3px;"><b>x</b></span><img class="img_' + i + '" src="' + objectUrl + '" width="150" height="150" style="margin-right: 3px;"></div>');
            j = i + 1;
            if (j % 3 == 0) {
                $('#imgs').append('<br>');
            }
        }
        updateFiles();
    });
});
#imgs > div {
    display:inline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" id="newstatus" runat="server" enctype="multipart/form-data">
    <textarea name="status" class="textarea newstatuscontent" placeholder="What are you thinking?"></textarea>
    <input type="file" name="files[]" multiple="multiple" id="file-5"><br />
    <div id="imgs"></div>
    <input type="submit" name="post" value="Post" class="post-btn" id="submit" />
    <input type="hidden" name="files_selected" id="files_selected" />
</form>

EDIT

The javascript files property is readonly, so to do what you want, you'll have to have a hidden input and update it with a string of comma separated indexes that point to the selected files array in PHP. Also, if you add display: inline CSS rule, then you'll have the divs on the same line and break every 3 images as your code works. See my updated snippet code for the whole working example.

To see the exact out put, use the following PHP code:

<pre><?php
print_r($_POST);
print_r(explode(',', $_POST['files_selected']));
?></pre>

<pre><?php
print_r($_FILES);
?></pre>

OUTPUT

Array
(
    [status] => 
    [post] => Post
    [files_selected] => 0,2
)
Array
(
    [0] => 0
    [1] => 2
)
Array
(
    [files] => Array
        (
            [name] => Array
                (
                    [0] => 1c.jpg
                    [1] => 1e.jpg
                    [2] => 2c.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                    [2] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /var/www/clients/client3/web35/tmp/phpzkmzlf
                    [1] => /var/www/clients/client3/web35/tmp/php9HuwoF
                    [2] => /var/www/clients/client3/web35/tmp/phpZiOur5
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                    [2] => 0
                )

            [size] => Array
                (
                    [0] => 11384
                    [1] => 7348
                    [2] => 12700
                )
        )
)

You have all selected files indexes to an array by making this call $selected = explode(',', $_POST['files_selected']

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • working but plz see the HTML part of this fiddle for questions.. https://jsfiddle.net/u8038e3y/ –  Nov 21 '16 at 11:30
  • how to fetch the names from
    to insert into database as a comma seperated value?
    –  Nov 21 '16 at 13:19
  • with #files_selected i guess? –  Nov 21 '16 at 13:21
  • Since you have the indexes into the `$selected` array, you can now use these indexes to access the files like this `$_FILES['files']['name'][$selected[0]];` will return the filename of the first selected image. Do you want me to update my answer? – Christos Lytras Nov 21 '16 at 13:23
  • Yes sure.. will be glad if its makes easy for me :) –  Nov 21 '16 at 13:34
  • let me update the question first.. i will update the ajax code I am using to insert the content to the database... please implement with it.. :) –  Nov 21 '16 at 13:35
  • question updated.. please check the ajax code.. I want the image names to be sent to the PHP file as a comma separated value like abc.jpg, 123.jpg, def.jpg to be inserted into the database.. thanks for the help :) –  Nov 21 '16 at 13:37
  • I can point you how to retrieve the filenames, but then you'll have to handle the rest of the code. I'll update my answer soon. – Christos Lytras Nov 21 '16 at 13:45
  • @ShubhamJha you cannot pass the files data when using ajax calls. You have to send the post data by submitting the form to the actual PHP server file. You can only retrieve the file names if you don't reload the page. Is it that you want? Just the file names? – Christos Lytras Nov 21 '16 at 14:16
  • yes so that I can insert it to database to match with the images uploaded later and display them later.. by the way keeping the same file names might make the chances of renaming like two people uploading a.jpg will get a.jpg and a(1).jpg right? why not to rename the file and insert the renamed file name to database and save the file with that very name? can it be done? possible? @ChristosLytras –  Nov 24 '16 at 11:55
0

Some edit you need to do in your code. Those are: 1.> Under <form> tag remove the <img> tag and add this <div id="imgs"></div> tag.

2.> Inside your onchange function() at from first line

$(document).ready(function(){
     $("#file-5").on('change',function() {
    var length= $('[id^=image]').length;
     for(var i = 0; i < length; i++){
        var imgTag = document.getElementById("image" + i);
       imgTag .parentNode.removeChild(imgTag );
    }
     var fileList = this.files;
     for(var i = 0; i < fileList.length; i++){
          var t = window.URL || window.webkitURL;
          var objectUrl = t.createObjectURL(fileList[i]);
          $('.removeimg').fadeIn();
          $('#imgs').append('<span id="image'+i+'" class="img_'+i+'" onclick="del('+i+')" style="cursor:pointer; margin-right: 3px;"><b>x</b><img class="img_'+i+'" src="' + objectUrl + '" width="150" height="150" style="margin-right: 3px;"/></span>');
          j = i+1;
          if(j % 3 == 0)
          {
            $('#imgs').append('<br>');
          }
        }
    });
});

I am adding the tag inside the . The span tags will have id like "image1","image2",... And whenever any changes occur in the selection then the old image are deleted and new images are added. You can edit your del() function to take input as the id of the span tag and whenever u click on the tag it should call the del('image1') deleted the corresponding span tag which contain the clicked image.

You should edit the line: $('#imgs').append('

  • plz see the HTML part of this fiddle for questions.. https://jsfiddle.net/u8038e3y/ –  Nov 21 '16 at 12:49
  • complete code already given above... nothing more than that i m using.. –  Nov 24 '16 at 11:49