Listener for the JSONModel for Custom Control UI5 - data-binding

i have a custom control which need to array of data as below
properties : {
scrollheight: {type : "sap.ui.core.CSSSize", defaultValue : "100%"},
array1 :{type : "Array", defaultValue : []},
array2 : {type : "Array", defaultValue : []},
}
and i have 3 JSONModel which i have set to the View
Problem is i need to process these model and i have to make 2 arrays to set to the Custom control.
When any change happen to these JSONModels i need to update the array also.
How can i achieve this, if i bind these to property? or do i need to listen the changes to the model and update the array?
or is their any other method of doing it?

i solved this by getting the binding and attaching change event
We have to get the binding for particular item in the Model if its property we can take PropertyBinding if its List or array we have to take ListBinding
and then i have one model which is set to the Custom Control and change event will update the Custom control model
JSBin which shows how to add the change event to binding(Here i used ListBinding)

It is sometimes tough to keep the data in your JSONModel consistent from the controller, as you always have to remember that if you change one thing, you also have to change the other.
To make controller code less cluttered, I usually create a subclass of JSONModel in which I take care of the model consistency. This can be accomplished by overriding the setProperty method with your own, and when you see that a certain property is edited, dependent properties are immediately changed as well.
Please find an example of how this could work in the jsbin below. In the example I'm trying to keep property 2 consistent with property 1:
http://jsbin.com/novepa/1/edit?html,output

Related

Why can you set a lit public property 'attribute' option to false?

From the Lit documentation: "The component shouldn't change its own public properties, except in response to user input."
Also from the documentation: "Internal reactive state works just like public reactive properties, except that there is no attribute associated with the property."
However, when you declare a property, there is an option of setting attribute to false, which prevents an attribute from being associated with the property.
#property({attribute: false})
data = {};
What would be the purpose of doing this? Wouldn't the property just act like internal state at that point?
For reference, Lit already has several ways of declaring internal state variables, either with the #state decorator or setting the state option to true, so I'm just not sure why they allow this too.
I think the main use case for this is for when you have to pass big complex data to the component but want it to be set directly as a property and still get lit to rerender stuff for you.
I think this is easier to visualize with an example, let's say you're making a component which will render a list out of an array passed as a property.
If the array was set as an attribute, it would look something like this:
<list-renderer items='[{id: "1", name: "John Doe"}, {id: "2", name: "Alice Williams"}]'></list-renderer>
Now, this example only has two items, but it could be something way bigger, and that attribute will eventually need to be serialized into an array using JSON.parse() by lit. So, you're just doing an extra step, especially if you already had the array as a JS object rather than JSON data.
So, for this kind of cases it's easier to just force users to set items as a JS property directly.
This will also apply for when you need to pass complex configuration setting objects or functions to the component.
Then again, for most of the components you'll be making, you will probably stick with either having the attribute or making it a fully internal state property.
This way you are really free to use any combination.
A property which acts also as state and attribute
A property which acts also as state but not as an attribute
A state, which is not a property
A property, which is an attribute
A property which is not an attribute
see also https://javascript.info/dom-attributes-and-properties for the difference between properties and attributes.

Modify editability of a field from field group by code

