How to make an input field not editable through text - react-bootstrap

I'm using the react FormControl like so:
<FormControl
type={"datetime-local"}
value={field.value}
onChange={field.onChange}
isInvalid={props.errors[name]}
/>
{form.errors[name] && (
<div className="custom-invalid-feedback">{form.errors[name]}</div>
)}
</FormGroup>
But it's editable by text input. I want it so that the date can only be selected from the dropdown and not by entering text. Is there a way to do this with FormControl, or is there another form that works with Formik that can be used?

There is officially no such attribute that would help you with your use case: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
Nore has the Form.Control component anything helpful: https://react-bootstrap.netlify.app/forms/form-control/#form-control-props
So what you need to do is to take control of rendering the input and the widget:
Define a state for the datetime value
Place a toggle which shows/hides some date/datetime widget
When widget sets a value, set the state as well
Reflect this state on the toggle label/title
I have set up a sandbox with an example: https://codesandbox.io/s/dry-shadow-nwi877.
I'm using "react-datetime" library as an example, but it's up to you what widget library you want to use. For the toogle, Dropdown component is used.

Related

Vuetify 2.1 V-Select reset or clear selection after change

i have to fix a vuetify custom component that extends from Vue Class and includes a V-Select component. The dropdown is working fine but since its just a trigger pad to pop open modals the requirement is to reset/clear the dropdown selection after onchange event. basically i think i need to trigger the clearableCallback but i am not sure how to do it. First of all i have the problem that when i bind a method from the parent component the scope is always the parent so this refers to the extend parent component class. so i wonder how to get into the scope of the v-select component. i can not see apart from the clearable prop there is no native functionality for what i am trying to do. any hints? thanks
I am not sure I fully understand your question, but if I do, you may try using #change event on the v-select and use a method in which you open modals and reset the value of the v-select model to any desired one.
<v-select
v-model="select"
#change="someMethod"
>
</v-select>
...
methods: {
someMethod(){
this.openModal(this.select);
this.select = 0;
}
Setting the value to 0 only worked for the first change for me. Every subsequent change did not reset the displayed value. The only thing that worked consistently for me was using $nextTick. e.g.
onInput() {
this.$nextTick(() => {
this.select = 0;
});
}
It seems to be something to do with vuetify's internal implementation, and the lazyValue getting out of sync with the value prop.
As I far understand your question. The solution could be using the ref key in the v-select element and call the reset() function.
For example
In HTML
<v-select #change="handleOnSelectChange"
ref="selectedEl"/>
In vue methods
methods:{ handleOnSelectChange:function(){this.$refs["selectedEl"].reset();}}

Blueprintjs: Hotkey input

I'm currently trying to do UI that allow me to enter hotkeys for different table rows...
So main idea is to make something like editableCell, where i will input hotkeys.
I already found getKeyComboString method from docs:
http://blueprintjs.com/docs/#core/components/hotkeys.key-combos
But my problem is: how i make something like EditableCell double click ?
i looked in source and found, that editableCell uses Draggable component for this (as i can say), but i can't import it.
so i don't know how should i check if my input looses focus...
Any ideas how to make hotkey input ?
I'v done this using onBlur event and isEditing state.
<div
className={className}
onDoubleClick={this.handleCellDoubleClick}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
tabIndex={0}
>
{this.state.keyCombo}
</div>
onDoubleClick set state to isEditing: true
onBlur set it to false
onKeyDown works only when isEditing: true

Passing initial value to custom input component

I am creating a custom input to handle a toggle switch.
Form component
<Field
label='Link to individuals'
name='employeeLink'
value={true}
component={Switch}
/>
If I log this.props.input.value of the Switch component I get value: "". How do I pass the initial value as seen in the form component to the Switch? Updating the value works as expected.
Or do I need to call componentDidMount as below? If yes, will it not always be dirty?
componentDidMount() {
this.props.input.onChange(this.props.input.value);
}
Totally forgot that redux-form provides a way to pass initial values
See:
http://redux-form.com/6.4.3/examples/initializeFromState/
http://redux-form.com/6.4.3/docs/api/ReduxForm.md/#-initialvalues-object-string-string-optional-

Knockout - Disabling the default behavior of updating model when using binding value with form element

Knockout has the default behavior of updating the associated model if you change your focus (e.g. by clicking outside the input control) after editing the value inside an input control, populated by a binding of type Value.
Here is the link to the official documentation page explanation, section Parameters:
http://knockoutjs.com/documentation/value-binding.html
Do you know a way to disable this default behavior ?
The reason behind this : Im using Models that can tell if their last update requires persistent backup by comparing the previous value to the new one.
I would like to listen to the key up event on my form inputs but if I do that, knockout triggers twice event (the default one + the key up) to update the Model and the second one is basically telling my Model to replace the value by the same value because it is already updated, which it translates to "there is no need to do persistent backup since the value didnt change".
I would gladly appreciate any help or suggestion, since Im stuck and can't find a way around :)
EDIT
Couldnt reproduce the error with bare backbone code. It seems as "super cool" said that valueUpdate should override the default Blur event that triggers when you use form controls with binding Value.
It may be a bug introduced by the library Knockback that I use to create the ViewModel.
Despite all this, just replacing the binding Value by the binding textInput did the trick. Thank you all.
Don't listen to the event, subscribe to updates, which won't fire unless the value is changed. Using the textInput binding will register every change to the value, even those done using menu items like cut and paste, when they happen.
Equivalently, you can use the value binding along with valueUpdate: 'input'
vm = {
myvar: ko.observable(),
updates: ko.observableArray()
};
vm.myvar.subscribe(function(newValue) {
vm.updates.push(newValue);
});
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="textInput: myvar" />
<div data-bind="foreach: updates">
<div data-bind="text: $data"></div>
</div>

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);

Resources