48

I have a form where I'm dynamically adding the ability to upload files with the append function but I would also like to be able to remove unused fields. Here is the html markup

<span class="inputname">Project Images:
    <a href="#" class="add_project_file"><img src="images/add_small.gif" border="0"></a>
</span>
<span class="project_images">
    <input name="upload_project_images[]" type="file" /><br/>
</span>

Right now if they click on the "add" gif a new row is added with this jquery

$('a.add_project_file').click(function() {
    $(".project_images").append('<input name="upload_project_images[]" type="file" class="new_project_image" /> <a href="#" class="remove_project_file" border="2"><img src="images/delete.gif"></a><br/>');
    return false;
});

To remove the input box i've tried to add the class "remove_project_file" then add this function.

$('a.remove_project_file').click(function() {
    $('.project_images').remove();
    return false;
});

I think there should be a much easier way to do this. Maybe i need to use the $(this) function for the remove. Another possible solution would be to expand the "add project file" to do both adding and removing fields.

Any of you JQuery wizards have any ideas that would be great

Matt Coughlin
  • 18,666
  • 3
  • 46
  • 59
Brooke.
  • 3,691
  • 13
  • 49
  • 80
  • Is there a reason you are using project_images as a class and not an ID? – Corey Sunwold Sep 30 '09 at 23:27
  • 3
    Not really, I tend to use classes for elements that may show up more than once on a page and ID for something that's only going to be used once. Here there is no real reason that I'm using a class instead of an ID – Brooke. Sep 30 '09 at 23:49

2 Answers2

56

Since this is an open-ended question, I will just give you an idea of how I would go about implementing something like this myself.

<span class="inputname">
    Project Images:
    <a href="#" class="add_project_file">
        <img src="images/add_small.gif" border="0" />
    </a>
</span>

<ul class="project_images">
    <li><input name="upload_project_images[]" type="file" /></li>
</ul>

Wrapping the file inputs inside li elements allows to easily remove the parent of our 'remove' links when clicked. The jQuery to do so is close to what you have already:

// Add new input with associated 'remove' link when 'add' button is clicked.
$('.add_project_file').click(function(e) {
    e.preventDefault();

    $(".project_images").append(
        '<li>'
      + '<input name="upload_project_images[]" type="file" class="new_project_image" /> '
      + '<a href="#" class="remove_project_file" border="2"><img src="images/delete.gif" /></a>'
      + '</li>');
});

// Remove parent of 'remove' link when link is clicked.
$('.project_images').on('click', '.remove_project_file', function(e) {
    e.preventDefault();

    $(this).parent().remove();
});
Alex Barrett
  • 16,175
  • 3
  • 52
  • 51
  • Thank you, thank you thank you! I've never heard of "live" but I see how that can be handy. Also what's the advantage of using a
  • for the file list. Is this so we can remove just the one file upload we want?
  • – Brooke. Sep 30 '09 at 23:46
  • Yes, it's so we can easily remove each input individually. It's also a more semantic representation of your content (a list of files). You could just as easily wrap them in `span` or `div` tags if you preferred. – Alex Barrett Sep 30 '09 at 23:51
  • Oh, and `live` is only a feature in the most recent versions of jQuery (v1.3+) - it's not suprising you haven't heard of it. – Alex Barrett Sep 30 '09 at 23:53
  • 11
    .live is deprecated, should use .on() from now on. – Lukasz May 14 '12 at 02:52