简体   繁体   中英

jQuery Appending Input elements

I am trying to create a simple Do to List which will have Checklists with a list of Tasks under it.

Idea is to create the Complete List and then Submit it to the Server to Save it in the Database.

I am looking to get the Input Boxes in a Clean structure like the following

Array
(
    [checklist] => Array
        (
            [0] => Array
                (
                    [task] => Array
                        (
                            [0] => 
                            [1] => 
                        )

                )

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

                )

            [2] => 
        )

    [submit] => Submit
)

As i need to Add the right name to the input box to retain the structure i receive in the database i will need to count the Checklist number and the Task number and then append the same.

One unique case is when a user delete an input box from the middle of the list of tasks how can i retain the number to increment so that i do not over lap an input name and lose the data.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ToDo</title>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>

<body>
<form action="todo.php" method="post" name="todo">
  <ul>
    <li>
      <input name="checklist[0]" type="text">
      <ul>
        <li>
          <input name="checklist[0][task][0]" type="text">
        </li>
        <li>
          <input name="checklist[0][task][1]" type="text">
        </li>
      </ul>
      <a class="add" href="#">Add one</a> </li>
    <li>
      <input name="checklist[1]" type="text">
      <ul>
        <li>
          <input name="checklist[1][task][0]" type="text">
        </li>
        <li>
          <input name="checklist[1][task][1]" type="text">
        </li>
        <li>
          <input name="checklist[1][task][2]" type="text">
        </li>
      </ul>
      <a class="add" href="#">Add one</a> </li>
    <li>
      <input name="checklist[2]" type="text">
      <ul>
      </ul>
      <a class="add" href="#">Add one</a> </li>
  </ul>
  <input name="submit" type="submit" value="Submit">
</form>

<script language="javascript">


$( ".add" ).click(function() {

  // Find the Task Count
  var task_count = $(this).siblings('ul').children('li').length;
    var count = $(this).siblings('ul').count;
  var input = '<li><input name="checklist[][task][]" type="text"></li>';

  console.log(task_count);

  $(this).siblings('ul').append(input);
});

</script>
<hr/>
<pre>
<?php
print_r($_POST);
?>
</pre>
</body>
</html>

Link: http://play.mink7.com/todo.php

The code (at the page bottom) is:

$( ".add" ).click(function() {

  // Find the Task Count
  var task_count = $(this).siblings('ul').children('li').length;
    var count = $(this).siblings('ul').count;
  var input = '<li><input name="checklist[][task][]" type="text"></li>';

  console.log(task_count);

  $(this).siblings('ul').append(input);
});

When user removes an input you can store the input name probably in an array. And while appending you can check the array for the name. Based on the absence or presence of the name in array you can rename newly appended input. This will prevent the data loss if any.

Another approach will be to don't bother about the names while appending. But before the form is submitted, you can dynamically generate the name of the inputs based on the children count and the task name. This will certainly prevent the data loss.

Here is the demo for the second method: http://jsfiddle.net/lotusgodkk/GCu2D/359/

$(document).ready(function () {
    $('input[type="submit"]').on('click', function (e) {
        $('form>ul').each(function () {
            var ul = $(this);
            var name = ul.attr('data-name');
            var inputs = $('input', ul);
            inputs.each(function () {
                var i = $(this);
                var index = inputs.index(i);
                var n = name + '_' + index; // Generate the name of input
                i.attr('name', n);
            });
        });
        return false;
    })
});

Sample HTML :

<form action="todo.php" method="post" name="todo">
    <ul data-name="listone">
        <li>
            <input name="checklist[0]" type="text" />
            <ul>
                <li>
                    <input name="checklist[0][task][0]" type="text" />
                </li>
                <li>
                    <input name="checklist[0][task][1]" type="text" />
                </li>
            </ul> <a class="add" href="#">Add one</a> 
        </li>
        <li>
            <input name="checklist[1]" type="text" />
            <ul>
                <li>
                    <input name="checklist[1][task][0]" type="text" />
                </li>
                <li>
                    <input name="checklist[1][task][1]" type="text" />
                </li>
                <li>
                    <input name="checklist[1][task][2]" type="text" />
                </li>
            </ul> <a class="add" href="#">Add one</a> 
        </li>
        <li data-name="listthree">
            <input name="checklist[2]" type="text" />
            <ul></ul> <a class="add" href="#">Add one</a> 
        </li>
    </ul>
    <input name="submit" type="submit" value="Submit" />
</form>

Here, for naming I used a data attribute on ul and the index on input inside the list.

Click on the submit button and you'll see the changed name of input.

I think you should count checklists and tasks at submit time. Just ignore the names during "edit time" and set the names all in one block at the end, like this:

http://jsfiddle.net/s3j7ok56/1/

This way if the user deletes, or moves (drag?) items, you just don't care as they will be named correctly at the end.

( example with remove: http://jsfiddle.net/s3j7ok56/2/ )

Note that I also set the val() of inputs for debug, to show the names. And I block the form submit for JsFiddle, all this should be removed to allow correct form posting.

HTML:

<form method="post" id="todo" name="todo" onsubmit="/* for JSFIDDLE */ return false;">
    <ul id="all">
    </ul>
    <a id="addc" href="#">add checklist</a><br />
    <input name="submit" type="submit" value="Submit">
</form>

JS:

$(function() {

    $("#addc").click(function(e) {

        var elem=$('<li class="checklist"><input type="text"><ul class="tasks"></ul></li>');
        var link=$('<a class="add" href="#">Add task</a>');

        link.appendTo(elem);
        elem.appendTo("#all");

        link.click(function(e1) {
            var task=$('<li class="task"><input type="text"></li>');
            $(this).parent().children(".tasks").append(task);
        });
    });

    $("#todo").submit(function() {
        var countLists=0;
        var countTasks=0;
        $("#all>li.checklist>input").each(function() {
            $(this).attr("name","checklist["+countLists+"]");
            $(this).val("checklist["+countLists+"]");
            countTasks=0;
            $(this).parent().find("ul.tasks>li.task>input").each(function() {
                $(this).attr("name","checklist["+countLists+"]task["+countTasks+"]");
                $(this).val("checklist["+countLists+"]task["+countTasks+"]");
                countTasks++;
            });
            countLists++;
        })
        return true;
    });

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM