Using a list MI API transaction for a form

For M3 we have different APIs, most used are probably the list and get APIs. But what if you have a mashup and what you need is in a list API? Well you could just as well use the list API and bind to the first returned item. Or in fact you configure the MIDataService to only return the first result in the list.

Assuming there is an exact match you will get the expected data back. Say that you want to list customers and you pass in Infor, if infor isn’t a valid customer the list API will return whatever customer that comes after alphabetically.

My example will have an entry field for the customer to search for and a button that will trigger the List Event. In a real scenario this would probably be replaced with an event from a standard M3 form, like a CurrentItemChanged on a list or a detail form.

1. Adding the TextBox and the Button to the UI

<StackPanel Orientation="Horizontal"><TextBlock Text="Customer:" VerticalAlignment="center" />
   <TextBox Name="searchText" Width="200" />
      <Button Content="Search" IsDefault="True" Style="{DynamicResource styleButtonPrimaryMashup}"/>
</StackPanel>

2. Add a MIPanel and configure it for CRS610MI LstByNumber


3. Before saving I select the Generate Form button and order the fields. If the GenerateButton is not pressed then no XAML for the UI will be generated – only the XAML for the definition of the datasource. There is no roundtrip editing of the UI in the control so keep in mind that manually added converters and styles and stuff will be lost if you edit the control for example if you want to add another field.

4. Generate MI Panel Content Screen

Here are the fields that I would like to display in the form. The isvisible flag is for those values that should exist in the form but not be visible. This approach is useful when you have a scenario were for example the key, like CUNO should be in the form but it doesn’t need to be visible but it is needed for further events such as calling an API to update the data.

The result is the XAML for the form.

<m3:MIPanel Name="customer">
    <m3:MIPanel.DataSource>
      <m3:MIDataSource Program="CRS610MI" Transaction="LstByNumber" Type="List" InputFields="CUNO" OutputFields="SMCD,AGPG,TDIN,CORG,COR2" MaxReturnedRecords="1" />
    </m3:MIPanel.DataSource>
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <Label Content="Organization number 1:" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [CORG]}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Organization number 2:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [COR2]}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Overdue invoice amount:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="15" Text="{Binding [TDIN]}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Post giro number:" Grid.Row="0" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [AGPG]}" Grid.Row="0" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Salesperson:" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [SMCD]}" Grid.Row="1" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
    </Grid>
  </m3:MIPanel>

5. Make sure the panel is entered in a new row by setting Grid.Row=”1”. Now the UI and the data service are configured. All that remains is to define the event that will drive the detail form and to modify the generated bindings since the actual result for a list is a collection and not a specific entry. {Binding [SMCD]} assumes that the DataContext is a single result which it won’t be so we need to manually fix that as well.

There is a general difference between using a list or a detail panel. MIListPanel has an Items property with the result and the MIDetailPanel has an Item property. The only reason we added the Detail panel was to generate the XAML with the form. Copy out the Grid with the content above. Now we have to replace the MIPanel with a list.

6. It’s the same configuration and generation but it will generate a ListView as content. Replace the ListView with the grid from above. The code will look like this:

<m3:MIListPanel Name="customer" Grid.Row="1">
    <m3:MIListPanel.DataSource>
      <m3:MIDataSource Program="CRS610MI" Transaction="LstByNumber" Type="List" InputFields="CUNO" OutputFields="CORG,COR2,TDIN,SMCD" />
    </m3:MIListPanel.DataSource>
      <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <Label Content="Organization number 1:" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [CORG]}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Organization number 2:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [COR2]}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Overdue invoice amount:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="15" Text="{Binding [TDIN]}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Post giro number:" Grid.Row="0" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [AGPG]}" Grid.Row="0" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Salesperson:" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [SMCD]}" Grid.Row="1" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
    </Grid>
  </m3:MIListPanel>

7. Set the correct DataContext. The result for the list is in an Items proeprty. To bind to a single line add the following to the grid.
DataContext=”{Binding Items[0], ElementName=customer}”

8. Add the following event to the Button

<Button Content="Search" IsDefault="True" Style="{DynamicResource styleButtonPrimaryMashup}">
  <Button.CommandParameter>
    <mashup:Events>
      <mashup:Event TargetName="customer" SourceEventName="Click" TargetEventName="List">
        <mashup:Parameter TargetKey="CUNO" Value="{Binding ElementName=searchText, Path=Text}" />
      </mashup:Event>
    </mashup:Events>
  </Button.CommandParameter>
</Button>