I have this piece of code:
controlDetails = this.form().design(1).addControl(FormControlType::Group, #quickCreateDetails);
controlDetails.dataSource(fbds.id());
controlDetails.dataGroup(#quickCreateDetails);
controlDetails.frameType(10);
controlDetails.autoDataGroup(true);
controlDetails.hideIfEmpty(false);
controlDetails.columns(2);
I want to modify the editability of one certain field on that dataGroup, but I don't know how to do it with code or in the AOT (DS). Seems like Im pretty much limited...
You have next options:
change Form Data Source filed editability
via AOT - https://msdn.microsoft.com/EN-US/library/aa860145.aspx
via code FormDataSource.object: InventTrans_ds.object(fieldNum(InventTrans, Qty)).allowEdit(false)
change child control design property. addControl returns FormBuildGroupControl. Then you have to loop through controlNum(), find correct design control and cast it to one of FormBuildControl nested type with data bounding. There you have allowEdit method.

Get entity assert property in form view (or in form builder) to use with JS

I'm trying to access assert information defined in entity class from a form
class MyEntity {
[...]
/*
* #Assert\Count(min="1", max="3")
*/
protected $myfield;
[...]
}
The purpose is to customize the view.
In this example, I would like to display a message that said "you must enter between [min] and [max] items"
I var_dumped a lot of variable in form_div_layout.html.twig
I've tried to explore the FormBuilder object but I haven't found this.
Do you know a way to achieve this ?
PS: sorry for my poor english
EDIT AFTER Martin Rios answer:
The goal is not to provide error message.
The final goal is to use these values for the construction of the view.
For example, if you use this jQuery plugin: sfPrototypeMan, you can have an "add item" link and a "remove item".
If I want to disable the "add item" link when my collection reaches its maximum size, I need to manipulate constraint property in my JavaScript
I tried to study this plugin JsFormValidatorBundle but didn't understood how it works...
Why don't you do it like the Validation in the cookbook ?
Is far more easier than to do it inside your Entities. And at the same time you have the benefit of not having your entities coupled to Symfony.
# src/Acme/BlogBundle/Resources/config/validation.yml
Acme\BlogBundle\Entity\MyEntity:
properties:
myfield:
- Count:
min: 1
max: 3
minMessage: "You must specify at least one item"
maxMessage: "You cannot specify more than {{ limit }} items"
Make sure the property you are validating is a collection's (i.e. an array or an object that implements Countable)
EDITED after the edition of chakhâl :
You don't need to overcomplicate things, if you want to access it from somewhere just keep this values in parameters.yml and do a Custom form Validation
AFAIK you cannot use a variable defined in parameters.yml on the validation otherwise this will be very easy.
But I try to keep always in mind, that forms are forms, and views are different things. So if you want to keep things simple, just pass this min / max values as an additional template array, and define it in the parameters.yml. Only if you need to go deeper, then inject them in a custom validator and have them in a single place (But it sounds like overcomplicating things a bit in my personal opinion)

Setting all QLineEdits to readOnly

I am trying to make all of my QLineEdits(I have about 150) read-only, is there a way to do this without going through and setting each individually? I was hoping I could do something like QLineEdit::setReadOnly(true); in my constructor but I get a compiler error saying it is an illegal call of non-static member function.
Thank you in advance!
Use QObject::findChildren(), like this:
QList<QLineEdit*> l_lineEdits = ui->frame->findChildren<QLineEdit*>();
foreach (QLineEdit* l_lineEdit, l_lineEdits) {
l_lineEdit->setReadOnly(true);
}
In this example the ui->frame is the parent widget of all the QLineEdits. Just change it to yours.
What you can do is to inherit from QLineEdit and call setReadOnly(true) in its constructor. Now instead of creating object of QLineEdityou create objects of your custom MyQLineEdit. If you need to change this property dynamically then i guess there is no way but to store references to all of them in some array and traverse that to toggle this property.

Can you prevent LinqDataSource from setting a property?

I've got a Linq 2 SQL object I'm trying to update. Two of the properties on this object are related to each other, and setting one sets the other.
So if I do:
Foo.Code = BEER;
The Foo.CodeID property will automatically be set to 5 (or whatever.)
The problem is that LinqDataSource sets Foo.Code, then immediately sets Foo.CodeID... which is not bound to anything since we want the users to set just Code. This immediately sets them both back to null.
I know I can use Parameters to default values, but is there any way to just tell LinqDataSource to not even set a property?
EDIT: Worked around issue by creating a hidden field, and assigning the correct value to that in the formview's ItemUpdating event. Would still like to avoid doing the same lookup four times though...
Would it be an option to make the Code property private (select the Code property in the dbml and set the access property in the Properties window) and create a new public property over which you have more control?
I personally have have written a generator that generates the necessary files for me (like sqlmetal), giving me full control over the code. Perhaps this is an option for you as well, if you do not like the generated dbml.

Resources