Set language label programmatically - zk

I have problems setting labels with language specifications programmatically after the component has been rendered. I have the following:
public class DateFilterWidget extends Div implements IdSpace {
private static final long serialVersionUID = 1L;
#Wire
Datebox startDate, endDate;
#Wire
Button filterButton;
#Wire
Label datefilterLabel;
String field;
public DateFilterWidget(String name, String filterField) {
Executions.createComponents("widgets/datefilter.zul", this, null);
Selectors.wireComponents(this, this, false);
Selectors.wireEventListeners(this, this);
datefilterLabel.setValue("${labels.data.dateFilterButton.label}");
this.field = filterField;
}
}
And the datefilter.zul
<hbox sclass="filterWidgetBox" align="center">
<label id="datefilterLabel" />
<datebox id="startDate" format="yyyy-MM-dd"
weekOfYear="true" width="105px"/>
<label value="-" />
<datebox id="endDate" format="yyyy-MM-dd"
weekOfYear="true" width="105px"/>
<button id="filterButtonc"
label="${labels.data.dateFilterButton.label}" />
</hbox>
I the above case the same label has been used for both the button and the label. The button language reference works fine, but the label that got a value programmatically don't work.
I know that I can use the Labels.getLabel("data.dateFilterButton.label"), but this solution removes the possibility to update language unless the whole application is rerendered with the new language.

label="${labels...}" is a static EL and will only get evaluated once the zul file is parsed, and has the same effect as calling setLabel(Labels.get(Labels.getLabel(...))).
The button language reference works fine
I don't really understand what you mean by that. When I run your example using Labels.getLabel(...) it works as expected, setting both labels in the current locale. When changing the locale during runtime e.g. from EN -> DE none of the labels update automatically, and both components need to be re-rendered and then update correctly.
To provide a solution, can you please give details on what you expect to happen? Or what you are trying to achieve regarding:
this solution removes the possibility to update language unless the whole application is re-rendered with the new language
"Update" can have several meanings, it's just not clear yet.
Robert

