I want to have a Slider and an Input control, both for one specific value.
The user should be able to use either the input field or the slider to input his value.
If the user changes the value on the Slider, the input field should show the Slider's value. And if the user inputs something in the input field, the Slider should move to the corresponding value.
Currently, I am creating a JSONModel with the value as a property to bind:
let model = new JSONModel({
valueName: 10
});
settings.setModel(model);
Now, when I am changing the value on the slider, the update of the input field is working fine. But if I'm entering a value in the input field, the Slider does not move to the value.
Why is that so and how do I solve my problem?
<Slider value="{/valueName}" step="10" width="200px" />
<Input value="{/valueName}" type="Number" width="50px" />
Since the given solutions only worked for integer values a follow up question for float values was created here
I was baffled by this at first. The reason appears to be that the value is saving as a string (in spite of you explicitly specifying number or clearly binding the value in the initial model to a numeric value).
I checked this by handling the liveChange event off the Input, retrieving the model value of valueName, doing a parseInt on the value and then setting the Slider to that value.
This causes the slider to update as I change the Input.
Controller:
handleChange: function(){
var slider = this.getView().byId("slider");
var val = this.getView().getModel().getProperty("/valueName");
slider.setValue(parseInt(val));
}
XML View:
<Slider id="slider" value="{/valueName}" min="0" max="100" step="10" width="200px" />
<Input textAlign="Center" value="{/valueName}" type="Number" width="50px" valueLiveUpdate="true" liveChange="handleChange"/>
The caveat was if I wanted to update the slider to, say, 70 I would need to key in the 0 first (as the slider settings as they stand convert the value to min (0) or 10 the moment I type a number - given the correct behaviour of liveUpdate). There are ways to work around this but I thought I'd get you the answer and you can figure out what to do from there.
Ultimately i think this is a bug. EDIT - this is not a bug - please refer comment by Boghyon below this Answer
The user should be able to use either the input field or the slider to input his value.
In case you were not aware, you could use the built in Tooltip input feature:
<Slider
showAdvancedTooltip="true"
showHandleTooltip="false"
inputsAsTooltips="true"
/>
Gives you this:
Slider awaits a value of type float.
The input field, however, evaluates inputs as string.
You can solve it declaratively by assigning an appropriate type to the binding info object:
Either assign sap/ui/model/type/String* to Slider's value binding type ⇒ Formats the string value from the model to a float type prior to passing the value to the Slider.
Float value manipulated from the Slider will be converted back to a string value before storing it in the model as a result of two-way binding with the String type.
Or assign sap/ui/model/type/Float* to Input's value binding type ⇒ Stores the value as number in the model. The Slider can then use the number value directly.
Here is a demo of the above approaches: https://jsbin.com/sodihub/edit?js,output
Using the type feature in binding will allow parsing, formatting, and even validating the model value before updating the control while still keeping the two-way data binding mode.
* In case of binding with ODataModel, require sap/ui/model/odata/type/Decimal|String instead!
Related
When I entered a value in the input box and submitted it, the mandatory item verification failed, and the system displayed a message indicating that a parameter was empty and instructed me to enter a value. The code for obtaining the input value is as follows:
(see the solution in column C)
can you give me some advice about it?
The possible cause is that the method for obtaining the value is incorrect. As a result, the value in the input box cannot be obtained.
Use the onchange event to assign a value to the model and obtain the value of the input box. The method is as follows:
Initialize the model.
data:{
accountValue:''
}
Bind an event to the input box.
<input #change="getAccountValue" value="{{accountValue}}"></input>
Assign a value.
getAccountValue: function(e) {
this.accountValue = e.value // Here, e.value instead of e.target.attr.value is used.
}
Refer to the official document instead of generating a JavaScript object for coding. A JavaScript object may lead to compatibility issues.
Currently, the data binding mode of the quick app is unidirectional.
The value entered in the input box does not change the value of accountValue in data.
If the value of the input box is changed by setting this.accountValue to xxx, the onchange event of the input will not be triggered.
In this.accountValue = xxx format, if the value of accountValue before and after the change is the same, the page will not be re-rendered.
From the documentation, it describes having an uncontrolled field by omitting the value and onChange attribute. The React website says to use a ref on any uncontrolled inputs, but doing this with a TextField only refs its container, a div. What is the recommended way of retrieving the value of an uncontrolled TextField in Material UI? I could use a querySelector to find the element, but that doesn't seem like a proper way.
use inputRef prop on TextField
<TextField inputRef={ref} ... />
you can access its value by this: ref.current.value
A clarification: value deals with controllability, and onChange deals with observability. They are separate from each other.
You only make inputs controlled by setting the value prop. Setting the onChange prop can be used separately to observe the input changes without acquiring control over it, thus, achieving what you are asking for.
The way to provide a ref to the rendered input is via the innerRef prop on the TextField component. Here's the a link to the API where it states that. From there you can access the value of the input as such, ref.current.value
<TextField innerRef={ref} />
can anybody explain the following code snippet (used in CSS):
[type="checkbox"]:checked
I've tried to find this on various sites, I understand the pseudo class on the end but the square brackets have really got me stumped.
Thanks for reading.
this [type="checkbox"] is an attribute selector
[attr=value]
Represents an element with an attribute name of attr and whose value is exactly "value".
:checked is:
a pseudo class selector represents any radio (<input type="radio">),
checkbox (<input type="checkbox">) or option (<option> in a <select>)
element that is checked or toggled to an on state. The user can change
this state by clicking on the element, or selecting a different value,
in which case the :checked pseudo-class no longer applies to this
element, but will to the relevant one.
Which means you have a checkbox element checked
[type="checkbox"] is an attribute selector.
This specific selector will match any element that has the attribute type and that attribute's value is checkbox. Most would identify this as a selector for and input but is not specific enough to be limited to that element type. Other elements that accept the type attribute are <button> <command>, <embed>, <object>, <script>, <source>, <style> and <menu>.
You'll often see input pre-pended to a selector like the one above, i.e. input[type="checkbox"], when targeting specific types of input.
The square brackets target an attribute such as type for an input elemet.
In your case you're selecting a checked checkbox.
I've a text box in my html file and I want to detect whenever a user changes the value of it and determine its updated value also. html code for text box is :
<input type="text" name="amount" id="amount" value="0" onchange="Demo().change(id,value)">
and in my scala file, I've implemented a function 'change' as :
#JSExport
def change(id:String):Unit={
appendPar(document.body,"Text Box value is changed and the new value is : "+document.getElementById(id).getAttribute("value"))
}
But it is not working in my case. What am I doing wrong here ?
Any suggestions ?
UPDATE : It is firing the event only when I press enter after altering the value in text box. Further, it is showing updated value as "0". How can I make it fetch from the text box instead of my pre defined value ?
You can use input event instead of change if you can ignore IE<=9.
The DOM input event is fired synchronously when the value of an or element is changed
From MDN.
Note that for non-text/textarea inputs (e.g. checkboxes, radio buttons, etc.) there are additional browser compatibility caveats, but you can just use change event on those. See http://caniuse.com/#search=input for details.
I also don't see where the variable id is coming from in your code. You should pass the string "amount" instead of id if that's what you want, like this: Demo().change("amount"). That would be quite unreusable, but it should at least work.
If you want the method to be more generic, note that javascript passes an Event object to all event handlers, and it has a target key which contains the HTML element on which the event happened (in this case that would be your textarea). You can get then easily get the value of that target.
If this is confusing, I suggest you try to implement this in JS first, and then translate this into Scala. You don't want to be fighting on both fronts at the same time.
You'll need to use one of the onkey handlers. For example:
Note that IIRC, this will also trigger if the user moves around with the arrow keys. So if you really want to only be called if it changes, you'll need to introduce a variable and check:
var lastValue: String = ""
#JSExport
def change(id:String): Unit = {
val newValue = document.getElementById(id).getAttribute("value")
if (lastValue != newValue) {
appendPar(document.body,
"Text Box value is changed and the new value is : " + newValue)
lastValue = newValue
}
}
I'm writing an application using XML view. There is a JSON Model 'data' set on the view, when I put a text field like below, I can get the updated value from user input.
<TextField value="{path: 'data>/xxx'}" />
But if I put a formatter in the binding like below, then it's impossible to get the updated value back.
<TextField value="{path: 'data>/xxx',
formatter: 'abc.util.formatter.yyy'}" />
Why is that? How to use JSONModel TwoWay binding and formatter at the same time???
The binding mode switches to OneWay as formatters do not support bi-directional data flow, as they are used for formatting property values for the output. A TwoWay binding includes also parsing and validating input before it is written to the model. If you need this, you should use a type instead. This is the same for all model type, not only the JSONModel.
Maybe your binding sytle is problem.
Can you try this in your index.
data-sap-ui-xx-bindingSyntax="complex"