"FormatException in property ... " error despite valid Expression Binding syntax - sapui5

I would like to display a sap.m.Button in case the value of two model properties are equal. It that possible via expression binding.
Bindings:
{user-management>/alias}
value: "TESTUSER"
{recipe-service>Author/alias}
value: "TESTUSER"
My attempts:
<Button xmlns="sap.m" visible="{= ${user-management>/alias} === ${recipe-service>Author/alias}}" />
<!-- or: -->
<Button xmlns="sap.m" visible="{= ${user-management>/alias} === ${recipe-service>Author/alias} ? true : false}"/>
The above attempts are not working resulting with the following console error:
FormatException in property 'visible' of 'Element sap.m.Button#__button1': TESTUSER is not a valid boolean value
Hint: single properties referenced in composite bindings and within binding expressions are automatically converted into the type of the bound control property, unless a different 'targetType' is specified. targetType:'any' may avoid the conversion and lead to the expected behavior.
I am not aware of using targetType for expression binding.

You must be using an OData V4 service. In that case, replace $ with % within the expression binding where the V4 OData model value is embedded but causes the above error.
Assuming the latter "recipe-service" model is sap.ui.model.odata.v4.ODataModel:
<Button xmlns="sap.m" visible="{= ${user-management>/alias} === %{recipe-service>Author/alias}}" />
See also the information about the automatic type determination in topics Changes Compared to OData V2 Model and Type Determination.

Related

sap.m.Input's value binding with type="Number" clears the input field

This is a follow-up question to How to bind integer Input value to Slider.
I have found out that the demo solution in this answer only works when there are integer values in the slider and the language of your browser is set to English.
Snippet from the demo:
<Input xmlns="sap.m"
xmlns:core="sap.ui.core"
core:require="{FloatType: 'sap/ui/model/type/Float'}"
type="Number"
value="{
path: '/value',
type: 'FloatType'
}"
/>
To reproduce the issue:
Go to the settings of your browser.
Set e.g. German as the language.
Reload the demo.
If the step of the slider is then set to an integer value (e.g. 1), values are all shown correctly in the input field.
With step="0.1", however, only integer values are shown whereas float values (e.g. "1,4") are hidden, causing warning in the browser console:
The specified value "1,4" cannot be parsed, or is out of range.
Any ideas or better solutions?
In that case, remove type="Number" from the <Input> control.
The property type="Number" in UI5 shouldn't be used together with value-binding anyway, due to browsers implementing HTML <input type="number"> behavior slightly differently, according to the API reference:
Only the default value sap.m.InputType.Text may be used in combination with data model formats. (Source).
Found a solution:
A formatter is needed that replaces the "," with a ".":
formatStringToNumber: sNumber => parseFloat(sNumber.replace(","))
In the binding of the input then simply add the formatter:
<Input
width= "50px"
type="Number"
value="{
path: '/passageWidth',
formatter: 'formatStringToNumber',
type: 'FloatType',
formatOptions: { emptyString: 0 }
}"/>

Angular2 applies ng-valid class to field when required attribute is conditional and value is still empty

I'm using angular 2.3.1 and I have the following html element in a component template:
<input class="form-control" type="text" id="password" name="password"
placeholder="Password" [attr.required]="requirePasswd ? true : null"
[(ngModel)]="password">
If this is a new user (id is empty) then I want to require the password. If not a new user, the password is optional.
The conditional attribute is working but when used conditionally, the ng-valid class is applied even though the field still has no value.
If I hard code the required attribute, angular2 appropriately sets the class to ng-invalid, but when I make it conditional and requirePass is true, this element always has the ng-valid class even when it's still invalid.
Check out the Angular 2 source. You'll see that required is actually a Directive, so you'll need to use that syntax to setup your binding here.
It also takes a value, it doesn't just have to be present, so instead of passing in null you can just pass in true/false.
[required]="requirePasswd"

Cannot use value 0 of an enumeration while defining instances of an entity

