Angular:删除项目后自动完成字段更改焦点

Posted

技术标签:

【中文标题】Angular:删除项目后自动完成字段更改焦点【英文标题】:Angular: autocomplete field changes focus after removing an item 【发布时间】:2018-01-10 18:55:16 【问题描述】:

我有一个使用 PrimeNG 组件的 Angular 2 应用程序。

UI 具有多选 (p-autoComplete) 的自动完成组件,类似于 the documentation 中的那个:

<p-autoComplete [(ngModel)]="countries" 
                [suggestions]="filteredCountriesMultiple" 
                (completeMethod)="filterCountryMultiple($event)" 
                [minLength]="1" 
                placeholder="Countries" 
                field="name" 
                [multiple]="true">
</p-autoComplete>

唯一的区别是,在我的例子中,输入字段有固定的尺寸和滚动条。

问题:

每当我从自动完成列表的中间删除一个元素时,它都会将焦点移到输入字段的底部。它看起来像这样:

这对用户来说很烦人,尤其是当有几个字段应该被删除时。

问题:如何在移除元素后强制滚动保持在同一位置?

如何重现:

更具体地说,您可以通过添加下一个 css 来重现问题

max-width: 150px;
max-height: 100px;
overflow-y: auto;

使用浏览器控制台直接将documentation page 转换成ui-autocomplete-multiple-container.ui-inputtext css 类。

更新: 我设法通过使用如下代码在组件中设置onUnselect 方法来获取滚动条位置:

onUnselect(event: any) 
    document.querySelector("div.my-input-class").scrollTop

更新 2:我设法让它工作

解决方案是onUnselectonFocus 事件处理程序的组合。

首先。我将最后一个滚动条位置保存到 onUnselect 调用中的字段中。

第二。我在onFocus 调用期间将此值设置为指定元素。

对应的代码如下:

scrollPosition: number = 0;

onUnselect(event: any) 
    let input = document.querySelector("div.my-input-class");
    this.scrollPosition = input.scrollTop;


onFocus(event: any) 
    let input = document.querySelector("div.my-input-class");
    input.scrollTop = this.scrollPosition;

效果很好,可能这将是最终的解决方案。

但是我不喜欢它。如果 PrimeNG 的人在他们的组件中嵌入这样一个有用的功能会更好。对我来说很奇怪为什么它不开箱即用。

如果您找到更好的解决方案,请提出。

【问题讨论】:

你能创建一个 plunker 来复制吗? 似乎是光标导致了跳跃行为。所以我建议在删除项目时尝试禁用光标(可能通过禁用元素)或在删除项目之前尝试将焦点切换到其他元素。我不知道您使用的控件是否可以让您这样做,但在我可以访问计算机之前我无法对其进行测试 另外,这是我见过的最好的结构化问题之一。很容易看到/理解您的问题。感谢您投入时间和精力! 【参考方案1】:
onUnselect(event: any) 
    // get index of the removed element
    // get total options count
    // get height of the element that contains the options
    // divide the height by number of options
    // set scroll potion to the result of division multiplied by the index
   document.querySelector('.ui-autocomplete-multiple-container.ui-inputtext').scrollTop = calculatedValue; 

【讨论】:

您建议如何设置滚动位置?我得到了元素并设置了它的scrollTop,即使没有计算它也不起作用。假设我将元素的 scrollTop 设置为 100 - 滚动条像以前一样跳到底部。 这正是我刚刚在评论中解释的内容,我尝试过这种方式,但它不起作用:( 你确定你没有遗漏任何东西。我刚刚将此代码粘贴到您发送的文档链接上,它对我有用 尝试将其包装在 setTimeout 调用中并使用从 0 开始的延迟 您是如何将代码注入该页面的?或者您尝试在没有onUnselect 关系的情况下调用它一次?【参考方案2】:

您应该使用onFocus 事件来处理与以下相同的情况,

<p-autoComplete [(ngModel)]="countries" 
                [suggestions]="filteredCountriesMultiple"                     
                (completeMethod)="filterCountryMultiple($event)" 
                styleClass="width12" (onFocus)="onFocus($event)">

  ....


onFocus(event)
      window.scrollTo(0, 0);


LIVE DEMO

【讨论】:

可能是我做错了什么,但我试过了,但它不起作用。并且该演示没有任何滚动条,因此无法检查它。无论如何,我不明白如何设置窗口的属性对特定页面元素内的滚动条的影响?在我的情况下,我需要在输入元素内设置滚动条的位置,而不是页面中的位置。 @OleksandrShpota 减小窗口大小并进行测试。 现在我明白你的意思了。可能问题并不完全清楚 - 我需要控制输入元素上的滚动条,而不是窗口中的滚动条。您提出的代码更改了窗口的滚动位置。 您也可以将它用于element。使用 event.srcElement.scroll.... 我不确定的确切对象。做一个控制台日志和演练。我在移动网站。如果您需要更多帮助,请告诉我 谢谢。此调用得到反映,我将尝试计算正确的滚动条位置。

以上是关于Angular:删除项目后自动完成字段更改焦点的主要内容,如果未能解决你的问题,请参考以下文章

Angular-Kendo 在更改时自动完成所选值

jQuery:在字段中发生自动完成后删除错误

移除 React Material ui 组件中自动完成的下划线样式

Angular2动态输入字段在输入更改时失去焦点

使用 angular.js 按自动编号字段删除记录

Angular:防止资产文件夹发生更改时自动重新编译