Unable to use focus() for wt.PasswordField
In my user interface, I'm using a wt.PasswordField, but I can't use the focus() function (since R2022a) to get the keyboard focus in the password field. Can this be somehow added? I couldn't find any documentation in MATLAB on how you're supposed to add support for focus for custom components...
I'm not a fan of a UI with a single field for entering data, that I have to click on with my mouse, or use TAB to get to.
Hi @versionbayjc, I played around with this a bit and could not come up with anything that worked. I submitted an enhancement request to the development team which is number g3624772.
Hi @versionbayjc , I got some input on how to achieve this. I don't have time to implement it right now, but if you want to play around with it I am including the example below:
fig = uifigure('Name','Testing Focus');
htmlComp = uihtml(fig);
htmlComp.HTMLSource = 'focusEx.html';
htmlComp.Position = [10 10 300 300];
b = uibutton(fig); b.Position = [350 350 100 20];
b.ButtonPushedFcn = @(~,~)sendEventToHTMLSource(htmlComp, 'focusInput', '');
focusEx.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var myComponent;
function setup(htmlComponent) {
myComponent = htmlComponent;
htmlComponent.addEventListener("DataChanged", updateData);
htmlComponent.addEventListener("focusInput", focusInputField);
// MATLAB side 'DataChangedFcn' callback will be triggered
document.getElementById("myInput").addEventListener("change", updateDataToMatlab);
document.getElementById("mainBody").onload = function () {
htmlComponent.dispatchEvent("BODYLOADED");
};
}
function updateData(e) {
var changedData = e.Data;
// Update your HTML or JavaScript with the new data
var dom = document.getElementById("Content");
dom.textContent = changedData;
}
function updateDataToMatlab(e) {
// newData can be passed directly to this function for debug purpose
var newData = document.getElementById("myInput").value;
// Triggering MATLAB DataChangedFcn and change the MATLAB Data
myComponent.Data = newData;
}
function focusInputField(e) {
// Get the input element
const inputElement = document.getElementById('myInput');
// Focus the input element
if (inputElement) {
inputElement.focus();
}
}
</script>
</head>
<body id="mainBody">
<div id ="Content"></div>
</div>
<br/><br/>
<div style="font-family:sans-serif;">
<span style="font-weight:bold;">
The data entered here will be updated to MATLAB:
<br/>
Also when focus event will focus this Input Field
</span><br />
<input type="text" id ="myInput" tabindex="0"></input>
</div>
</body>
</html>
Hi @rjackey, nice input, it works indeed. However, it is only compatible for MATLAB R2023a and later, as the sendEventToHTMLSource method is not available in earlier releases.
This got me thinking about how to solve it for earlier releases as well. I came up with the following solution: if the HTML Data is a structure that contains fields Value and DoFocus, the focus function can be triggered by setting DoFocus in the Data to TRUE instead of triggering a separate event. See example below:
fig = uifigure('Name','Testing Focus');
htmlComp = uihtml(fig);
htmlComp.Data = struct('Value', 'password', 'DoFocus', false);
htmlComp.HTMLSource = 'focusEx.html';
htmlComp.DataChangedFcn = @(s,e) fprintf('Data value changed to: %s\n', e.Data.Value);
htmlComp.Position = [10 10 300 300];
b = uibutton(fig); b.Position = [350 350 100 20];
b.ButtonPushedFcn = @(~,~)set(htmlComp, 'Data', struct('Value', htmlComp.Data.Value, 'DoFocus', true));
focusEx.html:
<input type="text" id="value" style="width:100%;height:100%">
<script type="text/javascript">
function setup(htmlComponent) {
// Code response to data changes in MATLAB
htmlComponent.addEventListener("DataChanged", dataFromMATLABToHTML);
// Update the Data property of the htmlComponent object
// This action also updates the Data property of the MATLAB HTML object
// and triggers the DataChangedFcn callback function
let dataInput = document.getElementById("value")
dataInput.addEventListener("change", dataFromHTMLToMATLAB);
// Trigger a DataChangedFcn callback when enter is pressed.
document.addEventListener("keyup", onKeyPressed);
function dataFromMATLABToHTML(event) {
let changedData = htmlComponent.Data;
console.log("New data from MATLAB:", changedData);
// Update your HTML or JavaScript with the new data
let domValue = document.getElementById("value");
domValue.value = changedData.Value;
// Focus on the input element
if (changedData.DoFocus){
// Focus on input field
domValue.focus();
domValue.select();
// Revert value for focus event
changedData.DoFocus = false;
htmlComponent.Data = changedData;
}
}
function dataFromHTMLToMATLAB(event) {
let newValue = event.target.value;
let newData = htmlComponent.Data;
newData.Value = newValue;
htmlComponent.Data = newData;
console.log("New data in HTML:", newData)
}
function onKeyPressed(event) {
// Get data to change
let newData = htmlComponent.Data;
let domValue = document.getElementById("value");
// ENTER key?
if (event.keyCode === 13) {
newData.Value = domValue.value + "\n";
htmlComponent.Data = newData;
}
}
}
</script>
@versionbayjc we believe this is fixed by @slootsjj. If any issues, reopen this.