Hi - We are currently working on building a chatbot. As part of that we tried to mimic the traditional chat UI by leveraging Appian components. However, we are facing an issue displaying the latest message entered by the user on a card layout. A scroll bar appears in this scenario and we need to manually scroll it. Also, Auto height on card layout doesn't work as chat window getting bigger. Any alternative approach or a way that we can take care of auto vertical scrolling on a component?
TIA
Discussion posts and replies are publicly visible
Hi Riyaz,
Could you please try this code . You may get some help . You can play around the UIs but lets see if this logic helps you
Here is the URL to try it
tlpf.appianportals.com/chatapp
a!localVariables( local!data:{}, local!msg, local!showAll:false(), a!formLayout( skipAutoFocus: false(), label: "Welcome", contents: { a!buttonLayout( primaryButtons: a!buttonWidget( label: if( local!showAll=false(), "Show All","Latest"), value: if( local!showAll=false(), true(),false()), saveInto: local!showAll ) ), if( local!showAll, a!forEach( items: local!data, expression: a!columnsLayout( columns: { a!columnLayout( contents: { a!textField( value: fv!item.msg, readOnly: true(), showWhen: if( loggedInUser()=fv!item.msgBy, true(), false() ) ) },
), a!columnLayout( contents: { a!textField( align: "RIGHT", value: fv!item.msg, readOnly: true(), showWhen: if( loggedInUser()=fv!item.msgBy, false(), true() ) ) } ) } ) ), {a!forEach( items: reverse(todatasubset(reverse(local!data),a!pagingInfo(1,5)).data), expression: a!columnsLayout( columns: { a!columnLayout( contents: { a!textField( value: fv!item.msg, readOnly: true(), showWhen: if( loggedInUser()=fv!item.msgBy, true(), false() ) ) },
), a!columnLayout( contents: { a!textField( align: "RIGHT", value: fv!item.msg, readOnly: true(), showWhen: if( loggedInUser()=fv!item.msgBy, false(), true() ) ) } ) } ) ), a!textField( value: local!msg, saveInto: { local!msg, }, ), a!buttonLayout( primaryButtons: { a!buttonWidget( label: "submit", saveInto: { a!save( local!data, append( local!data, 'type!{urn:com:appian:types:PD}PD_chatDetails'( id: count(local!data)+1 , msg: local!msg, msgBy: loggedInUser(), msgDate: now() ) ) ), a!save(local!msg,null)}, size: "SMALL" ) } )}) } ))
{ a!localVariables( local!recordData: a!queryRecordType( recordType: 'recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment', filters: { a!queryFilter( field: 'recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7839be35-1eac-4fea-bcff-9f65422c281b}caseId', operator: "=", value: ri!caseId ) }, pagingInfo: a!pagingInfo(1, 1), fetchTotalCount: true ), local!totalCount: local!recordData.totalCount, local!batchSize: 4, local!startIndex: if( local!totalCount <= local!batchSize, 1, local!totalCount - if( mod(local!totalCount, local!batchSize) = 0, local!batchSize, mod(local!totalCount, local!batchSize) ) + 1 ), local!pagingInfo: a!pagingInfo( startIndex: local!startIndex, batchSize: local!batchSize ), local!record: a!queryRecordType( recordType: 'recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment', filters: { a!queryFilter( field: 'recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7839be35-1eac-4fea-bcff-9f65422c281b}caseId', operator: "=", value: ri!caseId ) }, pagingInfo: local!pagingInfo ), local!comments: local!record.data, local!caseOwner: a!queryRecordType( recordType: 'recordType!{28dade06-19f7-4add-9a25-12b5a7c5c5a2}AHP Case', filters: { a!queryFilter( field: 'recordType!{28dade06-19f7-4add-9a25-12b5a7c5c5a2}AHP Case.fields.{37f7ef43-b1ae-4978-9c0c-5cd22284e7cf}id', operator: "=", value: ri!caseId ) }, pagingInfo: a!pagingInfo(startIndex: 1, batchSize: 1000) ).data['recordType!{28dade06-19f7-4add-9a25-12b5a7c5c5a2}AHP Case.fields.{a2eae269-4b53-4a29-8e22-4d3087e084ef}caseOwner'], local!addNew: true(), local!newComment, { a!cardLayout( contents: a!sectionLayout( label: "Comments", labelIcon: "comments", divider: "ABOVE", marginAbove: "STANDARD", isCollapsible: true(), contents: a!columnsLayout( columns: { a!columnLayout( contents: { rule!AHP_paginationSection( pagingInfo: local!pagingInfo, totalCount: local!totalCount ), a!cardLayout( showBorder: false(), showShadow: false(), padding: "NONE", contents: { /*Comments in conversation view*/ a!forEach( items: local!comments, expression: a!localVariables( local!fullName: user( username: fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'], property: "firstName" ) & " " & user( username: fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'], property: "lastName" ), local!showProfilePhoto: a!isNotNullOrEmpty( getprofilepictureforuser( fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'] ) ), local!isLoggedInUser: loggedInUser() = fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'], local!isCaseOwner: local!caseOwner = fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'], { a!columnsLayout( columns: { a!columnLayout( width: "EXTRA_NARROW", showWhen: local!isLoggedInUser ), a!columnLayout( contents: { a!cardLayout( contents: { a!sectionLayout( contents: { a!sideBySideLayout( items: { /*a!sideBySideItem(showWhen: local!isLoggedInUser),*/ a!sideBySideItem( item: a!stampField( labelPosition: "COLLAPSED", text: initials(local!fullName), backgroundColor: "SECONDARY", size: "TINY", align: if(local!isLoggedInUser, "END", "START") ), width: "MINIMIZE", showWhen: not(local!showProfilePhoto) ), a!sideBySideItem( item: a!imageField( labelPosition: "COLLAPSED", images: a!userImage( user: fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{46704656-32a1-4ec6-b011-9c98222e9b3e}createdBy'], altText: local!fullName, caption: local!fullName ), size: "TINY", style: "AVATAR", align: if(local!isLoggedInUser, "END", "START") ), width: "MINIMIZE", showWhen: local!showProfilePhoto ), a!sideBySideItem( item: a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextItem( text: concat( local!fullName, if( local!isCaseOwner, " (Case Owner)", "" ) ), /*link: a!userRecordLink(),*/ linkStyle: "STANDALONE", style: "STRONG", /*color: "ACCENT"*/ ), char(10), a!richTextItem( /*text: if(*/ /*tointeger(todatetime(now()) - fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7e212791-306c-4327-8817-dbbe1e67e9ab}createdOn']) < 1,*/ /*todatetime(todatetime(now()) - fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7e212791-306c-4327-8817-dbbe1e67e9ab}createdOn']),*/ /*fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7e212791-306c-4327-8817-dbbe1e67e9ab}createdOn']*/ /*),*/ text: fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{7e212791-306c-4327-8817-dbbe1e67e9ab}createdOn'], /*color: "#ffffff",*/ style: "EMPHASIS" ) } ), width: "MINIMIZE" ) }, alignVertical: "MIDDLE" ) } ), a!textField( labelPosition: "COLLAPSED", value: fv!item['recordType!{59505fbe-4a2d-41cf-b01c-b6b44dce0683}AHP Comment.fields.{17d45582-c2bb-4d6d-8e41-508da99fefae}comment'], readOnly: true, /*align: if(*/ /*local!isLoggedInUser,*/ /*"RIGHT",*/ /*"LEFT"*/ /*)*/ ) }, style: if( local!isLoggedInUser, "#3DA9BE", "#1B478F" ), shape: "ROUNDED", padding: "EVEN_LESS", marginBelow: "STANDARD", showShadow: true ) } ), a!columnLayout( width: "EXTRA_NARROW", showWhen: not(local!isLoggedInUser) ) } ) } ) ) }, height: "AUTO" ), a!sideBySideLayout( items: { /*Comment Box*/ a!sideBySideItem( item: a!textField( placeholder: "Type your comment here...", value: local!newComment, saveInto: local!newComment, refreshAfter: "KEYPRESS", showWhen: local!addNew ) ), /*Save comment button*/ a!sideBySideItem( item: a!richTextDisplayField( value: { a!richTextItem( text: a!richTextIcon(icon: "paper-plane"), link: if( a!isNullOrEmpty(local!newComment), {}, a!startProcessLink( label: "Save", processModel: cons!AHP_PM_CREATE_COMMENT, processParameters: { comment: local!newComment, caseId: ri!caseId } ) ), linkStyle: "STANDALONE", size: "MEDIUM", style: "STRONG" ) }, showWhen: local!addNew, align: "RIGHT" ), width: "MINIMIZE" ) }, alignVertical: "MIDDLE" ) } ) } ) ), shape: "ROUNDED", marginBelow: "STANDARD", showBorder: true(), showShadow: true(), style: "NONE" ) } ) } /* Pagination section code below */ a!sideBySideLayout( items: { a!sideBySideItem(), a!sideBySideItem( item: a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextIcon( icon: "angle-double-left", link: a!dynamicLink( value: 1, saveInto: ri!pagingInfo.startIndex, showWhen: tointeger(ri!pagingInfo.startIndex) <> 1 ), linkStyle: "STANDALONE", color: if( tointeger(ri!pagingInfo.startIndex) = 1, "SECONDARY", "ACCENT" ), size: "MEDIUM_PLUS" ), a!richTextIcon( icon: "angle-left", link: a!dynamicLink( value: tointeger(ri!pagingInfo.startIndex) - tointeger(ri!pagingInfo.batchSize), saveInto: ri!pagingInfo.startIndex, showWhen: tointeger(ri!pagingInfo.startIndex) <> 1 ), linkStyle: "STANDALONE", color: if( tointeger(ri!pagingInfo.startIndex) = 1, "SECONDARY", "ACCENT" ), size: "MEDIUM_PLUS" ) }, showWhen: or(ri!totalCount > 0), align: "RIGHT" ), width: "MINIMIZE" ), a!sideBySideItem( item: a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextItem( text: concat( ri!pagingInfo.startIndex, " - ", if( ri!pagingInfo.startIndex + ri!pagingInfo.batchSize > ri!totalCount, ri!totalCount, ri!pagingInfo.startIndex + ri!pagingInfo.batchSize - 1 ) ), style: "STRONG" ), a!richTextItem(text: concat(" of ", ri!totalCount)), }, showWhen: or(ri!totalCount > 0), align: "RIGHT" ), width: "MINIMIZE" ), a!sideBySideItem( item: a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextIcon( icon: "angle-right", link: a!dynamicLink( value: tointeger(ri!pagingInfo.startIndex) + tointeger(ri!pagingInfo.batchSize), saveInto: ri!pagingInfo.startIndex, showWhen: ( tointeger(ri!pagingInfo.startIndex) + tointeger(ri!pagingInfo.batchSize) ) <= tointeger(ri!totalCount) ), linkStyle: "STANDALONE", color: if( ( tointeger(ri!pagingInfo.startIndex) + tointeger(ri!pagingInfo.batchSize) ) <= tointeger(ri!totalCount), "ACCENT", "SECONDARY" ), size: "MEDIUM_PLUS" ), a!richTextIcon( icon: "angle-double-right", link: a!dynamicLink( value: if( mod( tointeger(ri!totalCount), tointeger(ri!pagingInfo.batchSize) ) > 0, tointeger(ri!totalCount) - mod( tointeger(ri!totalCount), tointeger(ri!pagingInfo.batchSize) ) + 1, tointeger(ri!totalCount) - tointeger(ri!pagingInfo.batchSize) + 1 ), saveInto: ri!pagingInfo.startIndex, showWhen: ( tointeger(ri!pagingInfo.startIndex) + tointeger(ri!pagingInfo.batchSize) ) <= tointeger(ri!totalCount) ), linkStyle: "STANDALONE", color: if( ( tointeger(ri!pagingInfo.startIndex) + tointeger(ri!pagingInfo.batchSize) ) <= tointeger(ri!totalCount), "ACCENT", "SECONDARY" ), size: "MEDIUM_PLUS" ) }, showWhen: or(ri!totalCount > 0), align: "RIGHT" ), width: "MINIMIZE" ), }, alignVertical: "MIDDLE", showWhen: and( or(ri!totalCount > 0), not( or(ri!totalCount <= ri!pagingInfo.batchSize) ) ), spacing: "NONE" )