To set the value programmatically you should used the class Labels of the zk api.
You can see the javadoc clicking here:
Labels
And use the method getLabel.
Example:
datefilterLabel.setValue(Labels.getLabel("data.dateFilterButton.label");
If that is the right label key.

Related

How to get id of invisible element in fragment?

I have a Dialog in fragment:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<Dialog title="{i18n>AddNewItem}" resizable="true" draggable="true">
<content>
<MessageStrip
id="failMsg"
visible="false"
text="{i18n>SensorTypesCreateFail}"
type="Error"
showIcon="true"/>
</Dialog>
</core:FragmentDefinition>
As in UI5 doc:
Retrieving a control instance when the fragment is not part of a view:
When no fragment ID was given: myControl = sap.ui.getCore().byId("myControl")
When a fragment ID myFrag was given: myControl = sap.ui.core.Fragment.byId("myFrag", "myControl")
If there is no visible="false", I can get this MessageStrip by sap.ui.getCore().byId("failMsg").
But I found that with visible="false", id of MessageStrip is sap-ui-invisible-failMsg, I failed to found proper API to get it.
Of course I can use sap.ui.getCore().byId("sap-ui-invisible-failMsg"), but I am not sure whether this ID will change after I deploy it to FLP, and as #schnoedel said in another question:
Beware that the prefixes like -- and --- used by the framework may change in the future. Thats why it's recommended to use the public api functions the framework supplies like byId() and createId().
So, is there any better way to get it?
Update:
Change my code from:
this[dialogName] = sap.ui.xmlfragment("namespace." + dialogName, this);
this.getView().addDependent(this[dialogName]);
To
this[dialogName] = sap.ui.xmlfragment(dialogName, "namespace." + dialogName, this);
this.getView().addDependent(this[dialogName]);
And now my id is sap-ui-invisible-dialogName--failMsg...
It depends on what you want to achieve after getting the ID. If you just want to change a property you could do it without any ID via a Model.
For that you can assign a Model field (i.e. baseModel>/visable) to the visable property and once it should be changed you change the model and via two way binding it updates the control.
code to change a model:
this.getView().getModel("nameOfUrModel").setProperty("property", "value")
for more information about this just check the walkthrough tutorial on
https://sapui5.hana.ondemand.com/
And if you for whatever reason really need the ID:
https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.ui.core.Fragment.html
here you find the command:
sap.ui.core.Fragment.byId(sFragmentId, sId)
It should be able to return the Control your using
Hope that helps
Eric
You were very close to the solution. After adding dialogName for the fragment ID in its creation, you just have to call the API ...:
sap.ui.require(["sap/ui/core/Fragment"], Fragment => Fragment.byId(dialogName, "failMsg"));
... to get the control instance as mentioned here.
However, regardless whether you provided a fragment ID or not, you can easily ignore the render prefix "sap-ui-invisible-" at any time - Meaning that you could've also been able to get the control instance via sap.ui.getCore().byId("failMsg") instead of sap.ui.getCore().byId("sap-ui-invisible-failMsg") even if the control is invisible.

Listen to ItemTapped Event in FreshMvvm

In my project I have a list view, now listening to SelectedItem change is easy, every tutorial has that, but I can't find anything on using ItemTapped event.
What do I bind the event to in the modelPage?
Thanks,
Mike
Since ItemTapped is an event and not a Command (or BindableProperty at all) you cannot use it directly from you PageModel.
They have invented something like Behaviors for this. With Behaviors you can turn an Event to a Command.
While there are third party plugins which do this like Corcav's one, it is also built into Xamarin.Forms now.
Let me explain it by the Corcav one, other implementations should be similar. Also I'm assuming you're using XAML.
First of all, install the NuGet and don't forget to include the right namespace into your page, which means adding something like: xmlns:behaviors="clr-namespace:Corcav.Behaviors;assembly=Corcav.Behaviors"
Now under your ListView declare your Behaviors like so:
<!-- ... more XAML here ... -->
<ListView IsPullToRefreshEnabled="true" RefreshCommand="{Binding RefreshDataCommand}" IsRefreshing="{Binding IsBusy}" IsVisible="{Binding HasItems}" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" CachingStrategy="RecycleElement">
<behaviors:Interaction.Behaviors>
<behaviors:BehaviorCollection>
<behaviors:EventToCommand EventName="ItemSelected" Command="{Binding ItemSelectedCommand}" />
</behaviors:BehaviorCollection>
</behaviors:Interaction.Behaviors>
<!-- ... more XAML here ... -->
Note that is is a collection, so you could add more if you want (also in other scenarios).
Also note that I did in fact user the SelectedItem as well. This is probably what you want because else the item you tapped will stay selected. So the SelectedItem property doesn't do much more than set it back to null (hence the TwoWay). But you can also take the actual selected item from there.
So now in your PageModel declare a Command and assign it with something like this:
private void ItemSelected()
{
// Open the article page.
if (_selectedItem != null)
{
CoreMethods.PushPageModel<GroupArticlePageModel>(_selectedItem, false, true);
}
}
_selectedItem being the property to which the tapped item is assigned.
Of course you could do it even better and supply the behavior with a CommandParameter in which you put the tapped item reference.

Orchard rendering custom shape, displaying one child only

I'm very new at orchard and I'm having troubles finding a solution for what I think is a basic problem.
I want to render my own custom shape 'Content-Button' for my custom content type 'Button'. This works wonderful!
The Button content is made out of:
Display name
Content picker
My custom shape looks like this:
#using Orchard.Utility.Extensions;
#{
if (Model.Title != null) {
Layout.Title = Model.Title;
}
Model.Classes.Add("content-item");
var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
Model.Classes.Add(contentTypeClassName);
var tag = Tag(Model, "div");
tag.AddCssClass("row");
}
#tag.StartElement
<div id="" class="col-md-8 col-sm-10 col-xs-8 col-xs-push-2 col-sm-push-1 col-md-push-2 btn btn-secondary center-block">
#Display(Model.Content)
</div>
#tag.EndElement
What I'm however trying to do is instead of calling '#Display(Model.Content)' I would like to call a specific shape to be rendered there. Like #Display(Model.Content.DisplayName).
I would like to do the same for the content picker so i can make a link in the div (through ID)
I've also tried to exlude certain (extra) fields using my theme's placement.info) but it seems I'm doing something wrong there as well.
<Match ContentType="Button">
<Place Parts_Contents_Publish="-"></Place>
<Place Fields_Common_Text="-"/>
</Match>
Note: The 'Fields_Common_Text' was purely a test but it stills renders that shape on my button.
If somebody could point me in the right direction, explain it or send me some very good documentation to read through I would be a very happy man.
You can access fields directly as following:
#Model.ContentItem.ButtonPart.DisplayName.Value
and same thing for content picker field, then you don't need to use placement.info file any more.

