You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular-UI-Bootstrap自动补全文本框三项定制需求求解

定制Angular-UI-Bootstrap自动补全文本框的实现方案

嘿,我来帮你搞定这三个定制需求!咱们一步步调整你的现有代码,把每个功能都实现到位:

需求1:选中列表项时触发事件

Angular UI Bootstrap的typeahead组件专门提供了typeahead-on-select属性,用来处理选中项的回调——比直接用ng-change更精准,毕竟ng-change会在输入过程中就触发,而我们只需要选中项时执行逻辑。

你需要在input标签上添加这个属性,然后在控制器里定义对应的处理函数:

<input type="text" 
       ng-model="selected" 
       uib-typeahead="state.businessName as state.businessName for state in states | filter:$viewValue"
       typeahead-on-select="onItemSelected($item, $model, $label)"
       class="form-control">

控制器里补充回调函数:

$scope.onItemSelected = function(item, model, label) {
  // 这里写你选中项后要执行的逻辑,比如打印选中的企业信息
  console.log('选中了:', item.businessName);
  // 如果需要关联ng-change的原有逻辑,也可以在这里调用对应的函数
};

需求2:未找到匹配项时显示“创建新项”

我们可以自定义一个过滤函数,当现有列表过滤后没有结果时,手动添加一个“创建新项”的选项,同时标记它方便后续处理:

首先在控制器里添加过滤函数:

$scope.filterStates = function(query) {
  // 先过滤现有企业列表
  var filtered = $scope.states.filter(function(state) {
    return state.businessName.toLowerCase().includes(query ? query.toLowerCase() : '');
  });
  // 如果没有匹配结果且输入了内容,添加创建新项选项
  if (filtered.length === 0 && query) {
    filtered.push({ businessName: '创建新项', isNew: true });
  }
  return filtered;
};

然后修改input的typeahead数据源为这个自定义函数:

<input type="text" 
       ng-model="selected" 
       uib-typeahead="state.businessName as state.businessName for state in filterStates($viewValue)"
       typeahead-on-select="onItemSelected($item, $model, $label)"
       class="form-control">

最后在回调函数里区分是否是新项:

$scope.onItemSelected = function(item, model, label) {
  if (item.isNew) {
    // 处理创建新项的逻辑,比如弹出创建表单或跳转页面
    console.log('要创建新项,输入内容为:', $scope.selected);
    // 可以清空输入框方便后续操作
    $scope.selected = '';
  } else {
    // 处理选中已有项的逻辑
    console.log('选中的企业:', item);
  }
};

需求3:获得焦点/点击时显示全部列表项

我们可以通过uib-typeahead-is-open属性控制下拉框的显示状态,结合ng-focus和ng-click事件,在触发时清空查询条件并展开全部列表:

控制器里添加控制变量和触发函数:

$scope.isTypeaheadOpen = false;

$scope.openTypeahead = function() {
  // 清空查询条件,确保显示全部列表
  $scope.selected = '';
  // 手动打开下拉框
  $scope.isTypeaheadOpen = true;
};

修改input标签绑定相关属性:

<input type="text" 
       ng-model="selected" 
       uib-typeahead="state.businessName as state.businessName for state in filterStates($viewValue)"
       typeahead-on-select="onItemSelected($item, $model, $label)"
       uib-typeahead-is-open="isTypeaheadOpen"
       ng-focus="openTypeahead()"
       ng-click="openTypeahead()"
       class="form-control">

完整修改后的代码

HTML部分

<div ng-controller="TypeaheadCtrl">
  <input type="text" 
         ng-model="selected" 
         uib-typeahead="state.businessName as state.businessName for state in filterStates($viewValue)"
         typeahead-on-select="onItemSelected($item, $model, $label)"
         uib-typeahead-is-open="isTypeaheadOpen"
         ng-focus="openTypeahead()"
         ng-click="openTypeahead()"
         class="form-control">
</div>