9. In my final mashup code I added a list just to validate the data.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI" xmlns:m3="clr-namespace:MForms.Mashup;assembly=MForms">
  <Grid.Resources>
  </Grid.Resources>

  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <StackPanel Orientation="Horizontal"><TextBlock Text="Customer:" VerticalAlignment="center" /><TextBox Name="searchText" Width="200" />
    <Button Content="Search" IsDefault="True" Style="{DynamicResource styleButtonPrimaryMashup}">
      <Button.CommandParameter>
        <mashup:Events>
          <mashup:Event TargetName="customer" SourceEventName="Click" TargetEventName="List">
            <mashup:Parameter TargetKey="CUNO" Value="{Binding ElementName=searchText, Path=Text}" />
          </mashup:Event>
          <mashup:Event TargetName="customerList" SourceEventName="Click" TargetEventName="List">
            <mashup:Parameter TargetKey="CUNO" Value="{Binding ElementName=searchText, Path=Text}" />
          </mashup:Event>
        </mashup:Events>
      </Button.CommandParameter>
    </Button>
  </StackPanel>
  <m3:MIListPanel Name="customer" Grid.Row="1" Margin="10,30,10,0">
    <m3:MIListPanel.DataSource>
      <m3:MIDataSource Program="CRS610MI" Transaction="LstByNumber" Type="List" InputFields="CUNO" OutputFields="CORG,COR2,TDIN,SMCD,AGPG" />
    </m3:MIListPanel.DataSource>
    <Grid DataContext="{Binding Items[0], ElementName=customer}">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="8" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="16" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <Label Content="Organization number 1:" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [CORG]}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Organization number 2:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="11" Text="{Binding [COR2]}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Overdue invoice amount:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="15" Text="{Binding [TDIN]}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Post giro number:" Grid.Row="0" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [AGPG]}" Grid.Row="0" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Label Content="Salesperson:" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Left" VerticalAlignment="Center" />
      <TextBox MaxLength="10" Text="{Binding [SMCD]}" Grid.Row="1" Grid.Column="6" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
    </Grid>
  </m3:MIListPanel>
  <m3:MIListPanel Name="customerList" Grid.Row="2" Margin="10">
    <m3:MIListPanel.DataSource>
      <m3:MIDataSource Program="CRS610MI" Transaction="LstByNumber" Type="List" InputFields="CUNO" OutputFields="CUNM,CUNO,CORG,COR2,TDIN,AGPG,SMCD" MaxReturnedRecords="1" />
    </m3:MIListPanel.DataSource>
    <ListView ItemsSource="{Binding Items}" Style="{DynamicResource styleListView}" ItemContainerStyle="{DynamicResource styleListViewItem}">
      <ListView.View>
        <GridView ColumnHeaderContainerStyle="{DynamicResource styleGridViewColumnHeader}">
          <GridView.Columns>
            <GridViewColumn Header="Customer number" DisplayMemberBinding="{Binding [CUNO]}" />
            <GridViewColumn Header="Organization number 1" DisplayMemberBinding="{Binding [CORG]}" />
            <GridViewColumn Header="Organization number 2" DisplayMemberBinding="{Binding [COR2]}" />
            <GridViewColumn Header="Overdue invoice amount" DisplayMemberBinding="{Binding [TDIN]}" />
            <GridViewColumn Header="Post giro number" DisplayMemberBinding="{Binding [AGPG]}" />
            <GridViewColumn Header="Salesperson" DisplayMemberBinding="{Binding [SMCD]}" />
          </GridView.Columns>
        </GridView>
      </ListView.View>
    </ListView>
  </m3:MIListPanel>
  <ui:StatusBar Name="StatusBar" Grid.Row="3" Grid.Column="0" />
</Grid>

In this example I demonstrated how to use a list api but bind to the details in a form. Note however that using this above combination might not trigger the correct CurrentItemChanged event when content is loaded. I have not tested but I can imagine that there are issues since the different MI Mashup controls target different purposes and different usage scenarios.

What remains in the example? I generally don’t like the idea that you might get the details for another customer if there is no exact match. Not sure how to solve that. Perhaps we could use the generic property setter event combined with a converter. But a converter has to be a converter that is already part of the LSO.

A good tip if you have issues is to use Fiddler to see exactly what is returned from the API. You could also test the MI transaction in MITest++ , that is mforms://mitest a test tool that is available from within LSO. LSO uses a M3-API-WS and relies on meta data information for successful handling of data. If you have issues with making the request in MITest++ and it works in MITest then the issue is always in the meta data for the MI transactions.
Happy coding!

2 thoughts on “Using a list MI API transaction for a form

  1. Jon

    Fantastic blog. Do you think you could do one for a easy add button. I need to create a button to link to a mod our company created. I just don’t know the script command to launch the program. Cheers

    1. karinpb Post author

      Hi,
      Do you mean in a Mashup or in a JScript? I’ll probably do both. New post coming.
      In a mashup you need to add an event and then write in the URL that you want to launch.
      There is a LinkUri property on the Event that you can set in code (or properties in 9.1.3).
      It looks like this:

        <Button Content="Open MMS001" Width="100" Margin="8">
              <Button.CommandParameter>
                <mashup:Events>
                  <mashup:Event SourceEventName="Click" LinkUri="mforms://mms001">
                  </mashup:Event>
                </mashup:Events>
              </Button.CommandParameter>
        </Button>
      

Comments are closed.