I'm adding keyboard shortcuts to a Flutter web application.
I have a form within a custom FocusableActionDetector where the shortcut has form like this:
SingleActivator(LogicalKeyboardKey.digit2)
and action is like:
CustomActivateIntent: CallbackAction<CustomActivateIntent>(
onInvoke: (intent) { provider.value = "2"; },)
In the same form I have a couple of numeric TextFormFields. To permit writing the character "2" I have to put these text fields inside some new FocusableActionDetector, otherwise the previous detector catches the command and the text field loses the "2" character, and this is already quite weird... Moreover, after writing in any of the text fields the form focus detector doesn't work anymore.
I think this could be related to the focus system, which is yet not that clear to me.
Can anyone help find a clean solution?
I found a workaround: the FocusableActionDetector is now preceded by an if statement. The code looks like the following:
// I extract the form to a widget to make it clearer
var searchWidget = SearchWidget();
child: textEditingInProgress
? searchWidget
: FocusableActionDetector(
child: searchWidget,
...,
),
The textEditingInProgress bool is a field in a provider and is controlled by the FocusNodes belonging to the TextControllers.
Still this is not a perfect solution, in particular I'd like to understand why the previous approach was not working.
Related
Hai i am struggling with keyboard problem in android, when i want to type any thing in text input it show some suggestions in keyboard, I don't want those suggestions, Can any one help me that how to avoid those suggestions.
Any help much appreciated, the above image from nexus 6.
Here is my TextInput code
<TextInput
style={styles.TextInput}
value={this.state.currentWord}
onChangeText={(text) => this.setState({currentWord:text.trim()})}
placeholder="Type Your word here"
autoCapitalize='characters'
autoCorrect={this.state.autoCorrect}
autoFocus={this.state.autoFocus}/>
In state i declare autoCorrect to be false
When using autoComplete="false", React native sets the underlying native android input type to TYPE_TEXT_FLAG_NO_SUGGESTIONS and clears out TYPE_TEXT_FLAG_AUTO_CORRECT, effectively telling the system not to offer any suggestions (see source code). This is the recommended way of disabling text suggestions per the Android reference guides.
The problem is it appears that some (or many?) HTC devices do not honor this setting. From my research, it appears some Samsung devices might not support this either. It is reasonable to assume that other manufactures will not honor this setting - which flat out just sucks. This is one of the big problems with Android - somehow they didn't learn from Microsoft - that sleazy manufacturers will destroy the reliability of your products and it takes years (a decade, roughly) to even begin to undo the damage </rant>. (note: I'm an Android fan).
According to Daniels answer it appears someone had success setting the text type to use TYPE_TEXT_VARIATION_FILTER - which tells the device that your input is being used to filter a list of items. Lets try to modify the existing text input and see if it works - then you can build our own if you want:
You need to find the file ReactTextInputManager.java. From the React Native folder, it will be located at this path:
[react-native]/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java
Around line 378 you will find a method called setAutoCorrect - update it to the following:
public void setAutoCorrect(ReactEditText view, #Nullable Boolean autoCorrect) {
// clear auto correct flags, set SUGGESTIONS or NO_SUGGESTIONS depending on value
updateStagedInputTypeFlag(
view,
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_FILTER,
autoCorrect != null ?
(autoCorrect.booleanValue() ?
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT : (InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_FILTER))
: 0);
}
Build your app and test. If it doesn't work, try removing both instances of InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | (including the pipe) from the above code and try again. If that doesn't work, I think you're out of luck.
If it does work, then you can either a) instruct everyone on your team how to modify the react native component before building (hacky and unreliable), or b) build your own text input component. You should be able to copy and paste the existing TextInput code and shouldn't have to write much native code at all - mostly just renaming things. Good luck.
Update: going further down the rabbit hole, you can also try the setting TYPE_TEXT_VARIATION_VISIBLE_PASSWORD. So here is the kitchen sink - I'm assuming you can read the code well enough to play around with different combinations of input types:
public void setAutoCorrect(ReactEditText view, #Nullable Boolean autoCorrect) {
// clear auto correct flags, set SUGGESTIONS or NO_SUGGESTIONS depending on value
updateStagedInputTypeFlag(
view,
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD,
autoCorrect != null ?
(autoCorrect.booleanValue() ?
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT : (InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD))
: 0);
}
It helps to understand that the method signature for updateStagedInputTypeFlag is the following:
updateStagedInputTypeFlag([view], [flagsToUnset], [flagsToSet]);
Update 2: There are lot's of "input type" flags you can use, see a full list here. Feel free to try others - you might stumble upon one that works. You should be able to modify the code from my first update above.
if anyone has this problem, setting autoCorrect=false and keyboardType="visible-password" hides the suggestions in android
You can set the TextInput to Set autoCorrect to false.
You would have to write your own Android TextView wrapper, that sets the correct input type. See this stack overflow post for more information on the android part.
My solution was using keyboardType={'visible-password'} when the password is visible
<TextInput
onChangeText={onChangeText}
label={label}
autoCapitalize='none'
value={password}
secureTextEntry={isPasswordVisibile}
keyboardType={this.state.isPasswordVisibile ? undefined : 'visible-password'}
/>
Our fix/hack was to simply change the input`s type from text to email and back to text.
I am creating a script that involved searching for a record and then updating the record. On the search screen, the user has the option of viewing advanced search options. To toggle showing or hiding advanced search is controlled by one button.
<a title="Searches" href="javascript:expandFilters()"><img border="0" align="absmiddle" alt="Advanced" src="****MASKED URL****"></a>
The only difference between the properties of the search button when it is showing or hiding the advanced search is the img src:
When advanced search is hidden the IMG src ends with "/Styles/_Images/advanced_button.jpg", when advanced search is visible, the IMG src ends with "/Styles/_Images/basic_button.png"
When I open the page, sometimes the Advanced search options are showing, sometimes they aren't. The value that I want to search on appears in the Advanced section, so for my script to work I have added an IF statement.
<input type="text" value="" maxlength="30" size="30" name="guiSystemID">
The IF statement looks for the fields that I need to enter data into, and if the field does not exist then that would indicate that the Advanced options are not visible I need to click on the button to expand the search option.
I created the following IF statement.
if (!driver.findElement(By.name("guiSystemID")).isDisplayed()) {
driver.findElement(By.cssSelector("img[alt='Advanced']")).click();
}
When I run the script and the Advanced search is expanded then the script runs successfully. However, when I run the script and the Advanced search is not expanded, the script fails, advising me that it could not find the object "guiSystemID". This is frustrating because if it can't find it then I want the script to continue, entering into the True path of the IF statement.
Has anyone got any suggestions about how else I could assess if the field is appearing without having the script fail because it can't find the field.
Thanks in advance
Simon
I might be late in answering this, but it might help someone else looking for the same.
I recently faced a similar problem while working with isDisplayed(). My code was something like this
if(driver.findElement(By.xpath(noRecordId)).isDisplayed() )
{
/**Do this*/
}
else
{
/**Do this*/
}
This code works pretty well when the element that isDisplayed is trying to find is present. But when the element is absent, it continues looking for that and hence throws an exception "NosuchElementFound". So there was no way that I could test the else part.
I figured out a way to work with this(Surround the {if, else} with try and catch block, say something like this.
public void deleteSubVar() throws Exception
{
try
{
if(driver.findElement(By.xpath(noRecordId)).isDisplayed() )
{
/**when the element is found do this*/
}
}
catch(Exception e)
{
/**include the else part here*/
}
}
Hope this helps :)
I've had mixed results with .isDisplayed() in the past. Since there are various methods to hide an element on the DOM, I think it boils down to a flexibility issue with isDisplayed(). I tend to come up with my own solutions to this. I'll share a couple things I do, then make a recommendation for your scenario.
Unless I have something very specific, I tend to use a wrapper method that performs a number of checks for visibility. Here's the concept, I'll leave the actual implementation approach to you. For general examples here, just assume "locator" is your chosen method of location (CSS, XPath, Name, ID, etc).
The first, and easiest check to make is to see if the element is even present on the DOM. If it's not present, it certainly isn't visible.
boolean isPresent = driver.findElements(locator).size() > 0;
Then, if that returns true, I'll check the dimensions of the element:
Dimension d = driver.findElement(locator).getSize();
boolean isVisible = (d.getHeight() > 0 && d.getWidth() > 0);
Now, dimensions, at times, can return a false positive if the element does in fact have height and width greater than zero, but, for example, another element covers the target element, making it appear hidden on the page (at least, I've encountered this a few times in the past). So, as a final check (if the dimension check returns true), I look at the style attribute of the element (if one has been defined) and set the value of a boolean accordingly:
String elementStyle = driver.findElement(locator).getAttribute("style");
boolean isVisible = !(elementStyle.equals("display: none;") || elementStyle.equals("visibility: hidden;"));
These work for a majority of element visibility scenarios I encounter, but there are times where your front end dev does something different that needs to be handled on it's own.
An easy scenario is when there's a CSS class that defines element visibility. It could be named anything, so let's assume "hidden" to be what we need to look for. In this case, a simple check of the 'class' attribute should yield suitable results (if any of the above approaches fail to do so):
boolean isHidden = driver.findElement(locator).getAttribute("class").contains("hidden");
Now, for your particular situation, based on the information you've given above, I'd recommend setting a boolean value based on evaluation of the "src" attribute. This would be a similar approach to the CSS class check just above, but used in a slightly different context, since we know exactly what attribute changes between the two states. Note that this would only work in this fashion if there are two states of the element (Advanced and Basic, as you've noted). If there are more states, I'd look into setting an enum value or something of the like. So, assuming the element represents either Advanced or Basic:
boolean isAdvanced = driver.findElement(locator).getAttribute("src").contains("advanced_button.jpg");
From any of these approaches, once you have your boolean value, you can begin your if/then logic accordingly.
My apologies for being long winded with this, but hopefully it helps get you on the right path.
Use of Try Catch defies the very purpose of isdisplayed() used as If condition, one can write below code without using "if"
try{
driver.findElement(By.xpath(noRecordId)).isDisplayed();
//Put then statements here
}
Catch(Exception e)
{//put else statement here.}
I got my autocomplete stuff working well enough to see that it's returning some data when I type in a field--but the data shown in the dropdown below the textbox is just a vertical column of asterisks or list item bullets. (I can't really tell what they are.)
When I query the web service directly in the browser, it returns a Json array as expected which looks like this where, for example ?term=chi (I've added some line breaks for readability)
[
{"Name":"Chihuahua"},
{"Name":"Chinese Crested"},
{"Name":"Chinese Shar-Pei"},
{"Name":"Japanese Chin"},
{"Name":"Schipperke"}
]
My JavaScript looks like this:
$(function() {
$("#Breed").autocomplete({
source: "#Url.Action("BreedList", "Patient")"
});
});
like I say, my textbox in question (#Breed) does respond sort of like an autocomplete box, but the dropdown data is weird. Any ideas?
Although I did have a CSS bundling problem (somehow I had omitted the jquery ui css from my bundle), a bigger issue was that the Json returned by my service needed a lower case "value" property for each item. I was using the column name as cased on my Linq query. The tip that pointed me in the right direction on this came from the answer here: jQueryUI autoComplete returns back empty list
I need to simulate a tab keypress in Selenium RC, using the Java API.
I do this after having entered some text using:
selenium.type(input, "mytext");
I've tried 3 alternatives to get the tab working:
selenium.keyPress(input, "\\9");
and:
selenium.focus(input);
selenium.keyPressNative("09");
and even:
selenium.getEval("var evt = window.document.createEvent('KeyboardEvent');evt.initKeyEvent ('keypress', true, true, window,0, 0, 0, 0,0, 9,0);window.document.getElementsByTagName('input')[2].dispatchEvent(evt);")
The best I can get is a "tab space" to be inserted after my text so I end up with this in the input field:
"mytext "
What I actually want is to tab to the next control. Any clues? Thanks!
(Note: I have to use tab and can not use focus or select to chose the element I want to go to, for various reasons, so no suggestions along these lines please!)
selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + "");
I don't use the Java API, but this post from google groups suggests it is your solution. I can't imagine that "9" is different from "09" in your question, but give it a try?
Try the official TAB char: \t or \u0009
Some functions may used Onblur. It will trigger the function when the field lose the key focus. here we can use fireEvent with "blur" or "focus" command as follows:
command: fireEvent
target: id=your_field_identification
value: blur
Reference: http://qaselenium.blogspot.com/2011/01/how-to-triger-tab-key-in-selenium.html
Improvising Ryley's answer, we can use
selenium.keyDownNative(java.awt.event.KeyEvent.VK_TAB + "");
selenium.keyUpNative(java.awt.event.KeyEvent.VK_TAB + "");
I tried this method for VK_CONTROL in IE and it worked good.
Use typeKeys():
Quoting the above link:
Unlike the simple "type" command, which forces the specified value into the page directly, this command may or may not have any visible effect, even in cases where typing keys would normally have a visible effect. For example, if you use "typeKeys" on a form element, you may or may not see the results of what you typed in the field.
In some cases, you may need to use the simple "type" command to set the value of the field and then the "typeKeys" command to send the keystroke events corresponding to what you just typed.
I've had nothing but grief using Symbian's browser control on S60 3rd edition FP1. We currently display pages and many things are working smoothly. However, when inputting text into an HTML text field, the user will get a KERN-EXEC 3 if they move left at the beginning of the text input area (which should "wrap" it to the end) or if they move right at the end of the text input area (which should "wrap" it to the beginning).
I can't seem to trap the input in OfferKeyEventL. I get the key event, I return EKeyWasConsumed and the cursor still moves.
TKeyResponse CMyAppContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
if (iBrCtlInterface) // My browser control
{
TBrCtlDefs::TBrCtlElementType type = iBrCtlInterface->FocusedElementType();
if (type == TBrCtlDefs::EElementActivatedInputBox || type == TBrCtlDefs::EElementInputBox)
{
if (aKeyEvent.iScanCode == EStdKeyLeftArrow || aKeyEvent.iScanCode == EStdKeyRightArrow)
{
return EKeyWasConsumed;
}
}
}
}
I would be okay with completely disabling arrow key navigation but can't seem to do this.
Any ideas? Am I going about this the wrong way? Has anyone here even worked with the Browser Control library (browserengine.lib) on S60 3.1?
Update: Interestingly, if I switch to use Cursor Navigation, it works fine. For now, this is a workaround. I'm still curious to know if there are ways to resolve this.
You would get quicker answer probably in http://discussion.forum.nokia.com/forum/.
Interestingly, if I switch to use Cursor Navigation, it works fine. For now, this is a workaround. I'm still curious to know if there are ways to resolve this. For now, I'm calling this the answer.