Focus on inputfield after DOM is loaded with Blazor - javascript

I want that my inputfield is focused when when I open the Website, it always focus the Link when I start it.
Secondly I have to Sacn muliple numbers into my inputfield with a Scanner. It triggers my function addToTable. So my number will be added to a list. after that It should clear the inputfield and focus on it again, so I can scan in the next number:
<input id="LeNumber" name="LeNumber" #onkeydown="addToTable" #onclick:preventDefault="#isPreventDefault"/>
private async void addToTable(KeyboardEventArgs args)
{
if (args.Key != "Tab")
{
LeNumber += args.Key.ToString();
}
else
{
if (!string.IsNullOrWhiteSpace(LeNumber))
{
if (todos.Contains(LeNumber))
{
LeNumber = null;
await SetValueBack("LeNumber");
await TurnRed("table");
await Focus("LeNumber");
}
else
{
if (LeNumber == "submit")
{
generateXml();
b += 1;
}
else
{
todos.Add(LeNumber);
LeNumber = null;
await SetValueBack("LeNumber");
await TurnNormal("table");
await Focus("LeNumber");
}
}
}
}
}
The Problem now is that it doesn't set the focus back on my inputfield. To set my Focus I have a JS Function witch do: document.getElementByID(id).focus().
That doesn't work but it works if I put a delay in like the following:
function focusElement(id) {
setTimeout(function () {
document.getElementById(id).focus();
}, 3000);
}
I Think it doesnt work because the focus gets lost when it displays the List:
#{
for (int i = 0; i < todos.Count; i++)
{
if (i % 2 == 0)
{
#:<tr>
<td>#todos[i]</td>
}
else
{
<td>#todos[i]</td>
#:</tr>
}
}
}
Is there a way to set the focus after everything is done? Because It would be very "ugly" to do this with the delay

Blazor has a method for this. FocusAsync().
I believe if you call it in the OnAfterRender handler, or in your event handlers, you will achieve what you want.
https://www.youtube.com/watch?v=lLypM7oBwyA

Related

Supress on click event in react

This is an on-click function for the identifier button. This function will trigger a popup design function when the user clicks on some feature on the map. I want this click functionality on that feature to be suppressed when the user clicks the identifier button a second time. This means the identifier button should act like a start-stop switch.
This function is inside useEffect() and the #IdentifierClick is the id for the button which is in return{} part which will trigger the click event.
const IdentifierClick = () => {
console.log("working");
// clicktimes = clicktimes+1;
// console.log("Button click times ",clicktimes)
if((enableIdentify == false))
{
initialMap.on('singleclick', function (evt)
{
console.log(evt, "printevt");
var myLayerChecked;
console.log(layerlist, "printlayerlist");
for (let i = 0; i <= 4; i++)
{
layerlist[1].values_.layers.array_[i].values_.layers.array_.forEach(arrayItem => {
myLayerChecked = arrayItem.state_.visible;
console.log("myLayerChecked", myLayerChecked);
// console.log(layerlists,"printlayerlist");
if (myLayerChecked == true) {
document.getElementById('popup-content').innerHTML = '<p class="identifier_p"><b>Identifier Details</b></p>';
console.log("My Array Data", arrayItem.values_.source)
designHtml(evt, arrayItem.values_.source, arrayItem.values_.title);
enableIdentify = true;
}
else
{
console.log("No Layer is checked");
}
});
}
})
}
else {
}
});
The intialMap.on('singleclick',function()) should be enabled and disabled by IdentifierClick function when we click to trigger the function. Please help me achieve this task.

Trouble with multiple choice quiz

