Form input widths behave more consistently when resizing

Fixes #919 #920
This commit is contained in:
Nick O'Leary 2016-06-26 23:48:59 +01:00
parent 682345da22
commit c3b1cf7c35
17 changed files with 118 additions and 77 deletions

View File

@ -214,22 +214,29 @@ RED.editor = (function() {
if (input.length === 0 ) {
return;
}
var existingWidthCSS = input[0].style.width;
var newWidth;
if (existingWidthCSS !== '') {
if (/%/.test(existingWidthCSS)) {
newWidth = (input.width()-10)+"%";
} else {
newWidth = input.width()-50;
}
var newWidth = input.width();
var attrStyle = input.attr('style');
var m;
if ((m = /width\s*:\s*(\d+(%|[a-z]+))/i.exec(attrStyle)) !== null) {
newWidth = m[1];
} else {
newWidth = "60%";
newWidth = "70%";
}
var select = $('<select id="'+prefix+'-'+property+'"></select>');
select.width(newWidth);
input.replaceWith(select);
var outerWrap = $("<div></div>").css({display:'inline-block',position:'relative'});
var selectWrap = $("<div></div>").css({position:'absolute',left:0,right:'40px'}).appendTo(outerWrap);
var select = $('<select id="'+prefix+'-'+property+'"></select>').appendTo(selectWrap);
outerWrap.width(newWidth).height(input.height());
if (outerWrap.width() === 0) {
outerWrap.width("70%");
}
input.replaceWith(outerWrap);
// set the style attr directly - using width() on FF causes a value of 114%...
select.attr('style',"width:100%");
updateConfigNodeSelect(property,type,node[property],prefix);
select.after(' <a id="'+prefix+'-lookup-'+property+'" class="editor-button"><i class="fa fa-pencil"></i></a>');
$('<a id="'+prefix+'-lookup-'+property+'" class="editor-button"><i class="fa fa-pencil"></i></a>')
.css({position:'absolute',right:0,top:0})
.appendTo(outerWrap);
$('#'+prefix+'-lookup-'+property).click(function(e) {
showEditConfigNodeDialog(property,type,select.find(":selected").val(),prefix);
e.preventDefault();

View File

@ -112,11 +112,18 @@
this.disarmClick = false;
this.element.addClass('red-ui-typedInput');
this.uiWidth = this.element.width();
this.uiSelect = this.element
.wrap( "<div>" )
.parent();
this.uiWidth = this.element.outerWidth();
this.elementDiv = this.element.wrap("<div>").parent().addClass('red-ui-typedInput-input');
this.uiSelect = this.elementDiv.wrap( "<div>" ).parent();
var attrStyle = this.element.attr('style');
var m;
if ((m = /width\s*:\s*(\d+%)/i.exec(attrStyle)) !== null) {
this.element.css('width','100%');
this.uiSelect.width(m[1]);
this.uiWidth = null;
} else {
this.uiSelect.width(this.uiWidth);
}
["Right","Left"].forEach(function(d) {
var m = that.element.css("margin"+d);
that.uiSelect.css("margin"+d,m);
@ -242,33 +249,31 @@
});
},
_getLabelWidth: function(label) {
var labelWidth = label.width();
var labelWidth = label.outerWidth();
if (labelWidth === 0) {
var newTrigger = label.clone();
newTrigger.css({
var container = $('<div class="red-ui-typedInput-container"></div>').css({
position:"absolute",
top:0,
left:-1000
}).appendTo(document.body);
labelWidth = newTrigger.width()+4;
newTrigger.remove();
var newTrigger = label.clone().appendTo(container);;
labelWidth = newTrigger.outerWidth();
container.remove();
}
return labelWidth;
},
_resize: function() {
if (this.uiWidth !== null) {
this.uiSelect.width(this.uiWidth);
}
if (this.typeMap[this.propertyType] && this.typeMap[this.propertyType].hasValue === false) {
this.selectTrigger.width(this.uiWidth+5);
this.selectTrigger.css('width',"100%");
} else {
this.selectTrigger.width('auto');
var labelWidth = this._getLabelWidth(this.selectTrigger);
var newWidth = this.uiWidth-labelWidth+4;
this.element.width(newWidth);
this.elementDiv.css('left',labelWidth+"px");
if (this.optionSelectTrigger) {
var triggerWidth = this._getLabelWidth(this.optionSelectTrigger);
labelWidth = this._getLabelWidth(this.optionSelectLabel)-4;
this.optionSelectLabel.width(labelWidth+(newWidth-triggerWidth));
this.optionSelectTrigger.css('left',(labelWidth+5)+"px");
}
}
},
@ -338,7 +343,7 @@
if (opt.options) {
if (this.optionSelectTrigger) {
this.optionSelectTrigger.show();
this.element.hide();
this.elementDiv.hide();
this.optionMenu = this._createMenu(opt.options,function(v){
that.optionSelectLabel.text(v);
that.value(v);
@ -361,13 +366,13 @@
if (opt.hasValue === false) {
this.oldValue = this.element.val();
this.element.val("");
this.element.hide();
this.elementDiv.hide();
} else {
if (this.oldValue !== undefined) {
this.element.val(this.oldValue);
delete this.oldValue;
}
this.element.show();
this.elementDiv.show();
}
this.element.trigger('change',this.propertyType,this.value());
}
@ -400,6 +405,13 @@
this.uiSelect.addClass('input-error');
}
return result;
},
show: function() {
this.uiSelect.show();
this._resize();
},
hide: function() {
this.uiSelect.hide();
}
});
})(jQuery);

View File

@ -147,8 +147,9 @@ input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input {
box-sizing: border-box;
display: inline-block;
height: 20px;
height: 34px;
padding: 6px 6px;
margin-bottom: 10px;
font-size: 14px;

View File

@ -24,8 +24,17 @@
vertical-align: middle;
box-sizing: border-box;
overflow:hidden;
position: relative;
.red-ui-typedInput-input {
position: absolute;
left:0;
right:0;
top:0;
bottom:0;
outline: red;
}
input {
width: 100%;
padding: 0 0 0 1px;
margin:0;
height: 32px;
@ -41,6 +50,7 @@
}
a {
box-sizing: border-box;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
padding: 0 1px 0 5px;
@ -72,6 +82,10 @@
&:not(.disabled):hover {
text-decoration: none;
background: $typedInput-button-background-hover;
span {
background: $typedInput-button-background-hover;
}
}
&:focus {
text-decoration: none;
@ -88,13 +102,22 @@
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
padding: 0 5px 0 0;
position:absolute;
left:0;
top:0;
bottom:0;
right:0;
i {
margin-right: 0;
margin-left: 4px;
position:absolute;
right: 4px;
top: 7px;
}
span {
background:#fff;
position:absolute;
left:0;
right:23px;
padding: 0 5px 0 5px;
}
}

View File

@ -17,18 +17,18 @@
<script type="text/x-red" data-template-name="inject">
<div class="form-row">
<label for="node-input-payload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input type="text" id="node-input-payload" style="width:73%">
<input type="text" id="node-input-payload" style="width:70%">
<input type="hidden" id="node-input-payloadType">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input type="text" id="node-input-topic" style="width:70%">
<input type="text" id="node-input-topic">
</div>
<div class="form-row">
<label for=""><i class="fa fa-repeat"></i> <span data-i18n="inject.label.repeat"></span></label>
<select id="inject-time-type-select" style="width:73%">
<select id="inject-time-type-select">
<option value="none" data-i18n="inject.none"></option>
<option value="interval" data-i18n="inject.interval"></option>
<option value="interval-time" data-i18n="inject.interval-time"></option>
@ -148,9 +148,6 @@
.inject-time-count {
width: 40px !important;
}
.red-ui-typedInput-container {
width: 73%;
}
</style>
<script type="text/x-red" data-help-name="inject">
<p>Pressing the button on the left side of the node allows a message on a topic

View File

@ -17,7 +17,7 @@
<script type="text/x-red" data-template-name="debug">
<div class="form-row">
<label for="node-input-typed-complete"><i class="fa fa-list"></i> <span data-i18n="debug.output"></span></label>
<input id="node-input-typed-complete" type="text">
<input id="node-input-typed-complete" type="text" style="width: 70%">
<input id="node-input-complete" type="hidden">
</div>
<div class="form-row">

View File

@ -35,7 +35,7 @@
</div>
<div class="form-row">
<label for="node-input-timer"><i class="fa fa-clock-o"></i> <span data-i18n="exec.label.timeout"></span></label>
<input type="text" id="node-input-timer" style="width:50px; text-align:end;" data-i18n="[placeholder]exec.label.timeoutplace"> seconds
<input type="text" id="node-input-timer" style="width:65px;" data-i18n="[placeholder]exec.label.timeoutplace"> seconds
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
@ -45,10 +45,10 @@
<script type="text/x-red" data-help-name="exec">
<p>Calls out to a system command.<br/></p>
<p>Provides 3 outputs... stdout, stderr, and return code.</p>
<p>By default uses exec() which calls the command, then gets a callback on completion, returning the complete result in one message, along with any errors.</p>
<p>Optionally can use spawn() instead, which returns the output from stdout and stderr as the command runs (usually one line at a time). On completion it then returns a return code (on the 3rd output).</p>
<p>The optional append gets added to the command after the <code>msg.payload</code> - so you can do things like pipe the result to another command.</p>
<p>Provides 3 outputs: stdout, stderr, and return code.</p>
<p>By default uses the <code>exec</code> system call which calls the command, then gets a callback on completion, returning the complete result in one message, along with any errors.</p>
<p>Optionally can use <code>spawn</code> instead, which returns the output from stdout and stderr as the command runs (usually one line at a time). On completion it then returns a return code (on the 3rd output).</p>
<p>The optional append gets added to the command after <code>msg.payload</code> - so you can do things like pipe the result to another command.</p>
<p>Parameters with spaces should be enclosed in quotes - <i>"This is a single parameter"</i></p>
<p>If stdout is binary a <i>buffer</i> is returned - otherwise returns a <i>string</i>.</p>
<p>The blue status icon will be visible while the node is active.</p>

View File

@ -17,7 +17,7 @@
<script type="text/x-red" data-template-name="http in">
<div class="form-row">
<label for="node-input-method"><i class="fa fa-tasks"></i> <span data-i18n="httpin.label.method"></span></label>
<select type="text" id="node-input-method" style="width:72%;">
<select type="text" id="node-input-method" style="width:70%;">
<option value="get">GET</option>
<option value="post">POST</option>
<option value="put">PUT</option>

View File

@ -17,7 +17,7 @@
<script type="text/x-red" data-template-name="http request">
<div class="form-row">
<label for="node-input-method"><i class="fa fa-tasks"></i> <span data-i18n="httpin.label.method"></span></label>
<select type="text" id="node-input-method" style="width:72%;">
<select type="text" id="node-input-method" style="width:70%;">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
@ -56,7 +56,7 @@
<div class="form-row">
<label for="node-input-ret"><i class="fa fa-arrow-left"></i> <span data-i18n="httpin.label.return"></span></label>
<select type="text" id="node-input-ret" style="width:72%;">
<select type="text" id="node-input-ret" style="width:70%;">
<option value="txt" data-i18n="httpin.utf8"></option>
<option value="bin" data-i18n="httpin.binary"></option>
<option value="obj" data-i18n="httpin.json"></option>

View File

@ -21,7 +21,7 @@
<option value="server" data-i18n="tcpin.type.listen"></option>
<option value="client" data-i18n="tcpin.type.connect"></option>
</select>
<span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 50px">
<span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 65px">
</div>
<div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">
<span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;">
@ -121,7 +121,7 @@
<option value="client" data-i18n="tcpin.type.connect"></option>
<option value="reply" data-i18n="tcpin.type.reply"></option>
</select>
<span id="node-input-port-row"><span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 50px"></span>
<span id="node-input-port-row"><span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 65px"></span>
</div>
<div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">

View File

@ -18,7 +18,7 @@
<script type="text/x-red" data-template-name="udp in">
<div class="form-row">
<label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.listen"></span></label>
<select id="node-input-multicast" style='width:62%'>
<select id="node-input-multicast" style='width:70%'>
<option value="false" data-i18n="udp.udpmsgs"></option>
<option value="true" data-i18n="udp.mcmsgs"></option>
</select>

View File

@ -20,7 +20,8 @@
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row">
<span data-i18n="switch.label.property"></span> <input type="text" id="node-input-property" style="width: 300px;"/>
<label data-i18n="switch.label.property"></label>
<input type="text" id="node-input-property" style="width: 70%"/>
</div>
<div class="form-row node-input-rule-container-row">
<ol id="node-input-rule-container"></ol>
@ -101,18 +102,18 @@
}
selectField.width(selectWidth);
if (type === "btwn") {
btwnField1.typedInput("width",(newWidth-selectWidth-80));
btwnField2.typedInput("width",(newWidth-selectWidth-80));
btwnField1.typedInput("width",(newWidth-selectWidth-70));
btwnField2.typedInput("width",(newWidth-selectWidth-70));
} else {
if (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "else") {
// valueField.hide();
} else {
valueField.typedInput("width",(newWidth-selectWidth-80));
valueField.typedInput("width",(newWidth-selectWidth-70));
}
}
}
$("#node-input-rule-container").css('min-height','300px').css('min-width','450px').editableList({
$("#node-input-rule-container").css('min-height','250px').css('min-width','450px').editableList({
addItem: function(container,i,opt) {
var rule = opt||{t:"",v:"",v2:""};
var row = $('<div/>').appendTo(container);
@ -126,7 +127,7 @@
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;margin-right: 10px;"}).appendTo(row);
var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row);
finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> ');
var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2);
$('<label/>',{for:"node-input-rule-case-"+i,style:"margin-left: 3px;"}).text(caseLabel).appendTo(row2);
@ -135,14 +136,14 @@
var type = selectField.children("option:selected").val();
if (type === "btwn") {
valueField.parent().hide();
btwnValueField.parent().show();
valueField.typedInput('hide');
btwnValueField.typedInput('show');
} else {
btwnValueField.parent().hide();
btwnValueField.typedInput('hide');
if (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "else") {
valueField.parent().hide();
valueField.typedInput('hide');
} else {
valueField.parent().show();
valueField.typedInput('show');
}
}
if (type === "regex") {

View File

@ -17,7 +17,7 @@
<script type="text/x-red" data-template-name="change">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" style="width:370px;" data-i18n="[placeholder]common.label.name">
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row" style="margin-bottom:0;">
<label><i class="fa fa-list"></i> <span data-i18n="change.label.rules"></span></label>

View File

@ -17,7 +17,7 @@
<script type="text/x-red" data-template-name="range">
<div class="form-row">
<label for="node-input-action"><i class="fa fa-dot-circle-o"></i> <span data-i18n="range.label.action"></span></label>
<select id="node-input-action" style="width:70%; margin-right:5px;">
<select id="node-input-action" style="width:70%;">
<option value="scale" data-i18n="range.scale.payload"></option>
<option value="clamp" data-i18n="range.scale.limit"></option>
<option value="roll" data-i18n="range.scale.wrap"></option>

View File

@ -79,7 +79,7 @@
<div class="node-row-custom">
<div class="form-row node-row-property">
<label>Combine each </label>
<input type="text" id="node-input-property" style="width:300px;">
<input type="text" id="node-input-property" style="width:70%;">
<input type="hidden" id="node-input-propertyType">
</div>
<div class="form-row">

View File

@ -17,11 +17,11 @@
<script type="text/x-red" data-template-name="html">
<div class="form-row">
<label for="node-input-tag"><i class="fa fa-filter"></i> <span data-i18n="html.label.select"></span></label>
<input type="text" id="node-input-tag" style="width:73% !important" placeholder="h1">
<input type="text" id="node-input-tag" placeholder="h1">
</div>
<div class="form-row">
<label for="node-input-ret"><i class="fa fa-sign-out"></i> <span data-i18n="html.label.output"></span></label>
<select id="node-input-ret" style="width:76% !important">
<select id="node-input-ret" style="width:70%">
<option value="html" data-i18n="html.output.html"></option>
<option value="text" data-i18n="html.output.text"></option>
<option value="attr" data-i18n="html.output.attr"></option>
@ -30,7 +30,7 @@
</div>
<div class="form-row">
<label for="node-input-as">&nbsp;</label>
<select id="node-input-as" style="width:76% !important">
<select id="node-input-as" style="width:70%">
<option value="single" data-i18n="html.format.single"></option>
<option value="multi" data-i18n="html.format.multi"></option>
</select>
@ -38,7 +38,7 @@
<br/>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" style="width:73% !important" data-i18n="[placeholder]common.label.name">
<input type="text" id="node-input-name" style="width:70%" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-tips"><span data-i18n="[html]html.tip"></span></div>
</script>

View File

@ -17,16 +17,16 @@
<script type="text/x-red" data-template-name="xml">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name" style="width:280px !important">
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
</div>
<div class="form-row" id="advanced">
</div>
<div id="advanced-options">
<div class="form-row">
<i class="fa fa-key"></i> <span data-i18n="xml.label.represent"></span> <input type="text" id="node-input-attr" style="width:20px !important" placeholder="$">
<i class="fa fa-key"></i> <span data-i18n="xml.label.represent"></span> <input type="text" id="node-input-attr" style="text-align:center; width:40px" placeholder="$">
</div>
<div class="form-row">
<i class="fa fa-key"></i> <span data-i18n="xml.label.prefix"></span> <input type="text" id="node-input-chr" style="width:20px !important" placeholder="_">
<i class="fa fa-key"></i> <span data-i18n="xml.label.prefix"></span> <input type="text" id="node-input-chr" style="text-align:center; width:40px" placeholder="_">
</div>
<div class="form-tips"><span data-i18n="xml.tip"></span></div>
</div>