请在此处查看解决方案:
https://stackoverflow.com/a/41686102/4180447
上述解决方案可用于在Angular中实现可编辑的下拉列表(select)元素。但是,假设元素的宽度是固定的。现在,我们正在实现响应式设计,我需要一种方法来根据另一个元素的宽度调整元素的宽度。
基本上,实现使用两个元素并将它们放在彼此之上。一个元素是ID以_sel
结尾的select元素,另一个元素是ID以_disp
结尾的文本元素。文本元素必须比下拉元素窄,以便下拉箭头可见。
文本元素的宽度必须比select元素的宽度小约18px。
有没有办法调整文本输入的高度比select元素的大小小18px?
请参阅下面的快照和相关代码以澄清情况:
HTML:
<div class="select-editable stop-wrap" style="width: 265px; border:none">
<select type="text" id="exterior_finish_sel" editable-dropdown="exterior_finish" name="exterior_finish_sel"
ng-model="exterior_finish_sel" ng-options="o as o for o in ddlOptions.exterior_finish track by o" maxlength="80"
class="ng-valid ng-valid-maxlength ng-not-empty ng-dirty ng-valid-parse ng-touched" style="">
</select>
<input type="text" id="exterior_finish_disp" name="exterior_finish_disp" ng-model="exterior_finish_disp" style="width: 247px;"/>
<input type="text" id="exterior_finish" name="exterior_finish" ng-model="exterior_finish" ng-hide="true"/>
</div>
CSS:
.stop-wrap {
display: inline-block;
}
.select-editable {
position:relative;
background-color:white;
border:solid grey 1px;
width:120px;
height:25px;
vertical-align: middle;
margin-bottom: 5px;
}
.select-editable select {
position:absolute;
top:0px;
left:0px;
border:none;
width:118px;
margin:0;
}
.select-editable input {
position:absolute;
top:0px;
left:0px;
width:100px;
padding:1px;
border:none;
}
.select-editable select:focus, .select-editable input:focus {
outline:none;
}
答案 0 :(得分:0)
我在这里找到了基于解决方案的答案:
https://stackoverflow.com/a/18743145/4180447
将监视宽度/位置变化的jQuery插件:
jQuery.fn.onPositionChanged = function (trigger, millis) {
if (millis == null) millis = 100;
var o = $(this[0]); // our jquery object
if (o.length < 1) return o;
var lastPos = null;
var lastOff = null;
var lastWidth = null;
var lastOffWidth = null;
setInterval(function () {
if (o == null || o.length < 1) return o; // abort if element is non existend eny more
if (lastPos == null) lastPos = o.position();
if (lastOff == null) lastOff = o.offset();
if (lastWidth == null) lastWidth = o.width();
if (lastOffWidth == null) lastOffWidth = o[0].offsetWidth;
var newPos = o.position();
var newOff = o.offset();
var newWidth = o.width();
var newOffWidth = o[0].offsetWidth;
if (lastPos.top != newPos.top || lastPos.left != newPos.left) {
$(this).trigger('onPositionChanged', { lastPos: lastPos, newPos: newPos });
if (typeof (trigger) == "function") trigger(lastPos, newPos);
lastPos = o.position();
}
if (lastOff.top != newOff.top || lastOff.left != newOff.left) {
$(this).trigger('onPositionChanged', { lastOff: lastOff, newOff: newOff});
if (typeof (trigger) == "function") trigger(lastOff, newOff);
lastOff= o.offset();
}
if (lastWidth != newWidth) {
$(this).trigger('onPositionChanged', { lastWidth: lastWidth, newWidth: newWidth});
if (typeof (trigger) == "function") trigger(lastWidth, newWidth);
lastWidth= o.width();
}
if (lastOffWidth != newOffWidth) {
$(this).trigger('onPositionChanged', { lastOffWidth: lastOffWidth, newOffWidth: newOffWidth});
if (typeof (trigger) == "function") trigger(lastOffWidth, newOffWidth);
lastWidth= o.width();
}
}, millis);
return o;
};
下面的editable-dropdown
指令:
app.directive('editableDropdown', function ($timeout){
return {
link: function (scope, elemSel, attrs) {
//This is the hidden input, and will be used for data binding
var inpElemID = attrs.editableDropdown;
var inpElem;
//This is the display element and will be used for showing the selected value
var inpElemDispID = inpElemID + "_disp";
var inpElemDisp;
//The parameter 'elemSel' is the SELECT field
function initInpElem() {
//Get a reference to the hidden and displayed text field
if ($(elemSel).is("select")) {
inpElem = $('#' + inpElemID); //Hidden field
inpElemDisp = $('#' + inpElemDispID); //Displayed field
} else {
//This is in case the Dropdown is based on DATALIST which is not yet implemented
//In this case, the input element is actually the same as the dropdown field using DATALIST
inpElem = elemSel;
}
}
initInpElem();
function updateEditable(elm) {
initInpElem();
//Copy value from SELECT element to the INPUT Element
//Use NgModelController to copy value in order to trigger validation for 'inpElem'
var selectedValue = $(elm).children("option").filter(":selected").text();
//Update the hidden text field which is used to save the value to DB
angular.element(inpElem).controller('ngModel').$setViewValue(elm.val());
angular.element(inpElem).controller('ngModel').$render();
//Update the display text field based on the selection (text value)
angular.element(inpElemDisp).controller('ngModel').$setViewValue($(elm).find('option:selected').text());
angular.element(inpElemDisp).controller('ngModel').$render();
makeEditable(elm);
}
function makeEditable(selElm) {
//Allow edit text field if "other" is selected
initInpElem();
if ($(selElm).is("select")) {
//JIRA: NE-2995 - of option seletec starte with "other" then activate editable option
if (selElm.val().toLowerCase().startsWith("other")) {
//Make the display field editable
$(inpElemDisp).prop("readonly", false);
} else {
//Make the display field read-only
$(inpElemDisp).prop("readonly", true);
}
} else {
if (elm.value != "Other" && !$(elm).attr("keypressOff")) {
$(elm).keypress(function(event) {
console.log("keypress preventd")
event.preventDefault();
})
} else {
$(elm).off("keypress");
$(elm).attr("keypressOff", true);
console.log("keypress event removed")
}
}
}
function resizeElem() {
angular.element(document).ready(function() {
initInpElem();
$(inpElemDisp).width($(elemSel).outerWidth()-20);
})
}
angular.element(document).ready(function(){
initInpElem();
//When the display value changes, then update the hidden text field
inpElemDisp.change(function(){
angular.element(inpElem).controller('ngModel').$setViewValue(inpElemDisp.val());
angular.element(inpElem).controller('ngModel').$render();
});
makeEditable(elemSel);
});
//When field values are initialized, ensure the drop-down list and other fields are synchronized
scope.$on('event:force-model-update', function() {
initInpElem();
//Use the value of the hidden field which is saved in DB to update the values of the other fields
var selectedValue = $(elemSel).find('option[value="' + inpElem.val() + '"]').val();
var selectedText;
if (angular.isUndefined(selectedValue)) {
selectedText = inpElem.val();
} else {
//Update the selected value
if (angular.element(elemSel).controller('ngModel')) {
angular.element(elemSel).controller('ngModel').$setViewValue(selectedValue);
angular.element(elemSel).controller('ngModel').$render();
}
$(elemSel).find('option[value="' + inpElem.val() + '"]').attr('selected', 'selected');
selectedText = $(elemSel).find('option:selected').text()
}
//Update the display value
angular.element(inpElemDisp).controller('ngModel').$setViewValue(selectedText);
angular.element(inpElemDisp).controller('ngModel').$render();
});
$(elemSel).change(function () {
//Everytime the selected value is update, then change the display and hidden value
updateEditable(elemSel);
});
$(elemSel).onPositionChanged(function() {
resizeElem();
})
}
}
});
上述代码需要改进才能监控仅对宽度的更改。我会在下一个冲刺中做到这一点。
塔雷克