While using CF Entities, I'm facing an issue defining instances of an entity that uses an enumeration value.
I can add the instances of the entitytwor, but during build or save an error would show up arguing:
CF0134: Instance value for key property 'EnumType' of entity 'Namespace.Entity' cannot be equal to the key property default value '0' of type 'System.Int32' ...
XML would present associated enumeration value for the property as expected.
It looks like the problem only occurs when first enumeration value is being used (associated value 0). Other lines won't be a problem.
Is there any particular things to do while defining enumeration values or use of them ?
Thanks for your answer
CodeFluent Entities defines the concept of "default value" for properties of any type, including value types and enums. The default value allows to store null in a database without having to use .NET Nullable type.
<cf:enumeration name="EmailStatus">
<cf:enumerationValue name="Valid" /> <!-- will become NULL in the Database -->
<cf:enumerationValue name="Invalid" />
</cf:enumeration>
Although the default values behavior is enabled by default you can also change it:
at the Property level by setting its usePersistenceDefaultValue attribute to false:
<cf:property typeName="EmailStatus" usePersistenceDefaultValue="false" />
at the Enumeration level by setting its usePersistenceDefaultValue attribute to false:
<cf:enumeration usePersistenceDefaultValue="false" />
at the Project level by setting its defaultUsePersistenceDefaultValue attribute to false:
<cf:project defaultUsePersistenceDefaultValue="false" />
http://blog.codefluententities.com/2012/11/15/property-default-values-and-enumerations/

Unable to keep the static data for the input type fields in angular material

How to make a default static value for input in material design?
<input type="text" value="xyz" />
but in material design angular I am unable to keep the static value like value="xyz
<md-input-container>
<label>Start date</label>
<input ng-model="agg.startDate" value="xyz">
</md-input-container>"
value xyz is not affected in this case.
In your controller create a variable named agg.startDate using the $scope variable, like following code to set the value of input field
$scope.agg = {startDate: 'xyz'};
check this fiddle link

How can I automatically add labels to input fields?

I'm working on a bigger project with AngularJS. Therefore, I want to make the work for a single form as easy as possible. As we're also using bootstrap, the code for a single input field in a form is quite verbose, maybe like
<div class="control-group">
<label class="control-label" for="inputEmail">Email</label>
<div class="controls">
<input type="text" id="inputEmail" placeholder="Email">
</div>
</div>
If I could write a single tag like
<custom-input
label="Email"
name="inputEmail"
placeholder="Email"
type="text"
... >
</custom-input>
instead, this would help to keep the code clean and the work simple.
To achive this, I'm working on a custom AngularJS directive. My directive currently uses a template similar to the bootstrap example from above, automatically assigning the label to the input-tag. Also, the directive's compiler function moves all attributes from the custom-input tag to the real input-tag in order to make it easy to customize the custom-input tag.
app.directive('customInput', function() {
return {
require: 'ngModel',
restrict: 'E',
template: '<div>' +
'<label for="{{ name }}">the label</label>' +
'<input id="{{ name }}" ng-model="ngModel" />' +
'</div>',
scope: {
ngModel: '=',
name: '#name',
},
replace: true,
compile: function (tElement, tAttrs, transclude) {
var tInput = tElement.find('input');
// Move the attributed given to 'custom-input'
// to the real input field
angular.forEach(tAttrs, function(value, key) {
if (key.charAt(0) == '$')
return;
tInput.attr(key, value);
tInput.parent().removeAttr(key);
});
return;
},
};
});
On Stack Overflow, there are many questions regarding the creation of custom input fields, but they are concerned with the data binding, custom formatting or binding to ng-repeat.
My approach however has a different issue: while the data binding works correctly, Angular's integrated form validation module get confused when the input field is 'required'. For some reason, validation doesn't recognize the new input field and instead keeps the form invalid because of some dead reference, which has an empty value. Please see the minimal example.
Where does the dead reference come from? How can I update the validation-module's references? Is there a better way to achieve my overall goal?
As a boolean attribute, there is a corresponding required property that is still true on your div even if the attribute is moved.
The required attribute isn't getting moved, it must be getting skipped because there is no value. I don't know how to even add it to an element using javascript without a value, but using the form required="required" fixes that
Using transclude=true will use a copy of your element after the compile phase when you moved attributes, I think this keeps the required property from being set
You have to assign a higher priority for some reason, maybe because of ng-model, which is not removed from your div because the name in tattrs is ngModel (although removing from the div doesn't remove the need for priority)
http://plnkr.co/edit/5bg8ewYSAr2ka9rH1pfE?p=preview
All I did was change the required attribute to be required="required" and add these two lines to the directive declaration:
transclude: true,
priority: 10,
I put ng-transclude on the template label by the way so the contents of your element will go in the label and you don't have to have an attribute for that.