使用JS渲染Django表单

时间:2018-01-28 01:15:11

标签: javascript django

我正在学习在Django项目中使用纯JS。作为服务器端开发人员,这些概念对我来说相对较新,所以需要一只手。

想象一下用户可以发布文本和/或上传图像的表单。可以把它想象成一个简单的Django形式:

class PostForm(forms.Form):
    image = forms.ImageField(required=False)
    reply = forms.CharField(required=False, widget=forms.Textarea(attrs={'cols':30,'rows':3,'class': 'cxl','autocomplete': 'off','autofocus': 'autofocus'}))

    def __init__(self,*args,**kwargs):
        super(PostForm, self).__init__(*args,**kwargs)
        self.fields['image'].widget.attrs['id'] = 'browse_image_btn'

    def clean(self):
        data = self.cleaned_data
        # perform cleaning
        return data

如果我要在HTML中呈现此表单,则会执行以下操作:

<form action="{% url 'post_content' %}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ post_form.reply }}<br>
    {{ post_form.image }}
    <label for="browse_image_btn" style="cursor: pointer;"><img alt="Select photo" src="{{ STATIC_URL }}img/upload.svg" width="70" height="70"></label>        
    <input type="submit" value="submit">
</form>

但是如何仅通过JS创建此HTML?

用例:想象一个包含很长内容列表的页面,每个页面下都有一个reply按钮。只要用户按下reply按钮,上面的表单就会显示在特定内容下。此外,按下相同的按钮也会切换off

我似乎无法解决这样的问题。请告知,最好是一个说明性的例子。我更愿意了解最有效,可扩展的方法,可以在专业环境中部署。只有纯JS,没有JQuery。

我已经尝试过这个,但是因为我是一个JS新手,所以他们已经半生不熟了。这是我到目前为止所得到的:

  var okBtn = document.createElement('button');
    setUpSubmitBtn(okBtn);
   e.target.parentNode.insertAdjacentElement('afterend', okBtn);

   var camBtn = document.createElement('img');
    setUpCameraBtn(camBtn);
   e.target.parentNode.insertAdjacentElement('afterend', lineBreak);
   e.target.parentNode.insertAdjacentElement('afterend', camBtn);

   var replyBox = document.createElement('textarea');
    setUpReplyBox(replyBox);
   e.target.parentNode.insertAdjacentElement('afterend', replyBox);

如果有简单的JS函数来创建上面提到的每个小部件:

function setUpReplyBox(replyBox) {
    replyBox.classList.add('mts');
    replyBox.setAttribute('id', 'reply-message');
    replyBox.setAttribute('style', 'display:inline');
    replyBox.setAttribute('placeholder', 'Reply');
}

function setUpSubmitBtn(okBtn) {
    okBtn.classList.add('btn', 'bcb', 'bs', 'mts');
    okBtn.setAttribute('style','border:none;height:25px;display:inline;');
    okBtn.setAttribute('id','reply-ok');
    okBtn.innerHTML = "OK";
}

function setUpCameraBtn(camBtn) {
    camBtn.setAttribute('id','camera');
    camBtn.setAttribute('src','/static/img/cam1.svg');
    camBtn.setAttribute('width','45');
    camBtn.setAttribute('height','45');
    camBtn.setAttribute('style','display:inline;float:right;');
}

我觉得我这样做的方式很难/错。正确的模式可能会更简单。

1 个答案:

答案 0 :(得分:1)

希望有所帮助:

var formTemplate = document.querySelector('#form-template form');
var idInput = document.getElementById('id-input');

function toggleReply(e) {
  if (!formTemplate) return;

  e.target.parentNode.insertBefore(formTemplate, e.target);
  idInput.value = e.target.getAttribute('data-id');
};

Array.from(document.querySelectorAll('button.reply'))
  .forEach(btn => btn.onclick = toggleReply)
form + .reply {
  display: none;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<div id="form-template" style="display: none;">
  <form action="" method="POST" enctype="multipart/form-data">
      <input id="id-input" type="hidden" name="id" value="">
      <div class="form-group">
        <label for="reply">Reply:</label>
        <textarea class="form-control" type="text" name="text"></textarea>
      </div>
      <input type="submit" class="btn btn-default pull-right" value="submit">
  </form>
</div>

<div class="container">
  <div class="list-group">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Comment title</h3>
      </div>
      <div class="panel-body">
        Comment content
      </div>
      <div class="panel-footer clearfix">
        <button class="reply btn btn-default pull-right" type="button" data-id="24">Reply</button>
      </div>
    </div>
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Comment title</h3>
      </div>
      <div class="panel-body">
        Comment content
      </div>
      <div class="panel-footer clearfix">
        <button class="reply btn btn-default pull-right" type="button" data-id="25">Reply</button>
      </div>
    </div>
  </div>
</div>