How can I use ValidationSupport between two textfields? - javafx-8

I would like to use the ValidationSupport to check the content of textfield2 against the content of textfield1. Here is what I tried to do :
validationSupport = new ValidationSupport();
validationSupport.registerValidator(textfield2, false, (Control c, String newValue)
-> ValidationResult
.fromMessageIf(textfield2,
"Should contain texfield",
Severity.WARNING,
!newValue.contains(textfield1.getText())));
validationSupport.initInitialDecoration();
Filling textfield1 first, then texfield2 is working as I expect : the warning decoration is displayed on textfield2 until the textfield1 content is not included in the texfield2 content.
But starting from same content in textfield 1 & 2, and trying to change texfield1 again (hence at this point, textfield1 content differ from textfield2 content), I was expecting the warning decoration to be displayed immediately on texfield2, which is not the case !
Indeed in order to have the validationSupport checked again, I need to update the textfield2 again. Only after the texfield2 content has been updated, then the ValidatorSupport is checked again, and the decoration is updated accordingly !
The only way I found to always get the decoration up to date is to remove the previous registerValidator and to add a listener on textfield1 textProperty to register a new validator for texfield2 each time textfield1 content is changed :
textfield.textProperty().addListener((observable, oldValue, newValue)
-> validationSupport.registerValidator(textfield2, false, (Control c, String str)
-> ValidationResult
.fromMessageIf(textfield2,
"Should contain texfield1",
Severity.WARNING,
!str.contains(textfield.getText()))));
This is working (meaning when I change textfield1, decoration on textfield 2 is updated immediately) but I feel it's not the right solution, but can't find another / better one. Is it the right way to do ? If not, what is the right way ? Any recommendation ? Thanks.

Related

React-Bootstap-Typeahead: Manually set custom display value in onChange() upon menu selection

In the onChange of React-Bootstrap-Typeahead, I need to manually set a custom display value. My first thought was to use a ref and do something similar to the .clear() in this example.
But although .clear() works, inputNode.value = 'abc' does not work, and I'm left with the old selected value from the menu.
onChange={option => {
typeaheadRef.current.blur(); // This works
typeaheadRef.current.inputNode.value = 'abc'; // This does not work (old value is retained)
}}
I also tried directly accessing the DOM input element, whose ID I know, and doing
var inputElement = document.querySelector('input[id=myTypeahead]');
inputElement.value = 'abc';
But that didn't work either. For a brief second, right after my changed value = , I do see the new display label, but then it's quickly lost. I think the component saves or retains the menu-selected value.
Note: I cannot use selected, I use defaultSelected. I have some Formik-related behavior that I've introduced, and it didn't work with selected, so I'm stuck with defaultSelected.
The only workaround I found is to re-render the Typeahead component (hide and re-show, from a blank state) with a new defaultSelected="abc" which is a one-time Mount-time value specification for the control.
I couldn't get selected=.. to work, I have a wrapper around the component which makes it fit into Formik with custom onChange and onInputChange and selected wasn't working with that.
So the simple workaround that works is, if the visibility of the Typeahead depends on some condition (otherwise it won't be rendered), use that to momentarily hide and re-show the component (a brand new repaint) with a new defaultSelected, e.g.
/* Conditions controlling the visibility of the Typeahead */
!isEmptyObject(values) &&
(values.approverId === null || (values.approverId !== null && detailedApproverUserInfo)
)
&&
<AsyncTypehead defaultSelected={{...whatever is needed to build the string, or the literal string itself...}}
..
// Given the above visibility condition, we'll hide/re-show the component
// The below will first hide the control in React's renders
setFieldValue("approver", someId);
setDetailedUserInfo(null);
// The below will re-show the control in React's renders, after a small delay (a fetch)
setDetailedUserInfo(fetchDetailedUserInfo());

Delete command is not working for NSTextField

I have a textfield to which I need to listen to tab key, so that when ever the user press tab from that text field I can move the focus to next text field. I have implemented the below code to perform that operation.
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
if (commandSelector == #selector(insertTab)) {
if control == firstTextField {
makeNextTextFieldAsFirstResponder()
}
}
return true
}
My problem is that as I have implemented this code, delete key is not doing what it suppose to do(removing last character from the text field's text). Am I missing something here?
I am new to Mac development so excuse me if this question has been asked already somewhere.
I found the solution to my own problem. It turns out to be a simple mistake. I am not sure about how exactly this method works and how the return value affect the nature of the text field as I am new to Mac development, but it seems that the default return value should be false. Any insights to this behaviour are welcome.

Changing the text of a UITextField does not trigger the rx.text binder

I have a UITextField called commentField and I create an Observable<Bool> like this:
let isCommentFieldValid = self.commentField.rx.text.orEmpty.map({ !$0.isEmpty })
This observable determines whether a button is enabled or not.
The problem is that when I change the text property of commentField liked this:
self.commentField.text = ""
The isCommentFieldValid doesn't trigger again and, thus, the button's state doesn't change. Any edition using the UI works: if I remove all text from the field through the keyboard, the isCommentFieldValid updates, but via code it doesn't.
Is there a reason this doesn't work?
If you look at the underlying implementation for rx.text you'll see that it relies on the following UIControlEvents: .allEditingEvents and .valueChanged. Explicitly setting the text property on UITextField does not send actions for these events, so your observable is not updated. You could try sending an action explicitly:
self.commentField.text = ""
self.commentField.sendActions(for: .valueChanged)

Use a text field to set the title of an MKAnnotation in Swift

having registered a long press at a point on the map, I'd like a text field to pop up, so I can set the input as the title of a pin dropped at that point. How would I go about doing this?
Heres my code which currently registers a longpress and drops a pin, that all works fine! I'm not sure how to bring up a text field and get the users input though
func DropPin(gestureRecognizer:UIGestureRecognizer) {
if gestureRecognizer.state == .Began {
var point:CGPoint = gestureRecognizer.locationInView(self.Map)
var pinLoc: CLLocationCoordinate2D = self.Map.convertPoint(point, toCoordinateFromView: self.Map)
let x = CustomAnnotation(coordinate: pinLoc, title: "Pin", subtitle: "Pin", imageName: "TouchPin")
self.Map.addAnnotation(x)
}
}
There are several ways to do so, but you can choose one of the two for example.
In your view, you add a text field where the user set the title before you drop the pin. But that might not be intuitive or look bad (if you need to have a full screen map for example).
So, what I would suggest is to fire an UIAlertController with a text field inside. Here is an example of how you could do it.
Either you :
Create the annotation
Add it to the map
An alert appear
The user enter a name (keep it somewhere)
You retrieve the last annotation you've added
You set it's title with the name entered previously
Or :
You detect your long press
An alert appear
The user enter a name (keep it somewhere)
Create your annotation with the name entered previously
Add it to the map
Those are just 2-3 examples. You might think of something else :)

