2015-06-09 2 views
0

У меня есть форма в HTML, которая имеет объект формы из моего django ModelForms. Я хочу разрешить пользователю динамически добавлять или удалять копии одной и той же формы, если они выбирают. Аналогичный пример (онлайн демо) будет таким: http://viralpatel.net/blogs/dynamically-add-remove-rows-in-html-table-using-javascript/Как создать кратность одной формы для пользователя

Я просто не знаю, как начать работу, как у меня есть небольшой опыт работы с JavaScript. Любой вход был бы оценен.

Вот мой HTML код:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>‌ 

<form id="blockForm" class="original" action="{% url 'inventory:requests' inventory.id %}" method="post">{% csrf_token %} 
<a href="#" id="insert-more"> Add New Row </a> 

<div class="requestForm"> 
    <div class="container"> 
     <ul><li><input {{form.as_table}} /></li></ul> 
    </div> 
</div> 
<input type="submit" name="submit" value="Request Blocks" id="submitButton"> 
</form> 

Вот JavaScript:

<script language="javascript" type="text/javascript"> 
function dupeForm() { 
    var reqs = document.getElementsByClassName('requestForm'), 
     btn = document.getElementById('submitButton'), 
     len = reqs.length, 
     lastReq = reqs[len - 1], 
     newReq = lastReq.cloneNode(true), 
     txtBxs = newReq.getElementsByTagName('ul'); 
    // I am unsure what this for loop does -quanuw 
    for (var i = 0; i < txtBxs.length; i++) { 
     txtBxs[i].setAttribute('name', 'txt' + len); 
     txtBxs[i].setAttribute('id', 'txt' + len); 
     txtBxs[i].value = 'More Text'; 
    } 

    lastReq.parentNode.insertBefore(newReq, btn); 
} 

var submitButton = document.getElementById('submitButton'); 
var insertLink = document.getElementById('insert-more'); 

insertLink.addEventListener("click", function(e) { e.preventDefault(); dupeForm(); }, false); 
submitButton.addEventListener("click", function(e) { e.preventDefault(); }, false); 

</script> 

Вот мой ModelForm:

class Block(models.Model): 
class Meta: 
    verbose_name_plural = "Request Blocks" 

inventory = models.ForeignKey(Inventory, null=True) 
block_status = models.CharField(max_length=12, default='STATUS') 
block_name = models.CharField(max_length=50, default='BLOCKNAME') 
block_derivatives = models.CharField(max_length=100, default='DERIVATIVES') 
block_subsystems = models.CharField(max_length=32, default='SUBSYSTEMS') 
owners = models.CharField(max_length=100, default='OWNERS') 


def __str__(self):    
    return self.block_name 

def block_owners(self): 
    return str(self.owners) 
+0

Как насчет формы ид? HTML имеет уникальный идентификатор для элементов – nikhil

+0

Что вы имеете в виду? Не могли бы вы рассказать? – quanuw

+0

Вы хотите создать копию формы? Теперь в элементе формы есть id blockForm. Если вы создадите копию формы, идентификатор новой формы будет blockForm, который не должен быть. – nikhil

ответ

0

Я создал plunker для вас какие клоны вашу форму html.

$(function(){ 
    $("#insert-more").click(function(){ 
    var form = $("#blockForm").clone(); 
    $(".container").append(form); 
    }); 
}); 

"http://plnkr.co/edit/jAyl2EkSkMUPWQa4gwRg?p=preview

+0

Хорошо, я удалил идентификатор формы, а также один из div, так как он казался излишним. – quanuw

+0

Отлично. Вы проверили мой код? Будет ли это работать на вас? – nikhil

+0

Просто интересно, как будет работать ваш скрипт, если я удалю свой идентификатор формы? Вы используете селектор «#blockForm». – quanuw

1

Есть несколько способов сделать это.

Вы можете воссоздать объект формы с помощью JavaScript. Тогда каждый раз, когда вам нужно добавить форму, вы просто повторно запустите JavaScript-функция.

В качестве альтернативы вы можете создать форму с использованием обычного HTML и назначить ее «скрытым» и «оригинальным» классом. Затем каждый раз, когда вы хотите добавить строку, вы запускаете следующее:

function(){ 
    var newForm = $('form#blockForm.original').clone().removeClass('original'); 
    newForm.appendTo($('div.container')).show(); 
} 

Чтобы запустить эту функцию, вы можете обернуть ее в событие .click(), прикрепленное к кнопке «Добавить строку». Не используйте <a href="#" id="insert-more"> Add New Row </a>. Вместо этого, я предпочитаю идти со следующим:

HTML:

<span id="insert-more">Add New Row</span> 

JavaScript:

$('span#insert-more').click(function(){ 
    var newForm = $('form#blockForm.original').clone().removeClass('original'); 
    newForm.appendTo($('div.container')).show(); 
}); 

И естественно, вам нужно что-то, чтобы активировать эту JavaScript после загрузки диапазона. Я использую $(document).ready(function(){//This is where most of my JavaScript file goes.});

--- EDIT ---

Хорошо, я предполагаю, что я не очень ясно, на вершине. Я предполагал, что вы используете какую-то мастер-форму, которая скрыта от представления, причем класс является «оригинальным». Затем, когда вы копируете это, код, который я написал, удаляет этот класс, но только из копии. Это значит, что вы не копируете копии. Но вам нужно поставить класс «оригинал» в оригинальную форму, которую вы хотите скопировать! Вы также хотите покончить с большей частью идентификаторов в форме или просто не использовать их вообще. Я предпочитаю использовать классы для этого, и тогда все, что я делаю с формой, обычно указывается следующим образом.

$('button.formSubmit').click(function(){ 
    var $thisForm = $(this).parent().parent(); 
    //multiple parent functions may be chained together, depending on how far down the button is nested. 
    //examples of use: 
    $thisForm.children('input.blah1').doSomething(); 
    var inp2 = $thisForm.children('input.blah2'); 
    //Really, you can do anything at this point. 
}); 

Что касается предоставления форм, уникальных идентификаторов, ненужен так долго, как у вас есть способ, чтобы выяснить, что принадлежит к какой форме, которая просто с функциональностью $(this) которая определяет, что вещь была нажата, и работы основаны на этом.Кроме того, если вы действительно используете стандартную функциональность «отправить форму», вам не нужно беспокоиться о $(this), потому что она представляет форму, в которой была нажата кнопка, независимо от идентификатора или класса. Вам нужно только беспокоиться о ids, когда вы собираетесь положить что-то вне формы, которая связана с чем-то внутри конкретной формы. Но так как вы делаете повторяющиеся формы, вы не захотите этого делать в любом случае.

+0

Поэтому я поставил обе части вашего javascript-примера в файл js, но добавление нового не работает. Должен ли я каким-то образом изменить свой код в соответствии с моими требованиями? – quanuw

+0

Если вы использовали '$ (" span # insert-more ")', вы также изменили ' Add New Row' на ' Добавить новую строку'? Если вы действительно хотите сохранить тег ссылки, вместо этого вы должны использовать '$ (" a # insert-more ")'. Извините, если я не понял. – RoboticRenaissance

+0

Итак, я изменил тег link на span, но как бы добавить функциональность кнопки или клика для добавления новой строки? Благодаря! – quanuw

0

Вы действительно хотите клонировать форму или отдельные строки внутри одной формы? Если это действительно последнее, вы можете использовать функцию для дублирования полей в вашей форме и обновлять имена полей ввода для соответствия.

function dupeForm() { 
    var reqs = document.getElementsByClassName('requestForm'), 
     btn = document.getElementById('submitButton'), 
     len = reqs.length, 
     lastReq = reqs[len - 1], 
     newReq = lastReq.cloneNode(true), 
     txtBxs = newReq.getElementsByTagName('input'); 

    for (var i = 0; i < txtBxs.length; i++) { 
     txtBxs[i].setAttribute('name', 'txt' + len); 
     txtBxs[i].setAttribute('id', 'txt' + len); 
     txtBxs[i].value = 'More Text'; 
    } 

    lastReq.parentNode.insertBefore(newReq, btn); 
} 

Смотрите скрипку здесь: http://jsfiddle.net/vp84oodt/

+0

Форма имеет только одну строку полей, так что имеет значение, если я хочу клонировать форму или отдельные строки? – quanuw

+0

Если вы клонируете всю форму, вам необходимо управлять всеми элементами этой формы для дублирования идентификаторов и имен. Кроме того, я думаю, что кнопка отправки отдельной формы отправит только форму, к которой она принадлежит, но не все формы и все имена форм будут такими же, что может повредить везде, где все эти данные идут. – Todd

+0

Итак, мне нужна форма, чтобы быть динамичной в том смысле, что пользователь может делать несколько заказов одновременно в одном представлении, но каждый заказ должен иметь уникальный идентификатор или pk в базе данных и не должен быть связан вместе. Будет ли клонирование правильным выбором для этого? – quanuw

Смежные вопросы