开发者

Trying to clean out form inputs with jQuery so I can add it back into the form

开发者 https://www.devze.com 2023-01-13 08:47 出处:网络
I have a pretty simple HTML form where users can enter in information about a person. Below that form is a button which allows them to \'add more\'. When clicked, the \'person\' form is copied and app

I have a pretty simple HTML form where users can enter in information about a person. Below that form is a button which allows them to 'add more'. When clicked, the 'person' form is copied and appended to the page.

The way I used to do this was to take my HTML file, copy out the relevant section (the part that gets 'added more') and then save it into a variable in the Javascript. This became rather annoying when I had to make changes to the form as I would then have to make the same changes to the Javascript variable.

My new method is to create the variable dynamically in Javascript. When the page loads, I use jQuery to grab out the 'add more' part of the code and cache the HTML into a variable. Then when the 'add more' button is clicked, I app开发者_开发百科end that cached HTML to the page.

The problem is with form inputs. The server-side code autofills the form with the user's data from the database. I want to cache that HTML data with no form inputs...

My current function looks like this:

function getHTML($obj, clean)
{
    if (clean)
    {
        var $html = $obj.clone();

        $html.find('input').each(function() { $(this)[0].value = ''; });
    }
    else
    {
        var $html = $obj;
    }

    var html = $html.wrap('<div></div>').parent()[0].innerHTML;
    $html.unwrap();

    return html;
}

It doesn't work. I'm also unsure if this is the best approach to solving the problem.

Any ideas?


I don't know why this wouldn't work. I can't see how the function is being called, or what is being passed to it.

I guess one thing I'd do differently would be to create a .clone() whether or not you're "cleaning" the inputs. Then you're not wrapping and unwrapping an element that is in the DOM. Just use the if() statement to decide whether or not to clean it.

Something like this:

function getHTML($obj, clean) {
    var $clone = $obj.clone();
    if (clean) {
        $clone.find('input').each(function() { this.value = ''; });
    }
    return $clone.wrap('<div></div>').parent()[0].innerHTML;
}

Or a little more jQuery and less code:

function getHTML($obj) {
    return $obj.clone().find('input').val('').end().wrap('<div/>').parent().html();
}

A little less efficient, but if it only runs once at the page load, then perhaps not a concern.

Or if it is going to be made into a jQuery object eventually anyway, why not just return that?

function getHTML($obj) {
    return $obj.clone().find('input').val('').end();
}

Now you've returned a cleaned clone of the original that is ready to be inserted whenever you want.


EDIT:

Can't figure out right now why we can't get a new string.

Here's a function that will return the DOM elements. Beyond that, I'm stumped!

function getHTML($obj, clean) {
    var $clone = $obj.clone();
    if (clean) {
        $clone.find('input').each(function() {
            this.value = '';
        });
    }
    return $clone.get();  // Return Array of DOM Elements
}

EDIT: Works now.

I ditched most of the jQuery, and used .setAttribute("value","") instead of this.value.

Give it a try:

function getHTML($obj, clean) {
    var clone = $obj[0].cloneNode(true);
    var inputs = clone.getElementsByTagName('input');
    console.log(inputs);
    for(var i = 0, len = inputs.length; i < len; i++) {
        inputs[i].setAttribute('value','');
    }
    return $('<div></div>').append(clone)[0].innerHTML;
}


I would wrap the part of the form that needs to be cloned in a <fieldset>:

<form id="my_form">
    <fieldset id="clone_1">
        <input name="field_1_1">
        <input name="field_2_1">
        <input name="field_3_1">
    </fieldset>
</form>
<a href="#" id="fieldset_clone">Add one more</a>

Then for the jQuery script:

$("#fieldset_clone").click(function(event) {
    // Get the number of current clones and set the new count ...
    var cloneCount = parseInt($("fieldset[id^=clone_]").size());
    var newCloneCount = cloneCount++;

    // ... then create new clone based on the first fieldset ...
    var newClone = $("#clone_1").clone();

    // .. and do the cleanup, make sure it has
    // unique IDs and name for server-side parsing
    newClone.attr('id', 'clone_' + newCloneCount);
    newClone.find("input[id^=clone_]").each(function() {
        $(this).val('').attr('name', ($(this).attr('name').substr(0,7)) + newCloneCount);
    });

    // .. and finally insert it after the last fieldset
    newClone.insertAfter("#clone_" + cloneCount);
    event.preventDefault();
});

This would not only clone and clean the set of input fields, but it would also set new ID's and names so once the form is posted, their values would not be overwritten by the last set.

Also, in case you want to add the option of removing sets as well (one might add too many by mistake, or whatever other reason), having them wrapped in a <fieldset> that has an unique ID will help in accessing it and doing a .remove() on it.

Hope this helps.

0

精彩评论

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

关注公众号