AutocompleteInput with ReferenceInput not clearing underlying state on erase - admin-on-rest

I'm trying to set a ReferenceInput with an Autocomplete input and I'm getting a bit of a weird behaviour that I'm not sure if it's intended or not. If I confirm the autocomplete option on the field, and then erase the field for any reason, the id value is still associated with the field, even bypassing a validate={required}.
<ReferenceInput allowEmpty source="postId" label="Post" reference="posts">
<AutocompleteInput optionText="name" optionValue="id" options={{maxSearchResults: 5, filter: AutoComplete.fuzzyFilter}} />
</ReferenceInput>
Any idea on how to fix it in order for the autocomplete to work properly and yet erasing it also clearing the underlying field?

Related

How can i force validation on the initial values in a formik form, when it mounts

I am in React 16+, using withFormik for the form.
Its a single field form which on initial use will have an empty string value. I want the initial value to be validated so the user knows they must fill a value.
So blank string "" initial value, i want the error to say "please enter a value" without the user touching or anything. onload.
formik docs claim it can do this thru the built in tools, but the library/docs dont add up.
validateOnMount:
https://formik.org/docs/api/withFormik#validateonmount-boolean
this value does nothing when set to true in my form. There are lots of logged issues of others having the same problems. It seems formik depreciated an old property that used to do this well. i cant find anything to do this without building some type of hack.
how can i have formik run the validation as ssoon as the from mounts.
in case your answer is to disable the "enableReinitialize" property, ive tried this in conjunction with validateOnMount: true and still get nothing.

MUIInputLabel does not grow when TextField is empty

The TextFields in the Material-UI docs has the label which grows and shrinks depending on whether there's a value in the field.
Rather than a user input, I am trying to use JS to reset my TextField to "" when a button is pressed. This means if a user has keyed data into the TextField, if they press the reset button, the field is cleared while the label grows to refill the field.
What is happening is that while my data is cleared, the label remains small.
Where am I going wrong with this?
I've read that it's related to something called shrink, but I dont understand how its called.
A portion of my code, built using Material-UI and ReactJS
EntryField component
<TextField onChange={inputChangedHandler} label={props.label} value={props.value} type={props.type} required={props.required} name={props.name} id={props.id} inputRef={props.propsRef} />
Form component, which uses the EntryField component above, as well as the ReactJS
const refNumRef = useRef();
const [objRefNum, setRefNum] = useState();
(...)
function resetData(event){
setRefNum('')
}
(...)
<EntryField label="Ref Number" type="text" editData={setRefNum} value={objRefNum}
id="input_refNum" name="refNum" propsRef={propRefNumRef} />
So....after posting my question, I made more trial and errors and I somehow managed to get it to work; Im not sure why.
But the main change I made was setting a default to the useState like so
const [objRefNum, setRefNum] = useState("");
And somehow this managed to fix not just this issue with the TextField, but an issue Ive been having with a Select statement as well, where I had trouble resetting it to a default value.
I will eventually have to figure out how to declare this programmatically based on API calls where the default value will change based on the results........but this is fine for now.

How can I validate my Firefox extension's preferences?

What is a generally accepted way to validate preference values in a Firefox extension, specifically when using the prefwindow mechanism in XUL?
I am introducing some new preferences in one of my extensions that I would like to validate before the preferences window is closed. If there's an error, the user should be allowed to correct the issue, and then proceed. I see that the prefwindow element has two potentially useful functions to help in this regard:
onbeforeaccept
ondialogaccept
The former seems to have an associated bug (Bug 474527) that prevents the prefwindow from remaining open when returning false from that function. This is bad in that it doesn't give the user an opportunity to immediately correct their mistake.
The latter appears to have the problem that the preferences get saved prior to exiting, which leaves the preferences in a bad state internally.
In addition, the prefwindow mechanism supports the browser.preferences.instantApply option, in which preference values are written immediately upon updating the associated control. This makes validation extra tricky. Is there a clean way to validate custom preferences in a Firefox extension, allowing the user to correct any potential mistakes?
Normally you would want to validate the preferences when they are changed. That's something that onchange attribute (and the corresponding change event) is good for:
<preference name="preference.name" onchange="validate(this);"/>
The event is fired after the preference value changes. There are two drawbacks:
In case of instantApply the new preference value is already saved, too late to validate and decline.
For text fields the preferences are saved every time a new character is typed. This becomes ugly if you report validation failure while the user is still typing.
You can solve the first issue by intercepting the change events for the actual input fields. For example, for a text field you would do:
<input preference="preference.name"
oninput="if (!validate(this)) event.stopPropagation();"
onchange="if (!validate(this)) { event.stopPropagation(); this.focus(); }"/>
So changes that don't validate correctly don't bubble up to the <prefpane> element and don't get saved. The events to listen to are: input and change for text fields, command for buttons and checkboxes, select for the <colorpicker> element.
The second issue is tricky. You still want to validate the input when it happens, showing the message immediately would be bad UI however. I think that the best solution is to assume for each input field initially that it is still "in progress". You would only set a flag that the value is complete when you first see a blur event on the field. That's when you can show a validation message if necessary (ideally red text showing up in your preference page, not a modal prompt).
So to indicate what the final solution might look like (untested code but I used something like that in the past):
<description id="error" hidden="true">Invalid preference value</description>
<input preference="preference.name"
_errorText="error"
onblur="validate(event);"
oninput="validate(event);"
onchange="validate(event);/>
<script>
function validate(event)
{
// Perform actual validation
var field = event.target;
var valid = isValid(field);
// If this is the blur event then the element is no longer "in progress"
if (event.type == "blur")
{
field._inputDone = true;
if (!valid)
field.focus();
}
// Prevent preferences changing to invalid value
if (!valid)
event.stopPropagation();
// Show or hide error text
var errorText = document.getElementById(field.getAttribute("_errorText"));
errorText.hidden = valid || !field._inputDone;
}
</script>
If you want to validate values as soon as the field is changed so you can handle the instantApply case, you could hook into the change events for the individual fields (e.g. oninput for a textbox). Display an error message and force the focus back to the field if the value is invalid. You can either set it back to a valid value automatically or block the user from closing the dialog until it is fixed.

