【问题标题】:Focus cursor to the end of an input value (CreateView, ModelForm)将光标聚焦到输入值的末尾(CreateView、ModelForm)
【发布时间】:2019-09-11 16:41:37
【问题描述】:

我有一个带有 2 个输入的表单。我正在使用 CreateView 和 ModelForm。还有 {% form %}。

问题:

当“选项卡”到时,我需要第二个输入(它已经有一个初始值),以将光标放在字符串的末尾。
当前行为:
当“制表符”进入第二个输入时,它会突出显示整个字符串。

到目前为止我所拥有的:
我可以通过将这行代码添加到我的 ModelForm init 来自动对焦: self.fields['description'].widget.attrs['autofocus'] = 'on'

我在想这样的事情: self.fields['inc_number'].widget.attrs['onfocus'] = 'INC'[:0] (“INC 是初始值)可能会解决问题。我没有收到任何错误,但是当我从描述输入中选择时,它仍然只是突出显示整个字符串。

对于我的代码,我将尝试只关注最相关的部分。

models.py

class ITBUsage(models.Model):
    """ ITB usage """

    itb = models.ForeignKey(IncidentTriageBridge, related_name='itb',
                            on_delete=models.DO_NOTHING, verbose_name="ITB name")
    description = models.CharField(max_length=100, verbose_name="Description", null=True)
    inc_number = models.CharField(max_length=20, verbose_name="Incident number", null=True)
    ...

views.py

class StartItb(CreateView):
    # class StartItb(CreateView):
    """ Start a bridge by adding a new row in ITBUsage """
    model = models.ITBUsage
    form_class = forms.StartItbForm
    template_name = "itb_tracker/start_form.html"

    initial = {'inc_number': "INC"}  # prefill INC for user

    def get_form_kwargs(self):
        """ inject the extra data """
        kwargs = super().get_form_kwargs()
        ...
        return kwargs 

    def form_valid(self, form):
        ...
        return super().form_valid(form)

上图:initial = {'inc_number': "INC"}这是我目前将“INC”输入到输入中的方式

forms.py:

class StartItbForm(forms.ModelForm):
    """ Start a bridge by adding a for in ITBUsage """

    class Meta:
        model = models.ITBUsage
        fields = ['description', 'inc_number']

    def __init__(self, *args, **kwargs):
        ...

        super().__init__(*args, **kwargs)

        self.fields['description'].widget.attrs['autofocus'] = 'on'

    def clean(self):
    ...
        return cleaned_data

    def clean_inc_number(self):
        """ Validate the INC Number is in the correct format """
        inc_number = self.cleaned_data['inc_number']

        if inc_number and not re.match(r'INC[0-9]+', inc_number):
            raise forms.ValidationError("Format must be 'INC' followed by a number. For example: 'INC123456'")
        return inc_number

    def save(self, commit=True):
        """ inject extra data """
        ...
        return super().save(commit)

上图:self.fields['description'].widget.attrs['autofocus'] = 'on' 是我如何在定向到页面时将光标设置为第一个输入(描述)。

我的表单 html 只是将 {% form %} 与一些 Bootstrap 4 一起使用。功能按预期工作。但这就是为什么我无法将 onfocus 逻辑直接放在输入上的原因。

期望的行为:
用户输入完“description”后,点击“Tab”,光标移到“inc_number”输入的“INC”(初始值)末尾。 (意图是他们不会删除“INC”,而是添加到它的末尾。

【问题讨论】:

    标签: python django


    【解决方案1】:

    widget.attrs 包含小部件的 HTML 属性。您可以设置 onfocus 属性,并且该属性必须是 JavaScript 函数。

    所以它应该看起来像这样:

    self.fields['inc_number'].widget.attrs['onfocus'] = 'this.setSelectionRange(..)

    虽然我不确定这是否适用于所有地方 - 请参阅此帖子:How to set cursor position at the end of input text in Google Chrome

    【讨论】:

    • 那么没有python的方法可以做到吗?它真的应该接受 Javascript 作为字符串吗?
    • 不,您不能在 python 中执行此操作,因为这是需要在浏览器中处理的事情。您通常会为此编写 javascript。
    • 所以不管self.fields['inc_number'].widget.attrs['onfocus'],在我当前的Python Django中没有办法解决我的问题吗?
    • 这样想:您的 django 服务器将 html 发送到浏览器,其中包含用于表单字段的 input 标记。当用户采取行动(如按 TAB)聚焦您的输入字段时,您希望浏览器采取行动并移动光标。所有这些都发生在 django 发送 HTML 之后很久。 python 代码在这里不再起作用。相反,要让浏览器执行此操作,您必须让它执行 JavaScript。
    • widget.attrs 让您做到这一点。
    【解决方案2】:

    因此,基于“rje”的帮助,这就是我为解决问题所做的。

    我不需要在视图中设置初始值。
    但取而代之的是self.fields['inc_number'].initial = "INC" 形式。
    这样我就可以获得长度(而不是硬编码为 3)。
    length = len(self.fields['inc_number'].initial)

    解决方案是
    self.fields['inc_number'].widget.attrs['onfocus'] = 'this.setSelectionRange(length, length)'

    【讨论】:

      猜你喜欢
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      相关资源
      最近更新 更多