Add Custom Data Type/Field in Jaydata - jaydata

How can I add a custom data type in Jaydata wherein I can just add anything on it and have it output in http://localh.ost/blahblah/$metadata ?
Like
$data.Entity.extend("Office", {
Id: { type: "id", key: true, computed: true },
OfficeName: { type: "string", maxLength:50, alternativeName:"office_name" }
});
Like I want to add the alternativeName and have it output in the browser so that when I type the http://localh.ost/blahblah/$metadata, I can see it as one of the fields.
Like:
//other XML output here
<Property MaxLength="50" Name="OffName" Type="Edm.String" alternativeName="office_name"/>
//other XML output here
Right now, I can only see this:
<Property MaxLength="50" Name="OffName" Type="Edm.String" />
So how can I achieve this?

Start the custom attribute name with $ sign

Related

Ant Design - Form Item Custom rule triggering only when the input is different than the original value

I have a Ant Design Form Item with a custom rule to check for name uniqueness. I only want this to be triggered in the edit scenario if the name was changed.
For example, the user edits an existing object named "Bob", he changes the name to "Fred".
In this scenario I want the validation to be triggered.
If the user edits the existing object called "Fred", and doesnt edit this field, but edits another field on the form I don't want the name uniqueness to be triggered.
<Form.Item
name="name"
label="name"
rules={[
{
required: true,
message: "Please input the name",
}),
},
() => {
return {
validator: uniqueNameValidator,
};
},
]}
>
<Input autoFocus data-cy="dir-create-name" />
</Form.Item>
<Form.Item
name="desc"
label="Description",
})}
>
<Input.TextArea data-cy="dir-create-desc" />
</Form.Item>
I am not sure if there is a way to compare values, and only do the validation if the previous value doesn't match the new value

How to make a Prisma enum array the options for a chakra-react-select form

I'm trying to figure out how to make a chakra-react-select form, with options for selection that are defined as an enum in the Prisma schema as follows:
enum Category {
FUTURE
NATURAL
SOCIAL
}
I can see the form in the docs looks as follows:
<Select
isMulti
options={[
{
label: "I am red",
value: "I-am-red",
},
{
label: "I fallback to purple",
value: "i-am-purple",
}
]}
placeholder="Select categories"
closeMenuOnSelect={true}
onChange={onChange}
onBlur={onBlur}
value={value}
ref={ref}
/>
I can't find an example of how to make the prisma enum Category, the select options. I don't care if both label and value are the categories.
How can I use enum values as the select options?
You should be able to do something like this inside your select:
<Select
placeholder="Select categories"
>
{Object.keys(Category).map(cat => (<option>cat</option>))}
</Select>

UI5 i18n support for the static model data

I'm exploring the sap.f.ProductSwitch controller on a sample project sap.f.sample.ShellBarProductSwitch.
Everything is clear besides one thing, what should be the approach if I want to provide an i18n support for a list of products (model/data.json)?
E.g. additionally to the hardcoded English list of products:
{
"items": [
{
"src": "sap-icon://home",
"title": "Home"
}
]
}
I want to provide a Frech one:
{
"items": [
{
"src": "sap-icon://home",
"title": "Maison"
}
]
}
With a basic dialogues I can rely on the built-in i18n UI5-engine, but here I don't know how to enable i18n in an XML-template:
<f:ProductSwitchItem
src = "{src}"
title = "{title}" />
A home-made solution.
XML-template:
<f:ProductSwitchItem
src = "{src}"
title = "{titleI18NKey}" />
Controller:
const resourceBundle = this.getView().getModel("i18n").getResourceBundle();
const productSwitcherModelData = this.getView().getModel("productSwitcher")?.getData();
productSwitcherModelData.items.forEach((item) => {
item.titleI18NKey = resourceBundle.getText(item.titleI18NKey);
});
this.productSwitcher.setModel(this.getView().getModel("productSwitcher"));
In product switcher model instead of real text I store a key-value pair:
titleI18NKey: i18n_dialogue_key
which is later replaced by the end-text from the i18n-model and set to the productSwitcher model.
P.S. Please, let me know, if there is more elegant implementation based on UI5 functionality.
If you like the data binding approach better, you can use a formatter with the title property binding to retrieve the text from the resource model.
The key to the text of the resource bundle must be defined in your data.json for every item:
The JSON data model:
{
"items": [
{
"src": "sap-icon://home",
"titleI18NKey": "myResourceBundleKeyToThisItem"
}
]
}
The XML-template:
<ProductSwitch
change = "onClickProductSwitcherItem"
items = "{
path: '/items'
}">
<items>
<ProductSwitchItem
src = "{src}"
title = "{
path: 'titleI18NKey',
formatter: '.getText'
}" />
</items>
</ProductSwitch>
The formatter getText needs to be defined in your controller:
getText(i18nKey) {
const dialogue = this.getView().getModel("i18n").getProperty(i18nKey);
return dialogue;
}
If you only have static values I would rather not use list binding but create the product switch items individually:
<ProductSwitch change="fnChange" >
<items>
<ProductSwitchItem src="sap-icon://retail-store" title="{i18n>Title_1}" />
<ProductSwitchItem src="sap-icon://family-care" title="{i18n>Title_2}" />
</items>
</ProductSwitch >
In doing so you can use the resource model for the titles as usual and don't need any further code.

SAPUI5 XML View Binding with parameters from same model

