我想在表单中有一个选择元素,但除了下拉列表中的选项之外,能够编辑它并添加新选项会很有用,但不能使用另一个输入文本,我需要一次全部完成。是否可以?
没有什么是不可能的。这是一个解决方案,只要
<select>
的值发生变化,就简单地设置文本输入的值(已在 Firefox 和 Google Chrome 上测试渲染):
.select-editable {position:relative; background-color:white; border:solid grey 1px; width:120px; height:18px;}
.select-editable select {position:absolute; top:0px; left:0px; font-size:14px; border:none; width:120px; margin:0;}
.select-editable input {position:absolute; top:0px; left:0px; width:100px; padding:1px; font-size:12px; border:none;}
.select-editable select:focus, .select-editable input:focus {outline:none;}
<div class="select-editable">
<select onchange="this.nextElementSibling.value=this.value">
<option value=""></option>
<option value="115x175 mm">115x175 mm</option>
<option value="120x160 mm">120x160 mm</option>
<option value="120x287 mm">120x287 mm</option>
</select>
<input type="text" name="format" value=""/>
</div>
下一个示例将用户输入添加到
<select>
的空选项槽中(感谢@TomerPeled)。它还具有更灵活/可变的 CSS:
.select-editable {position:relative; width:120px;}
.select-editable > * {position:absolute; top:0; left:0; box-sizing:border-box; outline:none;}
.select-editable select {width:100%;}
.select-editable input {width:calc(100% - 20px); margin:1px; border:none; text-overflow:ellipsis;}
<div class="select-editable">
<select onchange="this.nextElementSibling.value=this.value">
<option value=""></option>
<option value="115x175 mm">115x175 mm</option>
<option value="120x160 mm">120x160 mm</option>
<option value="120x287 mm">120x287 mm</option>
</select>
<input type="text" oninput="this.previousElementSibling.options[0].value=this.value; this.previousElementSibling.options[0].innerHTML=this.value" onchange="this.previousElementSibling.selectedIndex=0" value="" />
</div>
<input>
list
属性 和 <datalist>
元素: 执行此操作
<input list="browsers" name="browser">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
(click once to focus and edit, click again to see option dropdown)
但这更像是一个自动完成列表;一旦开始键入,只有包含键入的字符串的选项会保留为建议。这可能实用,也可能不实用,具体取决于您想用它做什么。
与上面的答案类似,但没有绝对定位:
<select style="width: 200px; float: left;" onchange="this.nextElementSibling.value=this.value">
<option></option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<input style="width: 185px; margin-left: -199px; margin-top: 1px; border: none; float: left;"/>
因此创建一个输入框并将其放在组合框的顶部
A bit more universal <select name="env" style="width: 200px; position:absolute;" onchange="this.nextElementSibling.value=this.value">
<option></option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<input style="width: 178px; margin-top: 1px; border: none; position:relative; left:1px; margin-right: 25px;" value="123456789012345678901234"/>layout ...
根据其他答案,这是用于淘汰赛的初稿:
用法
<div data-bind="editableSelect: {options: optionsObservable, value: nameObservable}"></div>
淘汰赛数据绑定
composition.addBindingHandler('editableSelect',
{
init: function(hostElement, valueAccessor) {
var optionsObservable = getOptionsObservable();
var valueObservable = getValueObservable();
var $editableSelect = $(hostElement);
$editableSelect.addClass('select-editable');
var editableSelect = $editableSelect[0];
var viewModel = new editableSelectViewModel(optionsObservable, valueObservable);
ko.applyBindingsToNode(editableSelect, { compose: viewModel });
//tell knockout to not apply bindings twice
return { controlsDescendantBindings: true };
function getOptionsObservable() {
var accessor = valueAccessor();
return getAttribute(accessor, 'options');
}
function getValueObservable() {
var accessor = valueAccessor();
return getAttribute(accessor, 'value');
}
}
});
查看
<select
data-bind="options: options, event:{ focus: resetComboBoxValue, change: setTextFieldValue} "
id="comboBox"
></select>
<input
data-bind="value: value, , event:{ focus: textFieldGotFocus, focusout: textFieldLostFocus}"
id="textField"
type="text"/>
视图模型
define([
'lodash',
'services/errorHandler'
], function(
_,
errorhandler
) {
var viewModel = function(optionsObservable, valueObservable) {
var self = this;
self.options = optionsObservable();
self.value = valueObservable;
self.resetComboBoxValue = resetComboBoxValue;
self.setTextFieldValue = setTextFieldValue;
self.textFieldGotFocus = textFieldGotFocus;
self.textFieldLostFocus = textFieldLostFocus;
function resetComboBoxValue() {
$('#comboBox').val(null);
}
function setTextFieldValue() {
var selection = $('#comboBox').val();
self.value(selection);
}
function textFieldGotFocus() {
$('#comboBox').addClass('select-editable-input-focus');
}
function textFieldLostFocus() {
$('#comboBox').removeClass('select-editable-input-focus');
}
};
errorhandler.includeIn(viewModel);
return viewModel;
});
CSS
.select-editable {
display: block;
width: 100%;
height: 31px;
padding: 6px 12px;
font-size: 12px;
line-height: 1.42857143;
color: #555555;
background-color: #ffffff;
background-image: none;
border: 1px solid #cccccc;
border-radius: 0px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;padding: 0;
}
.select-editable select {
outline:0;
padding-left: 10px;
border:none;
width:100%;
height: 29px;
}
.select-editable input {
outline:0;
position: relative;
top: -27px;
margin-left: 10px;
width:90%;
height: 25px;
border:none;
}
.select-editable select:focus {
outline:0;
border: 1px solid #66afe9;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.select-editable input:focus {
outline:0;
}
.select-editable-input-focus {
outline:0;
border: 1px solid #66afe9 !important;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
另一种解决方法可能是......
使用 HTML:
<input list="myselect" id="myoptions"/>
<datalist id="myselect">
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
<option>option 4</option>
</datalist>
在 Firefox 中,至少焦点后单击会下拉已知有效值的列表,因为
<datalist>
元素 IFF 字段恰好为空。否则,必须清除该字段才能在输入数据时看到有效的选择。接受输入的新值。必须用 JS 或其他方式处理新值才能持久化它们。
这并不完美,但它足以满足我的极简需求,所以我想我会分享。
感谢@Arraxas的anwser,我自定义了箭头并使
input
元素自动适应select
元素,并且在我的Android手机的Chrome,Firefox上看起来不错(设置color:transparent
为 select
和 option
添加一些颜色以隐藏 select
的文本显示,因为 input
和 .combobox div:after
无法完全覆盖 select
)。
/* https://stackoverflow.com/questions/13694271/modify-select-so-only-the-first-one-is-gray/41941056#41941056
select option:first-child, */
.combobox select, .combobox select option { color: #000000; }
.combobox select:invalid, .combobox select option[value=""] { color:grey; }
.combobox {position:absolute; left:80px; top:6px;}
.combobox>div { position:relative; font-size:1em; }
.combobox select {
font-size:inherit; color:transparent;
padding:0; -moz-appearance:none; -webkit-appearance:none; appearance:none;
border:1px solid blueviolet;
}
.combobox input {
position:absolute;top:1px;left:0px; text-overflow:ellipsis;
box-sizing:border-box; padding:0px; margin:0px; height:calc(100% - 1px); width:calc(100% - 20px);
border:1px solid blueviolet; border-right:none; border-top:none;
}
.combobox>div:after{
position:absolute; top:0px; right:0px; height:100%; width:20px;
box-sizing:border-box; content:"▼"; border:1px solid blueviolet; pointer-events:none;
display:flex; flex-direction:row; align-items:center; justify-content:center;
}
.combobox select:focus, .combobox input:focus {outline:none;}
<!-- mandatory benefits/social security/welfare -->
<div class="combobox"><div>
<select id=MandatoryBenefits onchange="this.nextElementSibling.value=this.value" required>
<option value="" selected>Select ...</option>
<option value="Pension">Pension %</option>
<option value="Medical">Medical %</option>
<option value="Unemployment">Unemployment %</option>
<option value="Injury">Injury %</option>
<option value="Maternity">Maternity %</option>
<option value="Serious Illness">Serious Illness %</option>
<option value="Housing Fund">Housing Fund %</option>
</select>
<input type="text" value="" onchange="this.previousElementSibling.selectedIndex=0"
oninput="this.previousElementSibling.options[0].value=this.value; this.previousElementSibling.options[0].innerHTML=this.value" />
</div></div>
在线演示(@jsbin)