JavaScript部分

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']); 
angular.module('ui.bootstrap.demo').controller('TypeaheadCtrl', function($scope, $http) { 
  var _selected; 
  $scope.selected = undefined; 
  $scope.isTypeaheadOpen = false;

  $scope.states = [ 
    { "@type":"CR", "companyId":1819, "companyCode":"NVX", "legalName":"Navex", "dbaName":"Navex Inc.", "formation":"P", "firstName":null, "middleName":null, "lastName":null, "dob":null, "registeredAgent":{ "personId":2, "category":null, "firstName":"Arthur", "middleName":"Parho", "lastName":"Benjiman", "dob":null, "addresses":null, "contacts":null, "fullName":"Benjiman, Arthur" }, "filingDate":null, "filingNo":null, "documentNumber":null, "ssn":null, "ein":null, "internal":true, "business":{ "code":"CR", "value":"Carrier" }, "locations":[ { "id":1821, "landmark":"4104 Banner Dr.", "type":{ "code":"P", "value":"Physical" }, "street1":"4104 Banner Dr.", "street2":null, "city":"Houston", "state":"TX", "zip":"77550", "country":null, "latitude":null, "longitude":null, "contacts":[ ], "action":0 } ], "mcNumber":"124578", "dotunitSeries":"111", "billingMethod":null, "businessName":"Navex" }, 
    { "@type":"SH", "companyId":1824, "companyCode":null, "legalName":null, "dbaName":null, "formation":"I", "firstName":"Sikandar", "middleName":"", "lastName":"Ali", "dob":"05/01/2018", "registeredAgent":null, "filingDate":null, "filingNo":null, "documentNumber":null, "ssn":124578963, "ein":null, "internal":true, "business":{ "code":"SH", "value":"Shipper" }, "locations":[ { "id":1825, "landmark":"2202 Jennifer St", "type":{ "code":"P", "value":"Physical" }, "street1":"2202 Jennifer St", "street2":null, "city":"Dallas", "state":"TX", "zip":"77880", "country":null, "latitude":null, "longitude":null, "contacts":[ { "id":1826, "medium":{ "code":"EM", "value":"Email" }, "serviceLocator":"sikandarali744@gmail.com", "prefered":true, "action":0 } ], "action":0 } ], "dotunitSeries":null, "billingMethod":null, "mcNumber":null, "businessName":"Ali, Sikandar" }, 
    { "@type":"TS", "companyId":1827, "companyCode":"", "legalName":"Wayis", "dbaName":"", "formation":"C", "firstName":null, "middleName":null, "lastName":null, "dob":null, "registeredAgent":null, "filingDate":null, "filingNo":null, "documentNumber":null, "ssn":null, "ein":null, "internal":true, "business":{ "code":"TS", "value":"Truck Stop" }, "locations":[ { "id":1828, "landmark":"2001 Ravi St", "type":{ "code":"P", "value":"Physical" }, "street1":"2001 Ravi St", "street2":null, "city":"Dallas", "state":"HI", "zip":"12345", "country":null, "latitude":null, "longitude":null, "contacts":[ ], "action":0 } ], "dotunitSeries":null, "billingMethod":null, "mcNumber":null, "businessName":"Wayis" }, 
    { "@type":"BR", "companyId":1871, "companyCode":"", "legalName":"E2 Financial", "dbaName":"E2F", "formation":"C", "firstName":null, "middleName":null, "lastName":null, "dob":null, "registeredAgent":null, "filingDate":null, "filingNo":null, "documentNumber":null, "ssn":null, "ein":null, "internal":false, "business":{ "code":"BR", "value":"Broker" }, "locations":null, "mcNumber":"124578", "billingMethod":"MCS", "dotunitSeries":null, "businessName":"E2 Financial" } 
  ];

  // 自定义过滤函数,添加创建新项选项
  $scope.filterStates = function(query) {
    var filtered = $scope.states.filter(function(state) {
      return state.businessName.toLowerCase().includes(query ? query.toLowerCase() : '');
    });
    if (filtered.length === 0 && query) {
      filtered.push({ businessName: '创建新项', isNew: true });
    }
    return filtered;
  };

  // 选中项的回调函数
  $scope.onItemSelected = function(item, model, label) {
    if (item.isNew) {
      console.log('准备创建新项,输入内容为:', $scope.selected);
      // 这里可以添加你的创建逻辑,比如打开模态框
      $scope.selected = '';
    } else {
      console.log('选中的企业:', item);
      // 这里添加选中现有项的处理逻辑
    }
  };

  // 打开typeahead下拉框,显示全部列表
  $scope.openTypeahead = function() {
    $scope.selected = '';
    $scope.isTypeaheadOpen = true;
  };

  // 保留你原有的其他代码
  $scope.getLocation = function(val) { 
    return $http.get('//maps.googleapis.com/maps/api/geocode/json', { 
      params: { 
        address: val, 
        sensor: false 
      } 
    }).then(function(response){ 
      return response.data.results.map(function(item){ 
        return item.formatted_address; 
      }); 
    }); 
  }; 

  $scope.ngModelOptionsSelected = function(value) { 
    if (arguments.length) { 
      _selected = value; 
    } else { 
      return _selected; 
    } 
  }; 

  $scope.modelOptions = { 
    debounce: { 
      default: 500, 
      blur: 250 
    }, 
    getterSetter: true 
  }; 

  $scope.statesWithFlags = [{'name':'Alabama','flag':'5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'},{'name':'Alaska','flag':'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'},{'name':'Arizona','flag':'9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'},{'name':'Arkansas','flag':'9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png'},{'name':'California','flag':'0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png'},{'name':'Colorado','flag':'4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png'},{'name':'Connecticut','flag':'9/96/Flag_of_Connecticut.svg/39px-Flag_of_Con'}];
});

内容的提问来源于stack exchange,提问作者Sikandar Sahab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:28:34