Setting a text field that has a JQuery mask on it

Using watir-webdriver, I am trying to set the value for a text field.
browser.text_field(:id, "phoneNumbers_value_input").set("5555551234")
When I run that command, I can see that watir found the field because the cursor is set on that field however no text is entered. I have also tried the send_keys and append commands but nothing seemed to work. No exception is thrown from these methods.
The only difference I could find between this field and the other fields on the page(which all work fine) is that it has this JQuery mask on it.
$(selector).mask("(999) 999-9999");
Any ideas on how to set the text field?
Edit:
Some more of the Javascript:
selector = '#' + id(field.id) + '_input';
if (field.format == 'phone') {
$(selector).mask("(999) 999-9999");
}
HTML of the field:
<div id="phoneNumbers_value_form_item" class="form_item validated no_focus">
<label for="phoneNumbers_value" class="form_label">phone</label>
<input type="text" value="" name="phoneNumbers[][value]" id="phoneNumbers_value_input" class="text">
<div class="tip"> </div>
<div class="tip_validating">
</div>
<div class="tip_error">
</div>
</div>
I don't see any element in the HTML you provided that would match the text input field being addressed in the ruby code at the top of your posting. e.g. there is nothing there with an ID of 'phone'
Based on the HTML in your question, I would expect the following to work
browser.text_field(:id, "phoneNumbers_value_input").set("5555551234")
Looking at the sample page you linked in the comments, when I use google chrome and the "Inspect Element" function on the input field with the ID of 'phone' I see that there are a number of event listeners associated with the field (blur, focus, input, keydown, keypress, unmask)
The 'focus' one gets my attention in particular, and seeing it there on that field makes me think that you might then need to first fire an event against the same element, such as the onfocus event, in order to activate the field, then try to set the value.
You'll notice that when you manipulate things manually, the field starts out blank, but as soon as it gets focus it displays the format for the input mask to the user, it may well be that this needs to happen first, before it see's any kind of input.
EDIT: In this case, based on feedback from the questioner, the answer turned out to be that they needed to first fire the 'unmask' event against the text field, and THEN .set the value they wanted, in order for things to work correctly when automating the testing. This doesn't exercise the field masking functionality, but then again I doubt the test mandate in this instance is to extensively test a 3rd party (JQuery) addin, and they are more concerned with the business logic etc in the back end, thus simply being able to set the value without the masking code getting in the way is what is needed.
The problem has to do with focusing on the text field. Even with a .click() somehow webdriver ends up with the cursor at the end if the input field (see issue 2377). Pressing the HOME key moves the cursor to the beginning and allows you to type in the input field, and still have the mask functionality.
In Java:
WebElement txtPhone = getDriver().findElement(By.id("phoneNumbers_value_input"));
txtPhone.sendKeys(org.openqa.selenium.Keys.HOME);
txtPhone.sendKeys(phoneNumber);

How do I identify a dynamic-id custom-type text field in WATiR?

I have this input of type "Submit" that Watir cannot see. I can identify it by ID, but it doesn't turn up in browser.text_fields, or by any other idenfication method. The ID is dynamically generated so I cannot use it for testing. Any ideas on how to make this readable? I'm willing to change the WATiR source code if necessary.
<INPUT id=t8CPm value=Submit type=submit>
I have obviously tried text_field(:value, 'Submit') and text_field(:type, 'Submit'), and I get an "Unable to locate element" error.
Did you try treating it as a button element? Inputs of type submit are generally considered to be a button because the browser generally renders them that way.
try
browser.button(:value, 'Submit').flash
and see if it works for you
I changed INPUT_TYPES to ["text", "password", "textarea", "submit"] in the TextField class of input_elements.rb and there it was.
I should also probably edit the collections to read the type too.
Edit: I am an idiot and I didn't need to do this, but I'm leaving it here in case anyone else needs to identify a real dynamic-id custom-type text field, not a fake dynamic-id custom-type text field otherwise known in my particular case as a "button".

Resources