Best practice to register custom focus event handler for input fields - focus

Sadly, I don't find any focus event for sap.m.Input or sap.m.TextArea to which I can register handlers in XML view.
What are your best practices e.g. if you have nearly 100 fields and most of them should handle focus event so that the text within the input field gets automatically selected?
Normally, I try to avoid to register the focusin handler in controller on every input field (also looping) but it seems that there are no other possibilities available isn't it?
What I want is a possibility, that when I navigate e.g. with keyboard through a table with input fields, every time when I press the tab or updown arrow keys to jump to next input field, the whole content of the input field should be selected.
Example:
Open this table sample.
Click on Edit.
When tabbing, it automatically selects the text. But it doesn't work with updown arrow keys and with sap.m.Input class.

Here is a working example of an extended sap.m.Input that selects the text on focus: https://embed.plnkr.co/98BIbMEIujbzBXqU
Input.extend("demo.control.Input", {
onfocusin: function() {
if (typeof Input.prototype.onfocusin == "function") {
Input.prototype.onfocusin.apply(this, arguments);
}
this.getDomRef("inner").select();
},
// ...
});
Note: sap.m.InputBase provides the API selectText(iStart, iEnd). However, that API doesn't support Input controls with type Number according to the HTML spec as well as API reference:
selectText
Only supported for input control's type of Text, Url, Tel and Password.
Since our goal is to select all text within the input field (not a range) regardless of the type, domElement.select()api can be used instead.

If you really have a form with -- gasp! -- 100 fields, I would then extend the standard sap.m.Input and attach the onfocus browser event in that extended control using sap.ui.core.Control's attachBrowserEvent method.

Related

Vaadin 23: addPropertyChangeListener for JavaScript changes

Intended: In a Vaadin 23 application I'd like to get informed when the value of an HTML attribute is changed.
What I tried: I created this input formula:
// Text input field
Input input = new Input();
input.setId("myInputField");
Element textInput = input.getElement();
// Change listener for property "value"
// Works well for manual input
// BUT doesn't work for JavaScript changes
textInput.addPropertyChangeListener("value", "change",
e -> {System.out.println(e.getValue());}
);
// Button that changes the value of attribute "value"
Button button = new Button("Change value");
button.addClickListener(e -> {UI.getCurrent().getPage().executeJs(
"document.getElementById('myInputField').setAttribute('value','hello');"
);});
this.add(input, button);
What does work: When the user types "something" into the input field then the server prints "something" to the console. This is intended and observed. OK.
What does NOT work: When the user pushes the button then the content of the input field is "hello" (OK). But the PropertyChangeListener does not fire an event, so the server does not print anything to the console.
Question: Is there a way to get the PropertyChangeListener fire an event, even if the attribute's value has been changed by JavaScript?
I see two problems here.
First, the server-side property change listener in Vaadin Flow needs to be triggered by a client-side event. The <input> element fires events when the the user directly changes the value in the field, but not when the value is changed programmatically. If you change the value from code, then you need to also manually fire an event to trigger the update.
Second, as pointed out in the comments, you should change the property rather than the attribute. In most cases, the attribute and the property with the same name are kept in sync, but the value of an input is an exception. Here, the attribute is the initial value and the property is the actual value. The stay the same if you only change the attribute, but diverge after the user edits through the UI or if the property is changed.

How to process user input as it writes in Dart

I'm trying to build a web app with Dart and HTML. I have a HTML input field
which receives type text. I would like to process the text the user inputs as it inputs each letter, not only when it hits ENTER or something like that.
I currently came up with this solution in Dart but it only prints the user input when it hits ENTER which is not what I'm looking for as said.
import 'dart:html';
void main() {
TextInputElement text = querySelector("#input-text");
text.autocomplete = "asas";
text.onChange.listen((data) {
parent.appendHtml('<p>${text.value}</p>');
});
}
I looked up some topics like Futures, Streams and Broadcast streams but it doesn't look like what I need still.
If someone could help it would be great!
Onchange will only work that way because it listens to submit events.
What you can do instead is listen to input field .onKeyUp event.
Everytime inside the input field if you type and the moment you release your key this event will be registered and listeners will be invoked
https://dartpad.dartlang.org/02e27326c073de360f14bb9a9726f1c9
You can see this example on dart the moment you type something it get's printed.
Here onKeyDown on onKeyPress can also be used but the thing is if the user keeps the key pressed it will register all of those events creating n number events

how to track the social media icons using DTM (Dynamic tag manager)

