2016-03-08 77 views
1

我正在实施一个简单的练习来教授密码学方法。目前我正在使用凯撒密码。 Web应用程序的工作方式如下,用户输入密钥和明文以生成包含明文每个字母的动态表单。然后每个表单都相互分离,这意味着每个表单都包含一个有效的按钮,以验证加密是否正确完成。Django错误表单提交使用Javascript

问题是,当从第二个窗体和其他窗体按下validate按钮时,它总是发送第一个窗体信息。我注意到这一点,因为我在Javascript和python中打印了表单的值,它总是打印第一个表单。

模板:

<div class="form-group"> 
    <label for='id_plaintext'> 
    Plaintext: 
    </label> 
    <form onsubmit="return false;" method="GET"> 
    {% csrf_token %} 
    <div class="col-sm-5 col-xs-6 col-md-4"> 
     {{ formPlaintext.plaintext }} 
    </div> 
    <button name="action" id="encryptButton" class="btn btn-primary" value="encrypt">Encrypt</button> 
    </form> 
    <br> {% if formPlaintext.errors %} 
    <div class="alert alert-danger" role="alert"> 
    <strong>{{ formPlaintext.plaintext.errors }}</strong> 
    </div> 
    {% endif %} 
</div> 

{% for letterOfWord, keyToUse, letterToFill, letterNumber in equations %} 
    <form method="GET" class="form-inline"> 
    {% csrf_token %} 
    <div class="row"> 
     <div class="col-sm-12 col-xs-12 col-lg-12 col-md-12"> 

     <div class="alert alert-info col-sm-12 col-xs-12 col-lg-12 col-md-12"> 
      Excercise Number {{letterNumber}} <br> 
      ({{ letterOfWord }} + {{ keyToUse }}) mod 26 = {{ letterToFill }} 
      <button name="action" class="validate"> 
      Validate 
      </button> 
     </div> 
     <div id="notification"> 
     {% include "content/caesarValidation.html" %} 
     </div> 
     </div> 
    </div> 

</form> 
{% endfor %} 

的Javascript:

$("#encryptButton").on({ 
    click: function() { 
     var variable = document.getElementById('id_plaintext'); 
     console.log(variable.value) 
     $.ajax({ 
      url: "/exampleCaesar", 
      type: "GET", 
      data: { 
      CSRF: 'csrf_token', 
      plaintext: $('#id_plaintext').val(), 
      key: $('#id_key').val() 
      }, 

      success: function(example) { 
      $('#example1').show(); 
      $('#exampleSection').html(example); 
      console.log(example); 

      } 

     }); //END OF Ajax 
     } //END OF FUNCTION 
    }); //END OF encryptButton 

    $(".validate").on({ 
    click: function(event) { 
     var variable = document.getElementById('id_letterToFill'); 
     console.log(variable.value) 
     console.log("Inside validate button function") 

     event.preventDefault(); 

     $.ajax({ 
      async: true, 
      url: "/validateCaesar", 
      type: "GET", 
      data: { 
      CSRF: 'csrf_token', 
      originalLetter: $('#id_letterOfWord').val(), 
      key: $('#id_keyToUse').val(), 
      encryptLetter: $('#id_letterToFill').val(), 
      numberLetter : $('#id_letterNumber').val() 
      }, 
      success: function(exampleData) { 

      console.log(exampleData) 
      $('#notification').html(exampleData) 
      console.log(exampleData) 

      } 

     }); 
     } 
    }); 

查看