UITextInput setMarkedText:selectedRange not working? (Can't be!)

I want to set the marked text programmatically and since iOS5 UITextView and UITextField conform to UITextInput this should be possible but for some reason I always get the markedText to be nil. :(
What am I missing here?
This is what I've tried without success:
(While the textview is firstResponder)
1.- When the text view contains no text:
text: "", selectedRange : {0,0}, markedText: nil.
[_textView setMarkedText:#"月" selectedRange:NSMakeRange(0, 1)];
Result:
text : "", selectedRange: {0,0}, markedText: nil. (Nothing changed)
2.- When the text view contains text + some marked text:
text : "AAA", selectedRange = {0,3}, marked text at the end : "太陽"
then I do:
[_textView setMarkedText:#"地" selectedRange:NSMakeRange(0,3)];
Result :
text :"AAA", selectedRange: {0,3}, markedText: nil; (the marked text became nil)
In both cases is like setMarkedText:selectedRange: would be setting the current marked text (if some) to nil.
Any help would be highly appreciated :)
UPDATE
Since the concept of marked text seems to be unclear, here is an explanation:
In multi stage input languages (e.g. Japanese) you can input regular text (like english) or input marked text (like japanese).
Here I wrote regular text : regular text then I wrote marked text つ
and then I wrote marked text き so it was appended becoming つき.
Marked text (text in the blue box) represents a transitional or intermediate input stage because it can become into other characters/words called candidates. Candidates are shown in the big box.
This screenshot was taken when using a bluetooth keyboard in the iPad but you will get similar results when using the software keyboard when writing japanese for example.
Before writing つ the textview was:
textView.text : "regular text"
textView.selectedRange : {12,0}
textView.markedText:nil
Then I wrote つ and the text view became:
textView.text : "regular textつ"
textView.selectedRange : {13,0}
textView.markedText: "つ"
Then I wrote き and the text view became:
textView.text : "regular textつき"
textView.selectedRange : {14,0}
textView.markedText: "つき"
Which is the current state of the text view.
I want to be able to set the marked text programatically :)
Is this possible? -- According to UITextInput docs it is.
I have a conceptual problem with your code here. I may just be overlooking some small thing, but I think you just have a simple error in your programming.
1) When the text view contains no text: text: "", selectedRange : {0,0}, markedText: nil:
[_textView setMarkedText:#"月" selectedRange:NSMakeRange(0, 1)];
Result: text: "", selectedRange: {0,0}, markedText: nil.
(Nothing changed)
2) When the text view contains text + some marked text: text: "AAA", selectedRange: {0,3}, markedText at the end: "太陽" then I do:
[_textView setMarkedText:#"地" selectedRangeNSMakeRange(0,3)];
Result: text: "AAA", selectedRange: {0,3}, markedText: nil;
(the marked text became nil)
I just fixed your problem in the code that I ran in Xcode. It ran flawlessly and changed the marked text when I clicked three different buttons. When there was no marked text, the text was appended and marked.
text is the name of a UITextView:
-(IBAction)first
{
[text setMarkedText:#"test" selectedRange:NSMakeRange(0, 4)];
}
-(IBAction)second
{
[text setMarkedText:#"woo" selectedRange:NSMakeRange(0,4)];
}
Here I clicked "First"
Here I clicked "Second"
I hope this helps you and is deserving of the bounty.
Did you add the UITextField to the view before setting it's contents (and marking the text)?