I have the below code in my web site.
I want to track each anchor tag using DTM. I know how to track single element. Since here we have a bunch of different elements, can anyone help how to track them using DTM? I don't want to create separate rule for each element. In a single rule how can we track these elements.
Here is an example of what you can do.
For Element Tag or Selector put "a.at-share-btn" (no quotes). This will target all the relevant links first. We can look for this too in the next step, but "pre-qualifying" it with this will improve performance so that the rule is not evaluated against every single a click.
Then, under Rule Conditions, add a Criteria of type Data > Custom.
In the Custom box, add the following:
var shareType = this.getAttribute('class').match(/\bat-svc-([a-z_-]+)/i);
if (shareType&&shareType[1]) {
_satellite.setVar('shareType',shareType[1]);
return true;
}
return false;
This code looks for the class (e.g. "at-svc-facebook") and puts the last part of it (e.g. "facebook") into a data element named shareType.
Then, you can reference it using %shareType% in any of the DTM fields. Note: because this data element is made on-the-fly, it will not show up in the auto-complete when you type it out in a field.
Alternatively, in custom code boxes (e.g. if you are needing to reference it in a javascript/3rd party tag box), you can use _satellite.getVar('shareType')

Select Multiple, get selected values and non-selected values

I have a select multiple on my page. The user can add elements to the list and remove them selecting one or more.
When I get the select's value through params.selectName, I receive only the selected ones. I
understand that this is the default behavior, but I need all of them, not only selected elements.
I don't really want to select all elements each time I send data to server. Does anyone have a better solution? Thanks.
The approach taken by the <g:checkBox> tag is to create a hidden field with the same name as the checkbox but with an underscore prepended. You could use a similar trick here, i.e. whenever you add a new <option> to the <select> you also add a hidden field named (say) selectName_options with the same value. Then in the controller you can take the difference between params.list('selectName') and params.list('selectName_options') to get the un-selected options from the list.
This is a bit of a complex solution to what should be a simple problem, but in my current project we just had the same problem and solved it as #cdeszaq describes.
Assuming an object of class Foo with a collection (bars) of Bar items, where each Bar has a String name and outputs it as its toString() representation, we do this in the FooController:
def removedItems = fooInstance.bars.findAll {
!params.bars.collect { it.key }.contains(it.name)
}
if(removedItems){
removedItems.each {
fooInstance.removeFromBars(it)
}
}

jQuery Tabs - Load contents only when clicked

I am relatively new to jQuery and web development.
I am using jQuery UI Tabs to create tabs.
But I want the contents to be loaded only when I select a particular tab.
OK, I assume when the user clicks a tab, you intend to fetch content dynamically, via AJAX. This really involves two things, setting an onclick even for your tab and fetching the data via ajax.
Setting an onclick event
Give your tab an class, for example my_tab. Let's say that when the user clicks the tab you want the handle_tab_click() function to fire. Here's an example of binding the onclick event to your my_tab tab:
$(".my_tab").bind("click", handle_tab_click);
Your handle_tab_click() function will be given an event argument which will be able to provide you with information on the element that fired the event (in this case, the element with class name my_tab).
function (event) {
if ($(event.target).hasClass("my_tab")) { /* handle tab click */ }
if ($(event.target).hasClass("my_tab_2")) { /* a different tab click */ }
if ($(event.target).hasClass("my_tab_3")) { /* ... */ }
}
See the JQuery event documentation for more details here.
Fetching the data via ajax
Fetching data will require you to invoke a remote script while supplying information about which tab was clicked (in order to fetch the appropriate information). In the following snippet, we're invoking the remote script myscript.php, supplying the HTTP GET argument tab_clicked=my_tab and calling the function tab_fetch_cb when the script returns. The final parameter is the type of data being returned (it's up to you to choose).
$.get("myscript.php", {tab_clicked, "my_tab"}, tab_fetch_cb, "text/json/xml")
It's up to you to design myscript.php to handle the tab_clicked parameter, fetch the appropriate data and return it (i.e. write it back out to the client).
Here's an example for tab_fetch_cb:
function tab_fetch_cb(data, status) {
// populate your newly opened tab with information
// returned from myscript.php here
}
You can read more about the JQuery get function here, and JQuery ajax functions here
I'm sorry I can't be more specific in my examples, but a lot of the processing is really dependant on your task. As it looks as it has already been pointed out, you may look to some JQuery plugins for a canned solution to your problem. That being said, it never hurts to learn how to do this stuff manually w/ JQuery.
Good luck.
UI/Tabs support loading tab content on demand via Ajax, check this example.
Loading content via Ajax adds the complexity of dealing with bookmarking / browser back buttons. Depending on your situation, you should consider loading new content with a full page request. Handling the bookmarking/browser back involves using adding anchor info in the URL.
Also, check out LavaLamp for tab selection. It's pretty nifty looking.
By default a tab widget will swap between tabbed sections onClick, but the events can be changed to onHover through an option. Tab content can be loaded via Ajax by setting an href on a tab.
source: http://docs.jquery.com/UI/Tabs
If you're using Rails, you can try this gem bettertabs
It supports ajax tabs.

Resources