Toggle visibility of typedInput field - layout issue

Hi folks,

In my camera-viewer node I have a dropdown, where you can choose between two options (push and pull). For each of those options, another typedinput field should be displayed. So when you select the 'push' option, then the typedinput for pushing will be shown (and the typedinput for the 'pull' option will be hidden).

But as soon as I select an option in the dropdown, the grey box of the typedinput will be shrinked entirely. Afterwards when I press 'Done' and reopen the config screen, the same grey box is displayed correctly:

typedinput_shrinked

This is the html part with the dropdown and the two typedinput fields:

<div class="form-row">
       <label for="node-input-source"><i class="fa fa-sign-in"></i> Source</label>
       <select id="node-input-source">
            <option value="pull">URL (pull)</option>
            <option value="push">Message (push)</option>
       </select>
</div>
<div class="form-row pull-row">
       <label for="node-input-typed-pullSource"><i class="fa fa-globe"></i> URL</label>
       <input id="node-input-typed-pullSource" type="text" style="width: 70%">
       <input id="node-input-pullSource" type="hidden">
</div>
<div class="form-row push-row">
       <label for="node-input-typed-pushSource"><i class="fa fa-file-image-o"></i> Image</label>
       <input id="node-input-typed-pushSource" type="text" style="width: 70%">
       <input id="node-input-pushSource" type="hidden">
</div>

The oneditprepare part is also pretty normal:

$("#node-input-typed-pushSource").typedInput({types: ['msg']});
$("#node-input-typed-pushSource").typedInput('type', node.pushSource.type || 'msg');
$("#node-input-typed-pushSource").typedInput('value', node.pushSource.value || 'payload');       

$("#node-input-typed-pullSource").typedInput({types: ['msg', 'str']});
$("#node-input-typed-pullSource").typedInput('type', node.pullSource.type || 'msg');
$("#node-input-typed-pullSource").typedInput('value', node.pullSource.value  || 'payload'); 

And below is the change handler of the dropdown (in oneditprepare), where I specify which of both typedinput fields should become visible (based on the 'push-row' and 'pull-row' classes):

$("#node-input-source").change(function() {
       var source = $("#node-input-source").val();

       switch (source) {
              case "pull":
                      $(".pull-row").show();
                      $(".push-row").hide();
                      break;
              case "push":
                      $(".push-row").show();
                      $(".pull-row").hide();
                      break;
       }
}); 

Not really rocket science ... Does anybody have idea about what I'm doing wrong?

Thanks !!
Bart

1 Like

I had tonnes of issues with typedinput when writing image-tools. I mean loads of stupid redraw, missing parts, no input possible, I was at my wit's end with what should have been simple.
I did eventually get something working and left it once stable (ugly hacks that can be probably cleaned up but I'm not going through the pain again). Code

Anyhow, what I did was to recreate the typedinput when the user chose different functions.
I wrote helper functions that rebuilt the typedinput based on their selected option. In my case that make plenty sense as there were over 40 options and each option had up to 8 differing parameters.

If you install node-red-contrib-image-tools and see how the parameters change with each image function and like how it works, then you can just rob the code.

Did you feed any of these issues back so we could investigate and address them?

I think what is happening is when the typedInput is created it calculates the width of the select icon on the left, but as you have it hidden, that's coming up with a width of 0 which is why it looks wrong when it gets displayed.

You could try calling $("#node-input-typed-pushSource").typedInput('width') after showing the row to trigger it to resize.

Short version...
Unfortunately not.

Long version...
I was assuming it was my fault and use/abuse of the jQuery widgeting methods. I was full steam ahead/in the zone trying to get past what I thought were my bugs (and possibly still were) resolved before bothering anyone.

I did witness what @BartButenaers describes.

Just to close out on this from my side - I've pushed a fix that should mean the label width is calculated properly without you having to take any extra steps in the future.

1 Like

Hey @Steve-Mcl, thanks for sharing your workaround! By looking at your code, I can now confirm that your 'hack' doesn't contain any non-legal or criminal or unethical stuff. So from now on you are official certified as Node-RED White-hat hacker :wink:.

Thanks again @knolleary. That indeed solves my problem! I have also added a comment to my code, to indicate that you have fixed this meanwhile. So I can remove this line in the future, and people reading my code can learn from it ...

Oh trust me it's a hack. Haha.

From what I remember, calling ttpedinput with "destroy" is supposed to be enough but whether due to timing or something, I'd get errors like "not a widget" or the hidden element would be unhidden or I'd get 2 when I recreated the typedinput (the original supposedly destroyed) and the newly created one.

And a bit more is coming back...
Ideally, I wanted to add and remove options (like add "str", remove "num" rather than destroy & recreate) but seem to remember it wasn't possible? Maybe it is (or should be)

https://nodered.org/docs/api/ui/typedInput/#methods-types

You know, I read that page many times and I'm certain I tried everything. I'm gonna have another bash at tidying up my code & then on to eat my words.

Fresh pair of eyes here, I’m seeing the trick. I read your linked code a while earlier so I don’t have your exact variables in mind, but instead of destroying, call the .typedInput(‘types’, ...) and replace that ... by an array of allowed types (array with just 1 element is still an array, so [‘str’] (with correct quotes but I’m on my phone) is a valid option too). Then to make sure it handles the overrule, use .typesInput(‘type’, ...) to set the input to the specified type, where ... is now the singular type as string.

Hope that helps you see it :slight_smile:

1 Like

thank you ! which branch / release is this fix please ?

It is in the dev branch for the 1.0 release.