View this page in the latest version of Appian. Create a Custom Chat Interface Share Share via LinkedIn Reddit Email Copy Link Print On This Page Tip: Interface patterns give you an opportunity to explore different interface designs. Be sure to check out How to Adapt a Pattern for Your Application. Goal Build a custom chat interface by using the cardLayout component to give each message a distinct visual style. This design pattern is not recommended for offline interfaces because reflecting immediate changes in an interface based on user interaction requires a connection to the server. A common approach is to store each message as an object with a sender and text field. Then, apply conditional formatting to display different icons and styles depending on the sender. Create this pattern In this pattern, you store each message as an object with a sender and text field. Then, you apply conditional formatting to display different icons and styles depending on whether the sender is the "User" or the "AI". The a!callLanguageModel function is used to generate a response from the AI. To create this pattern, follow these steps: Set up local variables. Create local!messages to store the list of chat messages. Initialize it with a "Welcome" message from the "AI" sender. Create local!newMessage to store the user's input from the text field. Display the message history. Use a!forEach to iterate over the local!messages variable. For each message, display an a!cardLayout. This will put each message in its own visual container. Apply conditional styling to each message. Inside the iteration, use an a!sideBySideLayout to place an icon next to the message text. Use an if() statement to check fv!item.sender: If sender is "User", show the User icon and set the a!cardLayout style to STANDARD. If sender is "AI", show the Support icon and set the a!cardLayout style to ACCENT. Create the user input area. Below the a!forEach loop, add an a!sideBySideLayout. In the first item, add a text field that saves its value into local!newMessage. In the second item, add an a!buttonWidget with a "send" icon. Configure the send button logic. In the button's saveInto parameter, chain multiple a!save functions to execute in order: Append the user's message (from local!newMessage) to local!messages. Call a!callLanguageModel with local!newMessage as the prompt. Append the AI's response to local!messages. Clear the text field by saving null into local!newMessage. Example expression 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 a!localVariables( local!messages: {}, local!newMessage, local!updatedMessages, a!sectionLayout( label: "Customer Support", contents: { /* Render messages as cards with alternating margins */ a!forEach( items: local!messages, expression: a!cardLayout( contents: a!sideBySideLayout( items: { a!sideBySideItem( item: a!richTextDisplayField( value: a!richTextIcon( icon: if( fv!item.sender = "User", "user", "support" ) ) ), width: "MINIMIZE" ), a!sideBySideItem( item: a!richTextDisplayField( value: fv!item.text ) ) } ), style: if( fv!item.sender = "User", "STANDARD", "ACCENT" ), marginBelow: if( fv!item.sender = "User", "LESS", "MORE" ) ) ), /* Spacer to add breathing room before the input bar */ a!richTextDisplayField( value: "", marginBelow: "STANDARD" ), /* Input area: text field + send button */ a!sideBySideLayout( items: { a!sideBySideItem( item: a!textField( placeholder: "Describe your issue...", value: local!newMessage, saveInto: local!newMessage ), width: "10X" ), a!sideBySideItem( item: a!buttonLayout( primaryButtons: { a!buttonWidget( icon: "send", style: "LINK", size: "SMALL", saveInto: { /* Append the user's message to create updated history */ a!save( local!updatedMessages, append( local!messages, { sender: "User", text: local!newMessage } ) ), /* Save the updated messages to display */ a!save(local!messages, local!updatedMessages), /* Call Appian's default model and append its reply */ a!save( local!messages, append( local!messages, { sender: "AI", text: a!callLanguageModel( prompt: "You are a helpful customer support assistant.", messages: a!forEach( items: local!updatedMessages, expression: { messageContent: fv!item.text, role: if(fv!item.sender = "User", "USER", "ASSISTANT") } ) ) } ) ), /* Clear input */ a!save(local!newMessage, null) }, disabled: or(isnull(local!newMessage), trim(local!newMessage) = ""), submit: false ) } ), width: "MINIMIZE" ) } ) } ) ) Displays the following: Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Test it out To test this pattern: Copy and paste the example expression into an interface object. Observe the interface in Preview mode. You will see the initial "Welcome" message from the AI. In the text field at the bottom, type a question, such as "How do I reset my password?". Click the send icon. Verify that your message appears in the chat history with the user icon and a "STANDARD" style card. After a moment, verify that a new response from the AI appears below your message, using the support icon and an "ACCENT" style card. Feedback Was this page helpful? SHARE FEEDBACK Loading...