Having trouble with the code below. When user clicks a button, I want to set the value of clickedAnswer accordingly. Then I can validate the button clicked against the answer later on. Currently, I'm logging a 4 every time. Any help is greatly appreciated!
let clickedAnswer = 1;
function setClickedAnswer(button) {
if (button.id === "option1") {
clickedAnswer = 1;
} else if (button.id === "option2") {
clickedAnswer = 2;
} else if (button.id === "option3") {
clickedAnswer = 3;
} else {
clickedAnswer = 4;
}
validateAnswer();
console.log(clickedAnswer);
}
answer1.addEventListener("click", setClickedAnswer);
answer2.addEventListener("click", setClickedAnswer);
answer3.addEventListener("click", setClickedAnswer);
answer4.addEventListener("click", setClickedAnswer);
The function is expecting the button itself to be passed:
function setClickedAnswer(button) {
However, no such button is passed:
answer1.addEventListener("click", setClickedAnswer);
What is sent to an event handler by default is the event object itself, which has a target property referring to the element invoking the event. So you can do this:
if (button.target.id === "option1") {
(repeat for the other conditions, of course)
Alternatively, if you prefer the function to expect a button element, you can wrap a function around your event handler invokation and pass the element there:
answer1.addEventListener("click", () => setClickedAnswer(answer1));
or:
answer1.addEventListener("click", function () { setClickedAnswer(answer1); });

Type Script BeforeUnloadEvent not firing

In my application I have an comment box where I would like to display a message that it was not saved. In the function warnOpenEditor I have added window.onbeforeunload event but it will not fire. Attached TS and html file.
Is there anything else I need to do for this event to fire?
TS file
import
#HostListener('window:beforeunload', ['$event'])
beforeUnloadHander(event) {
if (this.IsTouched = true) {
event.returnValue = 'You have unfinished changes!';
}
}
private cancel() {
this.IsTouched = false;
if (this.comments.length === 0) {
this.hideComments();
} else {this.hideEditor();}
this.commentText = "";}
private warnOpenEditor() {
this.IsTouched = true;
for (let i = 0; i < 2; i++) {
this.$commentForm.fadeTo(100, 0.3).fadeTo(100, 1.0);}
}
}
SideCommentsComponet.html
<p class="comment" [innerHTML]="comment.Content | newline">
Did you try to move unload event out of method?
You should use this code
#HostListener('window:beforeunload', ['$event'])
beforeUnloadHander(event) {
//check your comment box value to show message
}

I only want to have the click add one count, not repeated additions to the content

In class we are learning JavaScript, and we have to find out how to stop the button click from repeatedly adding the count with .insertbefore
I'm stumped as to why it continually inserts the count.
function clicked() {
console.log("Clicked!");
var count = "Node Count: "+countChildren(document.getElementById("content"));
console.log(count);
try {
var span = document.createElement("span");
span.innerHTML = count;
document.getElementsByTagName("body")[0].insertBefore(span, document.getElementById("content"));
} catch(ex) {
console.log("error "+ex)
}
}
You need to check if the node is already added.
var count = ...
if ( count !== 0 ) {
return;
}
try {
...
}
catch(ex) {
...
}
Modify your button HTML like this
<input type ="button" onclick="clicked(); this.onclick=null;"/>
so when once click function is executed, this will stop further clicking actions

Can't make TAB change the editor on dgrid

I'm trying to make the TAB key navigate on my dGrid. I have used as a base the solution found at Dgrid set focus on cell, but there are a couple of issues I'm running into which I couldn't solve so far.
Below you can find the block I'm using now; Not all columns have editors, so for I added a var do the element definition to select the next column instead of doing a right. I also added support for SHIFT+TAB to make backwards navigation possible. MT4.prje.grids[gridId]is the dGrid instance. There might be various on the page.
The grid is created with
MT4.prje.grids[gridId] = new (declare([OnDemandGrid, Keyboard, Selection, CellSelection]))(gridInfo, gridId);
where gridInfo has the column definitions and the store. The store is created as:
new Observable(new Memory({'data': {}, 'idProperty': 'id'}));
The editors are usually TextBox, NumberTextBox and Select dijit widgets, all set to autoSave.
aspect.after(MT4.prje.grids[gridId], "edit", function (promise, cellNode) {
if (promise === null) return;
promise.then(function (widget) {
if (!widget._editorKeypressHandle) {
widget._editorKeypressHandle = on(widget, "keypress", function (e) {
for (var rowId in MT4.prje.grids[gridId].selection) {
break;
}
for (var columnId in MT4.prje.grids[gridId].selection[rowId]) {
break;
}
if (e.charOrCode == keys.TAB) {
e.preventDefault();
var cellToEdit = null,
cellEdited = MT4.prje.grids[gridId].cell(rowId, columnId);
if (e.shiftKey) {
if (cellEdited.column.previousEditor === undefined) {
rowId = parseInt(rowId) - 1;
if (MT4.prje.grids[gridId].row(rowId).element !== null) {
for (var lastColumnId in MT4.prje.grids[gridId].columns) {}
cellToEdit = MT4.prje.grids[gridId].cell(rowId, lastColumnId);
}
} else {
cellToEdit = MT4.prje.grids[gridId].cell(rowId, cellEdited.column.previousEditor);
}
} else {
if (cellEdited.column.nextEditor === undefined) {
var firstColumnId = null;
rowId = parseInt(rowId) + 1;
if (MT4.prje.grids[gridId].row(rowId).element === null) {
var fields = {};
for (var cId in MT4.prje.grids[gridId].columns) {
if ((cId != 'excluir') && (firstColumnId === null)) {
firstColumnId = cId;
}
fields[cId] = '';
}
MT4.prje.addRowToGrid(gridId, fields);
} else {
for (var cId in MT4.prje.grids[gridId].columns) {
if (cId != 'excluir') {
firstColumnId = cId;
break;
}
}
}
cellToEdit = MT4.prje.grids[gridId].cell(rowId, firstColumnId);
} else {
cellToEdit = MT4.prje.grids[gridId].cell(rowId, cellEdited.column.nextEditor);
}
}
if (cellToEdit) {
MT4.prje.grids[gridId].deselect(cellEdited);
MT4.prje.grids[gridId].select(cellToEdit);
MT4.prje.grids[gridId].edit(cellToEdit);
}
}
});
}
});
});
Even ignoring the new line part, there are a couple of errors that happen. First of all, the editor barely pops into existence and them disappears, together with the selection. Sometimes when tabbing to an empty column, the editor will be filled with the values of the previous editor. Is there a way to do it more consistently?
What I'm figuring is that there is a race condition happening on the sharedEditor (they are set to editOn: focus). I tried wrapping the deselect/select on a dojo.on('blur') and emit it. But that doesn't get consistently correct with the dijit/form/Select widgets. Is there a better event that I can call for it?
I also tried changing the final block to:
if (cellToEdit) {
on(cellToEdit.element, 'focus', function(){
MT4.prje.grids[gridId].select(cellToEdit);
});
on(cellEdited.element, 'blur', function(){
MT4.prje.grids[gridId].deselect(cellEdited);
on.emit(cellToEdit.element, 'focus', {'bubble': true, 'cancelable': false});
});
on.emit(cellEdited.element, 'blur', {'bubble': true, 'cancelable': false});
}
But that gives two errors:
If I do make changes to a cell it does not go to the next editor. Does not even select it.
The first time I move from an empty cell to another empty cell it doesn't work either.
Anyone got any ideas?
This fix works on dgrid 0.3.11.
Add to your dgrid's postCreate.
postCreate: function() {
var that = this;
this.inherited(arguments);
this.on('dgrid-datachange', function(evt) {
that._selectedCell = that.cell(evt);
});
aspect.after(this, 'save', function(dfd) {
dfd.then(function() {
var nextCell = that.right(that.cell(that._selectedCell.row.id, that._selectedCell.column.id));
that.edit(nextCell);
// Bonus Fix. Workaround dgrid bug that blocks field text to be selected on focus.
nextCell.element.widget && nextCell.element.widget.textbox && nextCell.element.widget.textbox.select();
});
});
}

Categories