使用按键代替django表单中的按钮

时间:2014-07-28 17:15:45

标签: javascript jquery python django forms

我有一个网站,允许文本输入,条目投票和投票条目的实时表格: http://www.highscore.a2hosted.com/index/

这是用django编码的。我设法在一个页面上获得了一个文本输入和一个投票表单。

文字输入: 当按下回车键时,文本条目会向数据库(sqlite3)添加新条目。一些javascript将输入绑定到keypress以发送到views.py,后者使用GET添加文本和当前日期时间。没有使用任何表格,并且在js中重新加载位置。

投票表格 投票表单是POST方法,您有两个提交按钮来向上或向下投票显示的文本。显示的文本可以从' for循环访问'在HTML中。在刷新页面时,会从views.py更新为最新的未投票文本。

在views.py的投票功能中,会发送向上或向下按钮的名称以及要投票的条目的ID。选票加入或减去条目的分数,保存并刷新页面。

物理安装 我的下一步是构建使用Web体系结构的物​​理安装。最终安装不会在一个页面上,因此将有一个投票站和一个入口站。我将使用街机按钮进行输入和投票。

街机按钮>操纵杆编码器> Joy2Key Mapper 我将街机按钮连接到ZeroDelay操纵杆编码器,并使Joy2Key运行时按钮映射到13(输入)38(向上箭头)和40(向下箭头)。

一切都适用于文本输入(操纵杆按钮映射到输入按钮13)。

我遇到问题的方法是尝试获取密钥以使用django表单。 由于投票使用表格,因此django希望在按钮区域中单击鼠标。我试图解决这个问题。我得到的最接近的是在投票表格中放置一个多余的文本输入框来捕获关键活动。

当该框处于活动状态时,我可以按下映射到向上箭头的按钮,并在我的命令提示符中查看一些POST反馈(但它还没有发送投票)。如果我单击文本输入框,我可以按下映射到输入按钮的按钮,并在我的命令提示符和成功的文本输入中获得GET反馈。

所以我的问题是......没有外部库或花哨的Gamepad API编码,是否有一种整洁的方法可以让django表单按钮仅通过键盘按键工作?如果需要是一个活跃的盒子,这可能是隐藏和全屏? (我已经尝试过没有运气了)

1 个答案:

答案 0 :(得分:2)

好的,这就是我的所作所为。

在新的voting.html中,我使用此代码捕获操纵杆映射到的箭头按钮:

<div id="Vote" class = "high">
  <div style="text-align: center">
  {% for entry in voting_entry_list %} 
    <li><a href="/entries/{{ entry.id }}/">{{ entry.text }}&nbsp{{ entry.score }}</a></li>
    <p>
    <input type="submit" id="voteid" name='voteid' value="{{ entry.id }}" autofocus value="" onfocus="this.value = this.value;" class = "transparent"/>
          <script>
            $(document).ready(function() {
              $("#voteid").bind("keydown", function(e) { //input type=id above
                if (e.keyCode == 38) {
                  var text = $("#voteid").val();        
                  var args = {'voteid':text};       
                  $.get("/voteup/", args).done(function(data) {
                    console.log("message: " + data);
                    location.reload();  
                  });
                return false;
                }
                if (e.keyCode == 40) {
                  var text = $("#voteid").val();        
                  var args = {'voteid':text};       
                  $.get("/votedown/", args).done(function(data) {
                    console.log("message: " + data);
                    location.reload();  
                  });
                return false;
                }       
              });
            });     
          </script>
  {% endfor %}
  </div>
</div>

然后在views.py中,我使用GET而不是POST来捕获向上或向下的投票:

def voting(request):   
context = {
  'latest_entry_list': Entry.objects.order_by('-pub_date')[:10], # simple sorting by datetime, latest first, 10 items
  'high_entry_list': Entry.objects.order_by('-score','-pub_date')[:10], # simple sorting by score high to low, 10 items
  'high_entry': Entry.objects.order_by('-score','-pub_date')[:1], # simple sorting by score high to low, 10 items
  'low_entry_list': Entry.objects.order_by('score','-pub_date')[:10], # simple sorting by score low to high, 10 items
  'voting_entry_list': Entry.objects.unvoted_or_random(), # actually one item, command from extended object manager
}
return render(request, 'entries/voting.html', context); # returns when vote is accessed

def voteup(request):
voting_id = request.GET.get('voteid') # voting id number is brought in as var
if request.method=='GET': #always polling, when get votes, save and redirect to /index to refresh
    v = Entry.objects.get(pk=voting_id) # get by voting id var
    v.score +=1 # add one to score for voteup button
    v.voted=True # set voted boolean to true
    v.save() # explicit save, as is not saved with change above
else:
    pass
return HttpResponse('done') # Only on console 

def votedown(request):
voting_id = request.GET.get('voteid') # voting id number is brought in as var
if request.method=='GET': #always polling, when get votes, save and redirect to /index to refresh
    v = Entry.objects.get(pk=voting_id) # get by voting id var
    v.score -=1 # add one to score for voteup button
    v.voted=True # set voted boolean to true
    v.save() # explicit save, as is not saved with change above
else:
    pass
return HttpResponse('done') # Only on console

这似乎避免了表单和按键的任何问题。由于它位于单独的投票页面上,因此透明虚拟提交按钮会在刷新时激活该选择,而不是当它们位于同一页面时的文本输入框。我可以从voting_entry_list访问已排序的条目,并使用单独的js脚本和每个按钮的views.py请求向上或向下投票。

我的目标是使用基本的django和js来做这件事,没有信心安装一堆库或编写额外的gamepad.api状态和轮询,所以完成了工作!

现在它作为一种kludge起作用,但看起来很稳固。在将来,我可能会尝试使用按键切换来简化它,如果这是一个安全问题,可能会尝试使用POST而不是GET。