I have the following Problem:
I want to develop a shopping cart and have problems with the counter of the product card and I have problems to show the data in the summary view.
For this project I use XML views and I've already readed a lot about binding. When I want to bind a static path I have no problems. The data comes from a JSON model named "cartData".
Example (from the goToCart Button)
...
text="{cartData>/currentUser}";
...
Everything shows correctly (in the example), but for my project I need to bind a main binding (for counter of the cart) and this path need a parameter for the user. Which is saved at the path like in the example.
I've already tried a lot of combinations to accomplish this bug, but now I have no more ideas :-(
A example of my tried combinations:
text="{ ${cartData>/cartOfUser/} + {cartData>/currentUser} + '/roles/counter'}"
EDIT:
Some dummy parts of my code:
My Button (doen't work yet how I need...):
<m:Button
id="details.Btn.ShowCart"
text="{ parts: [
{path: 'cartProducts>/cartEntries/'},
{path: 'cartProducts>/currentChoice/'},
{path: '/addedRoles/counter'}
]}"
type="Emphasized"
icon="sap-icon://cart-3"
iconFirst="true"
width="auto"
enabled="true"
visible="true"
iconDensityAware="false"
press="showCart"/>
How my JSON Model in LocalStorage look like:
{
"cartEntries": {
"counter": 2,
"UserId12": {
"UserId": "UserId12",
"Email": "Email12",
"dateCreated": "2017-07-14T13:18:13.632Z",
"dateUpdated": "2017-07-14T13:18:13.632Z",
"addedRoles": {
"counter": 0
},
"existingRoles": {
"counter": 0
}
},
"UserId14": {
"UserId": "UserId14",
"Email": "Email14",
"dateCreated": "2017-07-14T13:18:30.415Z",
"dateUpdated": "2017-07-14T13:18:30.415Z",
"addedRoles": {
"counter": 0
},
"existingRoles": {
"counter": 0
}
}
},
"currentChoice": "UserId14"
}
My JSON Data with comment:
I need to grab the value from "currentChoice", to search with this information in cartEntries for the right counter
How the Button look now:
It show the data not in the correct way. Please ignore the zero at first...
The goal is to take the value of "currentChoice" and use it as a 'parameter' to call the information for the right user..
What I also tried:
text="{= ${= 'cartProducts>/cartEntries/' + ${cartProducts>/currentChoice/} + '/addedRoles/counter' } }"
What works, but I need it more "dynamic" is:
text="{cartProducts>/cartEntries/UserId14/addedRoles/counter}"
I hope you guy's now know what I mean... :-/
Best regards
The Solution
How I solve the problem:
Add a formatter to the button:
/',
formatter: '.formatter._getCartInt'
}"
type="Emphasized"
icon="sap-icon://cart-3"
iconFirst="true"
width="auto"
enabled="true"
visible="true"
iconDensityAware="false"
press="showCart"/>
Implement the formatter in my formatter.js file:
_getCartInt: function (sP1) {
var sCurrent = sP1.currentChoice;
var sFinalString = "cartProducts>/cartEntries/" + sCurrent + "/addedRoles/counter";
this.getView().byId("btn.ShowCart").bindProperty("text",{path: sFinalString, type: new sap.ui.model.type.Integer()}); }
Try to use the following approach:
in i18n file:
cartInfoTitle=User: {0} has: {1} items in the cart
in XML view:
<Text text="{
parts: [
{path: 'i18n>cartInfoTitle'},
{path: 'modelName>/property1'},
{path: 'modelName>/property2'}
],
formatter: 'jQuery.sap.formatMessage'
}" />
So you declare the i18n entry and then use the predefined formatter to replace the placeholders with the values from the "parts" array (Documentation article).
Ok so to answer : you cannot use expression in a binding (same applies for classes). So to have the output you want you will indeed need a formatter + include the needed top level elements of your JSON model in the binding parts (so that it updates properly).
XML (I assume your model is called 'cartData')
<Text text="{
parts: [
'cartData>/cartEntries',
'cartData>/currentChoice'
],
formatter: '.myFormatter'
}" />
JS Controller
controller.prototype.myFormatter = function (cartEntries, currentChoice) {
if (cartEntries && cartEntries[currentChoice]) {
return cartEntries[currentChoice].addedRoles.counter;
}
}
[code not tested]

Using play's wsclient to make a call to fetch a RSS feed and return a collection

I am making a request to a URL to grab the RSS xml data:
val items: List[Item] = ws.url("http://www.example.com/rss.xml").get().map { response =>
}
Now I want to loop through all the nodes and create a collection of Items.
My Item case class is:
case class Item(title: String, link: String, description: String, guid: String)
The format of the XML is like below:
<rss ...>
<channel>
<title>
</title>
<link />
<description />
<item>
<title>hello</title>
<description> ... </description>
<guid> ... </guid>
</item>
<item>
...
</item>
</channel>
</rss>
I'm not sure what to do with the response in the call to .map to iterate through the items and how to return a collection of Item case classes.
You should basically use the xml api to extract the relevant NodeSeq, which works like any collection.
Then you map each node to extract the relevant subtag content and create an object out of it.
val itemNodes = response.xml \\ "item" //will get all item nodes as a NodeSeq
val item = itemNodes.map(node =>
Item(
(node \ "title").text,
"", // there's no link tag in the item
(node \ "description").text,
(node \ "guid").text
)
)
If not exactly this, something similar