I'm quite new working with webflow, and I having some troubles to make a custom converter for date binding (I need to changue the default pattern for 'dd-MM-yyyy')
So I'm trying to do something like this:
<view-state id="viewAnexos" view="myview" model="myModelBean">
<binder>
<binding property="anyDateOfTheBean" required="true" converter="customConverter"/> <!-- the type is java.util.Date -->
</binder>
<transition on="saveAnexo" to="viewAnexos" bind="true">
<evaluate expression="myController.saveAction(myModelBean, messageContext)" />
</transition>
</view-state>
And I've defined the ConversionService
#Service("conversionService")
public class FlowConversionService extends DefaultConversionService {
public void FlowConversionService() {
addDefaultConverters();
}
#Override
protected void addDefaultConverters() {
super.addDefaultConverters();
addConverter(new StringToDateCustomConverter());
addConverter("customCoverter,"new StringToDateCustomConverter()); //This method is deprecated, so how should I do it?
}
}
And the CustomConverter
public class StringToDateCustomConverter extends StringToObject {
private DateFormat format = null;
public StringToDateCustomConverter() {
super(StringToDateCustomConverter.class);
format = new SimpleDateFormat("dd/MM/yyyy");
}
#Override
protected Object toObject(String string, Class targetClass) throws ParseException {
return format.parse(string);
}
#Override
protected String toString(Object object) {
return format.format((Date) object);
}
}
And in my servlet.xml file, I've defined
<webflow:flow-builder-services
id="flowBuilderServices"
view-factory-creator="mvcViewFactoryCreator"
conversion-service="conversionService"/>
<bean id="conversionService" class="es.xunta.emprego.converter.FlowConversionService"/>
And after all this I'm having the next error:
org.springframework.binding.convert.ConversionExecutorNotFoundException: Custom ConversionExecutor with id 'customConverter' cannot convert from sourceClass [java.lang.String] to targetClass [java.util.Date]
Any ideas of what am I missing here..? Thanks in advance...
I've just changued a few things, and it works now.
1.-Renamed the StringToDateCustomConverter to StringToDate.
2.-The ConversionService has changued this way
#Service("conversionService")
public class FlowConversionService extends DefaultConversionService {
#Override
protected void addDefaultConverters() {
super.addDefaultConverters();
addConverter(new StringToDate()); //This is overrided
}
}
3.-The binder in the flow.xml is not necessary anymore, so...
<view-state id="viewAnexos" view="myview" model="myModelBean">
<transition on="saveAnexo" to="viewAnexos" bind="true">
<evaluate expression="myController.saveAction(myModelBean, messageContext)" />
</transition>
</view-state>
And that's it, it's working fine!!
Related
Can anyone help me? I created simply project Xamarin Forms with Prism i VS2017 on Android (screen). I used Prism Template Pack. I would like connect project with my WebService. here is a link to screen of all project
I have two projects PrismCoursApp and PrismCoursApp.Droid. First project contains SecondPageViewModel.cs where I try use connected WebService (wsMES) but I can't add namespace with PrismCoursApp.Droid.
The namespace of project PrismCourseApp.Android is PrismCourseApp.Droid and
PrismCourseApp.Android depends on PrismCourseApp.
I could add reference to Web service only in PrismCoursApp.Android project but I would like to use it in SecondPageViewModel.cs in PrismCourseApp.
Can someone tell me what I'm doing wrong?
Thanks
SecondPageViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using PrismCourseApp.Models;
using System.Collections.ObjectModel;
namespace PrismCourseApp.ViewModels
{
public class SecondPageViewModel : BindableBase, INavigationAware
{
//zmienna do WebService
//wsMES.WSwitoMES ws = new wsMES.WSwitoMES();
private string _title;
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
private string _UserCode;
public string UserCode
{
get { return _UserCode; }
set { SetProperty(ref _UserCode, value); }
}
private string _LokalizCode;
public string LokalizCode
{
get { return _LokalizCode; }
set { SetProperty(ref _LokalizCode, value); }
}
public SecondPageViewModel()
{
UserCode = AppStateTest.User;
LokalizCode = AppStateTest.CurrentCode;
Title = "Użytkownik/Lokalizacja";
}
public void OnNavigatedFrom(INavigationParameters parameters)
{
}
public void OnNavigatedTo(INavigationParameters parameters)
{
if (parameters.ContainsKey("par1"))
{
string par1 = (string)parameters["par1"];
string par2 = (string)parameters["par2"];
}
}
public void OnNavigatingTo(INavigationParameters parameters)
{
}
}
}
SecondPage.axml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="PrismCourseApp.Views.SecondPage"
BackgroundColor="White"
Title="{Binding Title}"
xmlns:b="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
xmlns:c="clr-namespace:PrismCourseApp.Converters;assembly=PrismCourseApp">
<ContentPage.Resources>
<ResourceDictionary>
<!--<c:ItemTappedEventArgsConverter x:Key="itemTappedEventArgsConverter" />-->
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout
Spacing="20">
<Label
Text="Zalogowany użytkownik:"
TextColor="Gray"/>
<Label
Text="{Binding UserCode}"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Label
Text="Lokalizacja:"
TextColor="Gray"/>
<Label
Text="{Binding LokalizCode}"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<ListView
x:Name="lstView">
<!--ItemsSource="{Binding MyDatas}">-->
<!--<ListView.Behaviors>
<b:EventToCommandBehavior EventName="ItemTapped"
Command="{Binding ItemTappedCommand}"
EventArgsConverter="{StaticResource itemTappedEventArgsConverter}" />
</ListView.Behaviors>-->
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding name}" Detail="{Binding comment}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
SecondPage.axml.cs
using Xamarin.Forms;
using PrismCourseApp.Models;
using System.Collections.ObjectModel;
namespace PrismCourseApp.Views
{
public partial class SecondPage : ContentPage
{
//Elementy do ListView (klasa MyDate w PrismCourseApp)
private ObservableCollection<MyDate> MyDatas { get; set; }
public SecondPage()
{
InitializeComponent();
MyDatas = new ObservableCollection<MyDate>();
lstView.ItemsSource = MyDatas;
for (int i = 0; i < 30; i++)
{
MyDatas.Add(new MyDate
{
name = "Pozycja " + (i+1).ToString(),
comment = "Miejsce na szczegóły " + (i+1).ToString()
});
}
}
}
}
MainActivity.cs in Android Project
using Android.App;
using Android.Content.PM;
using Android.OS;
using Prism;
using Prism.Ioc;
namespace PrismCourseApp.Droid
{
[Activity(Label = "PrismCourseApp", Icon = "#drawable/ic_launcher", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App(new AndroidInitializer()));
}
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry container)
{
// Register any platform specific implementations
}
}
}
Summarising the discussion in the comments above:
One should not make a web service dependent upon something specific to one of many client platforms. It's preferable to put the service's interface between the server and the part of the client that's shared between the different client implementations.
Say you have a mobile app for Android and IOS. Then you'll have two projects MyApp.Droid and MyApp.IOS for the respective client-specific implementations. Also, there's a project that both of them reference, and that (hopefully) contains most of your app's client-side logic: MyApp.Logic.
Now for the server: you have the MyApp.Server project that implements the service. If you need to define interfaces to communicate between the app and the service (WCF comes to mind), you define a project referenced by both the client-side logic (MyApp.Logic) and the server implementation (MyApp.Server): MyApp.Interface.
MyApp.Droid & MyApp.IOS -ref-> MyApp.Logic -ref-> MyApp.Interface <-ref- MyApp.Server
How do I change the content of the second button, based on the method from the first button with MVVPCross?
Something like this:
MainPage.xaml:
<Button Content="Translate" Click="{x:Bind PhonewordTranslator.Translate}" />
<Button Content="{x:Bind PhonewordTranslatorViewModel.CallButtonText, Mode=TwoWay}" Click="{x:Bind PhonewordTranslatorViewModel.Call}" />
PhonewordTranslatorViewModel.cs:
public class PhonewordTranslatorViewModel : MvxViewModel
{
...
private string _callButtonText;
public string CallButtonText { get=>_callButtonText; set=>SetProperty(ref _callButtonText, value); }
public void Translate()
{
SetProperty(ref _callButtonText, "test123");
}
}
Try this:
public void Translate()
{
CallButtonText = "NewText";
RaisePropertyChanged(() => CallButtonText);
}
Please modify your translate method as below:
public void Translate()
{
CallButtonText = "test123";
}
So I am wrapping the Spring Integration TCP client to provide APIs for my application. Previous questions regarding this can be found here and here. The problem with this is that the gateway.send() doesn't end at all and the API response never comes back.
Here is my ServerConnection.java file:
package com.abc.xyz.serverconnection;
import org.springframework.context.support.GenericXmlApplicationContext;
public class ServerConnections {
private SimpleGateway gateway;
public ServerConnections() {
final GenericXmlApplicationContext context = setupContext();
this.setGateway(context.getBean(SimpleGateway.class));
}
public static GenericXmlApplicationContext setupContext() {
final GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load("classpath:META-INF/spring/integration/tcpClientServerDemo-context.xml");
context.registerShutdownHook();
context.refresh();
return context;
}
public SimpleGateway getGateway() {
return gateway;
}
public void setGateway(SimpleGateway gateway) {
this.gateway = gateway;
}
public boolean sendData(String input) {
this.gateway.send(input);
return true;
}
public void recieveData(String output) {
System.out.println("Data from server:" + output);
}
}
In my controller, I do something like this:
#RequestMapping(value = "/logon", method = RequestMethod.GET)
#ResponseBody
public String logon() {
// logics go here and the result is stored like below and sent
String message = "0000005401F40000C1E3E304010000000020000000000000000000000000000000000000000000004040404040404040C1E3E300C1C2C3C4C5C6C7C8E8C5E2C8E6C1D540F1F7F24BF0F1F64BF0F0F34BF0F5F200";
if (serverConnections.sendData(message)) {
return "Data sent successfully!";
} else {
return "Data not sent!";
}
}
Here is how my config looks like:
<context:property-placeholder />
<int:channel id="input" />
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="echoService"
method="recieveData"/>
<bean id="echoService" class="com.abc.xyz.serverconnection.ServerConnection" />
<bean id="CustomSerializerDeserializer" class="com.abc.xyz.serverconnection.CustomSerializerDeserializer" />
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:gateway id="gw"
service-interface="com.abc.xyz.serverconnection.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="<ip>"
serializer="CustomSerializerDeserializer"
deserializer="CustomSerializerDeserializer"
port="6100"
single-use="false" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="serverBytes2StringChannel"
connection-factory="client" />
EDIT: Not able to get the DEBUG log of the application since I am using the TCP client implementation as a Maven Module inside a Maven Project. Another module uses this as a dependency and that is where the REST API end-points reside at.
I think your
<int:service-activator input-channel="toSA"
ref="echoService"
method="recieveData"/>
Doesn't return any result to be sent to the replyChannel header, meanwhile your gateway.send() isn't a void method. That's how it waits for the reply which never comes back.
I am trying to add some elements in gwt-bootstrap3 modal [link], I am using UI-binder to generate the screen but nothing is appear.
my ui binder class
<?xml version="1.0" encoding="UTF-8"?>
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:b='urn:import:org.gwtbootstrap3.client.ui'
xmlns:res="urn:with:com.db.cary.client.resources.CSSResources">
<ui:with type="com.db.cary.client.resources.CSSResources" field="res">
</ui:with>
<b:Modal closable="true" fade="true" dataBackdrop="TRUE" dataKeyboard="true">
<b:ModalBody>
<b:Form type="HORIZONTAL">
<b:FieldSet>
<b:Legend>Please enter the book detail</b:Legend>
<b:FormGroup>
<b:FormLabel for="bookTitle" addStyleNames="col-lg-2">Title</b:FormLabel>
<g:FlowPanel addStyleNames="col-lg-10">
<b:TextBox placeholder="Enter book Title" ui:field="titleTextBox" />
</g:FlowPanel>
</b:FormGroup>
<b:FormGroup>
<b:FormLabel for="bookAuthor" addStyleNames="col-lg-2">Author</b:FormLabel>
<g:FlowPanel addStyleNames="col-lg-10">
<b:ListBox ui:field="authorListBox" />
<b:Button ui:field="newAuthorButton" type="LINK" size="EXTRA_SMALL">New author</b:Button>
</g:FlowPanel>
<g:FlowPanel addStyleNames="col-lg-offset-2 col-lg-10">
<b:TextBox ui:field="authorTextBox" placeholder="enter slash (/) separated list of authors"></b:TextBox>
</g:FlowPanel>
</b:FormGroup>
<b:FormGroup>
<b:FormLabel for="bookCategory" addStyleNames="col-lg-2">Category</b:FormLabel>
<g:FlowPanel addStyleNames="col-lg-10">
<b:ListBox ui:field="categoryListBox" />
<b:Button ui:field="newCategoryButton" type="LINK" size="EXTRA_SMALL">New Category</b:Button>
</g:FlowPanel>
<g:FlowPanel addStyleNames="col-lg-offset-2 col-lg-10">
<b:TextBox ui:field="categoryTextBox" placeholder="enter category"></b:TextBox>
</g:FlowPanel>
</b:FormGroup>
</b:FieldSet>
</b:Form>
</b:ModalBody>
<b:ModalFooter>
<b:Button type="PRIMARY" ui:field='submitButton'>Submit</b:Button>
<b:Button ui:field='cancelButton'>Cancel</b:Button>
</b:ModalFooter>
</b:Modal>
</ui:UiBinder>
and my view class
public class AddBook extends Modal {
interface CheckOutPopUpBinder extends UiBinder<Widget, AddBook> {
}
private static final CheckOutPopUpBinder binder = GWT.create(CheckOutPopUpBinder.class);
private final AuthorAndCategoryServiceAsync authorService = GWT.create(AuthorAndCategoryService.class);
private final LibraryServiceAsync libraryServiceAsync = GWT.create(LibraryService.class);
#UiField
TextBox titleTextBox;
#UiField
ListBox authorListBox;
#UiField
TextBox authorTextBox;
#UiField
ListBox categoryListBox;
#UiField
Button submitButton;
#UiField
Button cancelButton;
#UiField
Button newAuthorButton;
#UiField
Button newCategoryButton;
#UiField
TextBox categoryTextBox;
public AddBook(String title) {
binder.createAndBindUi(this);
setTitle(title);
initializeAuthorListBox();
initializeCategoryListBox();
}
private void initializeCategoryListBox() {
authorService.getCategories(null, new AsyncCallback<List<CategoryDTO>>() {
#Override
public void onFailure(Throwable arg0) {
Window.alert("unable to fetch category list");
}
#Override
public void onSuccess(List<CategoryDTO> arg0) {
for (CategoryDTO category : arg0)
categoryListBox.addItem(category.getCategoryName());
}
});
categoryListBox.setMultipleSelect(false);
categoryTextBox.setVisible(false);
}
private void initializeAuthorListBox() {
authorService.getAuthors(null, new AsyncCallback<List<AuthorDTO>>() {
#Override
public void onSuccess(List<AuthorDTO> arg0) {
for (AuthorDTO author : arg0) {
authorListBox.addItem(author.getAuthorName());
}
}
#Override
public void onFailure(Throwable arg0) {
Window.alert("Unable to fetch the list of authors");
}
});
authorListBox.setMultipleSelect(true);
authorTextBox.setVisible(false);
}
#UiHandler("cancelButton")
public void cancelAction(ClickEvent e) {
AddBook.this.hide();
}
#UiHandler("submitButton")
public void submitAction(ClickEvent e) {
AddBookDTO bookDTO = new AddBookDTO();
String bookTitle = titleTextBox.getText();
String bookCategory = categoryListBox.getSelectedValue() == null ? categoryTextBox.getText() : categoryListBox.getSelectedValue();
List<String> authorsList = new ArrayList<String>();
for (int i = 0; i < authorListBox.getItemCount(); i++) {
if (authorListBox.isItemSelected(i)) {
authorsList.add(authorListBox.getItemText(i));
}
}
if (null != authorTextBox.getText() && authorTextBox.getText().trim().length() > 0) {
String[] values = authorTextBox.getText().split("/");
for (String str : values) {
authorsList.add(str);
}
}
if (bookTitle == null || bookTitle.length() <= 0) {
Window.alert("Please enter a valid book title");
return;
} else if (bookCategory == null || bookCategory.length() <= 0) {
Window.alert("Please enter a valid book category");
return;
} else if (authorsList == null || authorsList.size() == 0) {
Window.alert("Please enter valid authors");
return;
}
bookDTO.setBookTitle(bookTitle);
bookDTO.setCategroyName(bookCategory);
bookDTO.setAuthors(authorsList);
libraryServiceAsync.addBook(bookDTO, new AsyncCallback<Boolean>() {
#Override
public void onFailure(Throwable arg0) {
Window.alert("There is some issue with database while adding book, Please contact your admin");
}
#Override
public void onSuccess(Boolean arg0) {
Window.alert("Book is successfully added !!!");
}
});
this.hide();
}
#UiHandler("newAuthorButton")
public void addAuthor(ClickEvent e) {
authorTextBox.setVisible(true);
}
#UiHandler("newCategoryButton")
public void addCategory(ClickEvent e) {
categoryTextBox.setVisible(true);
}
}
I am not sure, What is wrong but only header is appearing in the modal.
You are calling AddBook.this.show(); - this shows the Modal that is the base of this AddBook instance, not the instance defined in your UiBinder template. When you call setTitle(title); you are setting the header/title on this instance - this is why all you see is the header and not the rest of the modal. You should assign an ui:field to your Modal defined in your UiBinder template and show/hide it.
Also AddBook shouldn't be extending Modal - it shouldn't extend any widget class at all :) Normally, UiBinder classes are extending Composite - because your UiBinder template is composed of a variety of widgets and Composite is used to bring them together without exposing any of their APIs: you call initWidget with the result of binder.createAndBindUi(this).
But if you are creating a widget whose "main" widget is Modal, like here, you should just call binder.createAndBindUi(this) and ignore the Widget that is returned (just like you are doing now). This is because Modal attaches itself to the DOM, bypassing any GWT mechanism (actually, it conflicts with it).
Hello i have the following problem.
I have a search page lets call it search.xhtml and you can search for a bar-code. This value is unique so the result is always one or zero objects from the database
<p:panelGrid columns="1" style="margin:20px;">
<h:form>
<p:messages id="messages" globalOnly="true" showDetail="false" />
<p:message for="barcode" />
<p:inputText id="barcode" value="#{searchForm.barCode}"
required="true" requiredMessage="Value needed" />
<p:commandButton value="search"
action="#{searchForm.searchBarcode}" id="search"/>
</h:form>
</p:panelGrid>
This is the backingbean:
#ManagedBean
#ViewScoped
public class SearchForm extends BasePage {
private Long barCode;
#ManagedProperty("#{daoManager}")
public DaoManager daoManager;
public void setDaoManager(DaoManager daoManager) {
this.daoManager = daoManager;
}
public Long getBarCode() {
return barCode;
}
public void setBarCode(Long barCode) {
this.barCode = barCode;
}
public String searchBarcode() {
//request to dao to get the object
DataList<Data> data = daoManager.findbybarcode(barCode);
if (data.size() == 0) {
this.addMessage(FacesMessage.SEVERITY_ERROR,
"Not Found: " + barCode);
return null;
} else {
getFacesContext().getExternalContext().
getRequestMap().put("id", data.getId());
return "details";
}
}
So if i go to my details page which expect the parameter id this isnt send to the detail page.
backing bean details page:
#ManagedBean
#ViewScoped
public class DetailBean extends BasePage implements Serializable {
#PostConstruct
public void init() {
if (id != null) {
//Go on with the stuff
} else {
addMessage(FacesMessage.SEVERITY_ERROR,"Object not found");
}
}
}
What am i doing wrong? And is this wrong use of JSF? I know i can generate a list and the click on the result but thats not what i want. Also i can take the barcode from the first bean and pass it as a parameter but i want the details page only to accept the id from the objects. So is my thinking wrong? Or is there a solution to get it like this?
If I understand correctly, you wish to pass the ID of the barcode to the details page and yes this is possible.
getFacesContext().getExternalContext().getRequestMap().put("id", data.getId());
The following line is putting the ID parameter into the request that the client just sent you, but the navigation action to details will result in a different request. Try this instead:
return "details?faces-redirect=true&id=" + data.getId();
This will return an HTTP GET navigation action with the ID of the barcode passed as a request parameter in the request.