angularjs - multiple - Permitir el texto introducido manualmente en ui-select
ui select multiple angular (5)
Aquí hay una solución:
HTML -
<ui-select ng-model="superhero.selected">
<ui-select-match placeholder="Select or search a superhero ...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="hero in getSuperheroes($select.search) | filter: $select.search">
<div ng-bind="hero"></div>
</ui-select-choices>
</ui-select>
CONTROLADOR -
$scope.getSuperheroes = function(search) {
var newSupes = $scope.superheroes.slice();
if (search && newSupes.indexOf(search) === -1) {
newSupes.unshift(search);
}
return newSupes;
}
Aquí está la solución CodePen .
Estoy usando un cuadro de selección de ui-select. Todo funciona bien, pero quiero permitir el texto introducido manualmente y no quiero restringir al usuario de los valores disponibles en la lista. Si escribo texto, filtra mi lista correctamente. Pero cuando no hago clic en un elemento y me muevo al siguiente campo, mi texto se descartará.
¿Algunas ideas?
Gracias y saludos, Alex
No quise mostrar mi código porque creo que no es correcto, pero fue solicitado:
<ui-select ng-model="formData[field.id].selected" theme="bootstrap">
<ui-select-match placeholder="{{ lists[field.id].placeholder }}">{{$select.selected.text}}</ui-select-match>
<ui-select-choices repeat="item in lists[field.id].list | filter: $select.search">
<div ng-bind-html="item.text | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
Los datos se almacenan en formData[field.id].selected
. field.id
es el número del campo actual a mostrar (estoy generando mi formulario dinámicamente). Solo asuma que almacena un valor int único.
Editar 08.04.2015 Mi solución: descubrí que parece que no hay un combobox equivalente a C #. Así que seguí adelante y usé dos campos separados. No es lo que quería, pero funciona por ahora:
<ui-select ng-model="formData[field.id].selected" theme="bootstrap">
<ui-select-match placeholder="{{ lists[field.id].placeholder }}">{{$select.selected.text}}</ui-select-match>
<ui-select-choices repeat="item in lists[field.id].list | filter: $select.search">
<div ng-bind-html="item.text | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<?php echo __(''Create a new element if value is not in list''); ?>
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" ng-model="disabled[field.id]">
</span>
<input type="text" value="" ng-disabled="!disabled[field.id]" class="form-control" ng-model="formData[field.id].newValue" />
</div>
Creo que encontré una manera de permitir al usuario crear nuevas entradas. Use el atributo "on-select" para pasar una función que toma $ select como parámetro como se muestra a continuación:
<ui-select ng-model="person.selected"
theme="select2"
on-select="peopleSel($select)"
tagging
reset-search-input="false"
>
<ui-select-match placeholder="Enter a name...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="sel in people | filter: {name: $select.search}">
<div ng-bind-html="sel.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
Luego cree la función que agregue una nueva entrada cuando la variable clickTriggeredSelect sea falsa:
$scope.peopleSel= function(sel) {
if ( sel.search && ! sel.clickTriggeredSelect ) {
if ( ! sel.selected || sel.selected.name != sel.search ) {
//Search for an existing entry for the given name
var newOne= personSearch( sel.search );
if ( newOne === null ) {
//Create a new entry since one does not exist
newOne= { name: sel.search, email: ''none'', country: ''unknown'' };
$scope.people.push( newOne );
}
//Make the found or created entry the selected one
sel.selected= newOne;
}
}
sel.search= ''''; //optional clearing of search pattern
};
Tenga en cuenta que la definición de personSearch no se proporciona aquí. También este enfoque de probar el clickTriggeredSelect se puede usar para permitir al usuario deseleccionar el campo si la preferencia es una entrada en blanco.
CLORURO DE POLIVINILO
He bifurcado el proyecto ui-select para permitir esta funcionalidad a través del atributo de permiso de texto libre
<ui-select allow-free-text="true" ng-model="ctrl.freeTextDemo.color2" theme="bootstrap" style="width: 800px;" title="Choose a color">
<ui-select-match placeholder="Select color...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="color in ctrl.availableColors | filter: $select.search">
<div ng-bind-html="color | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
Aquí está el plnker
Hasta que mi solicitud de extracción sea aceptada por el equipo de angular-ui, puede obtener la compilación ui-select que incluye mi parche en mi propio repositorio.
Puede usar el atributo de etiquetado como se explica en la documentación: https://github.com/angular-ui/ui-select/wiki/ui-select
<ui-select multiple tagging tagging-label="(custom ''new'' label)" ng-model="multipleDemo.colors">
...
</ui-select>
Uso keyup
para agregar una nueva opción que representa el texto ingresado. Con este enfoque, si el usuario presiona enter
, puede seleccionar lo que ha ingresado hasta el momento (el elemento activo predeterminado es el primer elemento).
Esto admite ambos casos cuando la lista de datos contiene texto u objeto sin formato (se requiere atributo value-prop
).
Directiva:
commonApp.directive("uiSelectFreeText", function () {
return {
restrict: "A",
require: "uiSelect",
link: function (scope, element, attrs, $select) {
var searchInput = element.querySelectorAll("input.ui-select-search");
if (searchInput.length !== 1) {
console.log("Error! Input not found.");
return;
}
searchInput.on("keyup", function () {
var valueProp = attrs["valueProp"];
var addNewObjOption = function () {
// add new item represent free text option
var newOption = { isFreeText: true };
newOption[valueProp] = $select.search;
$select.items.unshift(newOption);
};
if ($select.items.length > 0) {
var firstItem = $select.items[0];
if (valueProp) {
// items is list of Object
if (firstItem.isFreeText) {
firstItem[valueProp] = $select.search;
} else {
addNewObjOption();
}
} else {
// items is list of string
if (firstItem === $select.search) {
return;
} else {
$select.items.push($select.search);
}
}
} else {
if (valueProp) {
addNewObjOption();
} else {
// items is list of string
$select.items.push($select.search);
}
}
});
}
};
});
HTML:
<ui-select class="ui-select-control"
ui-select-free-text value-prop="Label"
ng-model="keyword">
</ui-select>