Setting row class for sap.m.Table rows

I'm trying to assign a class to a row in my sap.m.Table dynamically using my view model SearchResults.
Unfortunately it's ignoring my class properties (see below).
How do I do this in my XML view ?
<ColumnListItem class="{SearchResults>typeClass}">
To apply CSS properties to row, you will also need take predefined CSS class of table .sapMListTbl along with your custom CSS class like I have done here.
I would suggest you to use formatter to apply these classes along with class from your model.
Unfortunately the class attribute is not bindable since it is not a property.
As a workaround you could do sth. like this:
<ColumnListItem visible="{
path: 'SearchResults>typeClass',
formatter: 'my.formatter.formatClass'
}" />
my.formatter.formatClass = function(typeClass) {
// in a static formatter this refers to the control, here your ColumnListItem
this.addStyleClass(typeClass);
// just always return true for the visible property
return true;
}
Note: The formatter can't be a member of your controller since then you won't be able to refer to the control (this will be the controller itself). Hence the formatter needs to be a static function.
Solution found!!!!
http://scn.sap.com/community/developer-center/front-end/blog/2016/05/17/coloring-table-rows-conditionally-in-sap-ui5-xml-views-based-on-odata-service
Hopefully this help anyone who's had the same problem...

Format date shown on DatePicker

I created a Pivot Project on Visual Studio 2013.
I created the following control:
<DatePicker Header="Data" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" Width="341"/>
When I tap on it on my phone, it displays the date as M/D/Y. Is it possible to display it as D/M/Y?
Also, don't know if I should create another question, but how can I translate to pt-BR the day/month names shown within the control? As well as that "Choose a date".
The DatePicker format is using user's preferred language and region. This control will automatically look different, for my region it's day/month/year like you wish it to be. I've tried to force the control to use other language, but it seems to be taking it directly from phone settings. Some information you may find here at MSDN:
If you need to allow users to choose a date or select a time, use the standard date and time picker controls. These will automatically use the date and time formats for the user's preferred language and region.
The other bad news you can find here at MSDN about formating that particular control:
Note This section applies to Windows Store apps using C++, C#, or Visual Basic. Formatting is ignored in Windows Phone Store apps.
So in current API it may be hard to change the formatting.
The good news is for the CHOOSE DATE text at the top - it's automatically localized, depending on user's language and region. So you don't have to worry about it if your app supports user's language. But I've not found way to change it to other text.
As for the text displayed inside the button before it's clicked, you can always use Button with DatePickerFlyout, a simple example with apropriate converter:
<Button Content="{Binding ElementName=chosenDate, Path=Date, Converter={StaticResource DateFormatConverter}}">
<Button.Flyout>
<DatePickerFlyout x:Name="chosenDate" />
</Button.Flyout>
</Button>
and the converter class:
public class DateFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
DateTimeOffset chosen = (DateTimeOffset)value;
return string.Format("{0}/{1}/{2}", chosen.Day, chosen.Month, chosen.Year);
// or use chosen.ToString() with format provider
}
public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); }
}