def exampleCaesar(request): 

    if request.is_ajax() and request.method == "GET": 
     formKey = caesarKey(request.GET or None) 
     formPlaintext = caesarPlaintext(request.GET or None) 
     if formKey.is_valid(): 
      if formPlaintext.is_valid(): 
       wordToEncrypt = request.GET.get('plaintext') 
       wordToEncrypt = wordToEncrypt.upper() 
       wordLength = len(request.GET.get('plaintext')) 
       key = request.GET.get('key') 

       print(wordToEncrypt) 
       print(key) 
       equations = [] 
       formKey = caesarKey(request.GET or None) 
       letterNumber = 1 
       for x in range(wordLength): 
        exampleForm = caesarCipherExample(initial={'letterOfWord' : wordToEncrypt[x], 'keyToUse' : key, 'letterNumber' : letterNumber}) 
        # print(exampleForm) 
        if exampleForm.is_valid: 
         equations.append(exampleForm) 
         letterNumber += 1 
         print(equations) 

       context = { 'equations' : equations, 
          'formKey' : formKey, 
          'formPlaintext': formPlaintext 

       } 

       html = render(request, "content/exampleCaesar.html", context) 
       return HttpResponse(html) 
      else: 
       print(formPlaintext.errors) 
       context = { 'formKey' : formKey, 
          'formPlaintext': formPlaintext 

       } 

       html = render(request, "content/exampleCaesar.html", context) 
       return HttpResponse(html) 


     else: 
      print(formKey.errors) 

def validateCaesar(request): 

    obj = CaesarCipher() 
    print("You're in!") 

    if request.is_ajax() and request.method == 'GET': 
     formExample = caesarCipherExample(request.GET or None) 

     encryptLetter = request.GET.get('encryptLetter').upper() 
     originalLetter = request.GET.get('originalLetter') 
     key = int(request.GET.get('key')) 
     print(encryptLetter) 
     print(originalLetter) 

     print(key) 
     if obj.validateLetter(encryptLetter, originalLetter, key): 
      listOfCorrect = [request.GET.get('numberLetter'), 'true'] 

      print(listOfCorrect) 
      html = render(request, "content/caesarValidation.html", {'listOfCorrect' : listOfCorrect}) 
      return HttpResponse(html) 
     else: 
      listOfCorrect = [request.GET.get('numberLetter'), 'false'] 

      print(listOfCorrect) 
      html = render(request, "content/caesarValidation.html", {'listOfCorrect' : listOfCorrect}) 
      return HttpResponse(html) 

caesarValidation模板:

<!doctype html> 

{% if listOfCorrect %} 
<div id="notification"> 

{% if "true" in listOfCorrect %} 
    <div class="alert alert-success"> 
    Success! 
    </div> 

    {% else %} 
    <div class="alert alert-danger"> 
    Fail! 
    </div> 
{% endif %} 

{% endif %} 

</div> 

这里是包含在模板中使用的形式forms.py:

class caesarCipherExample(forms.Form): 
    letterOfWord = forms.CharField(max_length = 1, widget=forms.TextInput(attrs={'class' : 'form-control', 'class' : 'no-border', 'style' : 'width:20px; background-color: #D9EDF7; text-align: left;', 'readonly' : 'readonly'})) 
    keyToUse = forms.DecimalField(max_value = 26, min_value = 1, initial = 1, required = True, widget=forms.NumberInput(attrs={'class' : 'form-control', 'class' : 'no-border', 'style' : 'width:30px; background-color: #D9EDF7; text-align: right;', 'readonly' : 'readonly'})) 
    letterToFill = forms.CharField(max_length = 1, widget=forms.TextInput(attrs={'class' : 'form-control','style' : 'width:60px'})) 
    letterNumber = forms.DecimalField(widget=forms.TextInput(attrs={'class' : 'form-control', 'class' : 'no-border', 'style' : 'width:20px; background-color: #D9EDF7; text-align: left;', 'readonly' : 'readonly'})) 

回答

0

您的形式被包含多次,但每次大概都使用相同ID值的字段。但在HTML中,ID必须是唯一的。

与其通过ID获取字段值,您需要使用jQuery来查找父表单,并从那里获取其值。例如:

var form = $(this).parent('form'); 
var variable = form.find('input[name=letterToFill]'); 

等等的其他值。

+0

我试过这种方法,但是当试图在Javascript中打印出变量时,它是未定义的。 – Silvestrini

+0

如果您显示包含的caesarValidation.html模板,这将有所帮助。 –

+0

我添加了caesarValidation.html模板。 – Silvestrini