开发者

"Add another item" form functionality

开发者 https://www.devze.com 2023-02-02 18:22 出处:网络
I have a form that lets a user enter their career history - it\'s a very simple form with only 3 fields - type (dropdown), details (textfield) and year (dropdown).

I have a form that lets a user enter their career history - it's a very simple form with only 3 fields - type (dropdown), details (textfield) and year (dropdown).

Basically I want to include some dynamic functionality whereby the user can enter multiple items on the same page and then submit them all in one go. I had a search on Google and found some examples but they were all based on tables - my markup is based on DIV tags:

<div class="form-fields">

<div class="row">
    <label for="type">Type</label>
    <select id="type" name="type">
      <option value="Work">Work</option>
    </select>
</div>

<div class="row">
    <label for="details">Details</label>
    <input id="details" type="text" name="details" />
</div>

<div class="row">
    <label for="year">Year</label>
    <select id="year" name="year">
      <option value="2010">2010</option>
    </select>
</div>

</div>

So basically the 3 DIV tags with class "row" need to be duplicated, or to simplify things - the div "form-fields" could just be duplicated. I am also aware that the inp开发者_开发问答ut names would have to converted to array format.

Additionally each item will require a "remove" button. There will be a main submit button at the bottom which submits all the data.

Anyone got an elegant solution for this?


One approach is:

$('<span class="add">+</span>').appendTo('.form-fields:last');
$('.add').live('click',
               function(){
                   $('.form-fields:first')
                       .clone()
                       .insertAfter('.form-fields:last');
                   $('.add').remove();
                   $('<span class="add">+</span>')
                       .appendTo('.form-fields:last');
               });

JS Fiddle demo

It's not particularly pretty, though; and as yet doesn't account for the need for unique ids.


HTML:

<div class="form-fields">
  <div class="row">
    <label>Type
      <select name="type[0]">
        <option value="Work">Work</option>
      </select>
    </label>
  </div>
  <div class="row">
    <label>Details
      <input type="text" name="details[0]" />
    </label>
  </div>
  <div class="row">
    <label>Year
      <select id="year" name="year[0]">
        <option value="2010">2010</option>
      </select>
    </label>
  </div>
</div>

JS:

var counter = 0, formFieldsString = '<div class="form-fields"...';

function addNew()
{
  $(formFieldString.replace('[0]', '['+(++counter)+']')).appendTo('#form-fields-parent');
}


I do this quite regularly right now. Here's a rundown of the large elements I use:

  1. Use the templating that comes with the latest version of JQuery.
  2. Pass a JSON object containing all the necessary data back and forth from the server.

    var data = { items: [ { id: 1234, work: "work", details: "details", year: "2010" } ] };

  3. Create a javascript function that can create a unique id for a particular property.

    function GetFieldId(type, id, prop) { return [type, id, prop].join("_"); }

  4. In the template, use the above function to add ids to each element the user can interact with. Creating "properties" that don't actually exist on the object works well for buttons and similar elements.

  5. Using JQuery delegates, create an "change" handler for any input with an id.

  6. In the change handler, pull the id apart, find the proper object, and go to work.

  7. To add an item, create a new object, throw it into the appropriate JSON array, render the template, and drop it into the right spot on the page.

  8. To delete an object, add an "IsDeleted" property to the object, and remove the HTML elements.

  9. Saving involves pushing this JSON object up the the server, where it will analyze it and take appropriate actions.


I do something like this using a combination of jQuery and ASP.NET.

First, I code up a partial page in ASP.NET (*.ascx) which contains a "row". In your case, since the three items go together, all those items could be considered a row. (You can use CSS styling to make them look like they belong together.) I also place an image at the end of my row (a plus sign) so that, if the user clicks on that plus sign, I can add a new row (more on that in a second).

In any case, I add the partial row to the page to get started. (I use a strongly-typed page so that I can just loop through the models and pass the individual row to my partial page.) I display all of this in a table. (In my case, it is represented by tabluar data, but it doesn't have to be.)

As for the plus sign, when the user clicks on it, I add a new row based on the partial page. Something along these lines:

personAdd($('#addPerson'), '#personInformation');

function personAdd(personDiv, tableName) {
    personDiv.live('click', function () {
        $.ajax({
            url: this.href,
            cache: false,
            success: function (html) { $(tableName + ' > tbody:last').append(html); }
        });

        $(this).replaceWith('<img alt="Delete Person" class="deleteImg" src="/Content/Images/remove_delete_cancel_clear.png" />');

        return false;
    });
}

This adds a new row, and changes the previous row to a "delete image" (a red X) so that previous rows can be deleted. I handle that bit with this jQuery:

// Allow rows to be deleted.
$('.deleteImg').live('click', function () {
    $(this).closest('tr').remove();
});

Since everything is strongly typed, when I go ahead and submit the form, it works pretty well. I hope this helps and gets you started, or perhaps helps somebody else. Please let me know if you have any questions.

0

精彩评论

暂无评论...
验证码 换一张
取 消