I'm using "microsoft bot builder" library to build a bot in c#.
I have a card that contains an AdaptiveSubmitAction button which will present a new card on click.
I want to disable the submit button once its activated.. how would that be possible?
This is a part of my code:
////// Submit and Finish button ///////
card.Body.Add(new AdaptiveColumnSet()
{
Columns = new List<AdaptiveColumn>()
{
new AdaptiveColumn()
{
Width = "auto",
Items = new List<AdaptiveElement>()
{
new AdaptiveActionSet()
{
Actions = new List<AdaptiveAction>()
{
new AdaptiveSubmitAction()
{
Title = "Submit",
Id = "Submit",
//from the data you can trigger actions
//e.g.:
Data = new {isDone = false, deleteCrit = false}
},
}
}
}
},
new AdaptiveColumn()
{
Width = "auto",
Items = new List<AdaptiveElement>()
{
new AdaptiveActionSet()
{
Actions = new List<AdaptiveAction>()
{
new AdaptiveSubmitAction()
{
Title = "End",
Id = "Finished",
Data = new {isDone = true, deleteCrit = false}
}
}
}
}
},
}
});
Any help is appreciated!
What you're asking for is impossible because neither Adaptive Cards nor Teams has a concept of a double click when it comes to submit actions. If you were using Web Chat then you might be able to build a custom solution but Teams does not allow for that kind of customizability. If you need a submit action to function in multiple possible ways then I recommend using two different submit actions instead.
You can send feedback to Teams through the Teams app directly or you can submit feature requests in the Teams docs repo or the Adaptive Cards repo.
Yes this should be possible, I believe you can update the Adaptive card view after the first click with only change in view being that the button will be in disabled view. Not only this you can make any change in the card and it will retroactively refresh the view of that card ID. For usage, see context.updateactivity and it's implementation details.
Related
I'm having an issue where buttons and actions in ms teams adaptive cards won’t wrap text inside the action button. The button UI is completely broken even if we are applied " full: width" in MS Team. I know the "Wrap: true || false" we can add inside the adaptive card body or title of the textblock, Is there any other way to handle this type of scenario in the action button title in MS Team channel.
The following code we are using for the adaptive card implementation.
public static Attachment ChoiceMenu(string channelType, string text, List buttons, string subCategory = null)
{
var menuCard = new AdaptiveCard("1.2");
if(!string.IsNullOrEmpty(subCategory))
{
menuCard.Body.Add(new AdaptiveTextBlock()
{
Text = subCategory,
Size = AdaptiveTextSize.Large,
Wrap = true,
});
}
menuCard.Body.Add(new AdaptiveTextBlock()
{
Text = text,
Wrap = true,
});
foreach (var button in buttons)
{
var columns = new AdaptiveColumnSet();
menuCard.Body.Add(columns);
var userCategory = new AdaptiveColumn();
columns.Columns.Add(userCategory);
var actionType = new AdaptiveActionSet();
userCategory.Items.Add(actionType);
var submitAction = new AdaptiveSubmitAction()
{
Title = button,
Id = button
};
if (channelType == Channels.Msteams)
{
submitAction.Data = new AdaptiveCardDataObjectForTeams()
{
MsTeams = new MsTeamsObject()
{
Type = ActionTypes.MessageBack,
DisplayText = button,
Text = button
}
};
}
else
{
submitAction.Data = button;
}
actionType.Actions.Add(submitAction);
}
return new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = menuCard
};
}
Platform
Web ( MsTeams Web http://teams.microsoft.com ) Microsoft Teams
Version 1.4.00.32771 (64-bit). It was last updated on 12/15/2021.
Adaptive Card Version
1.2
As per the Format cards in Microsoft Teams docs,
Cards support formatting in the text property only, not in the title
or subtitle properties.
Note: The Action Button text is in the title property, This is the reason we cannot do any formatting for it. So there is no way to wrap text in the Action Button.
Alternate Solution:
We have changed the MS Team title of the button using the substring concatenation, hereafter the particular character will display "...", So this way we can alternatively fix this issue.
submitAction.Title = button.Length > 50 ? string.Concat(button.Substring(0, 50), "...") : button;
Output:
Reference:
Github discussion
Apart from using full width property in Adaptive card, there doesn't seem to be any way to increase the size of actionable buttons in adaptive card in order to fit the text/title properly.
"msteams": {
"width": "Full"
}
How can I create an inline keyboard with several buttons, one per row?
like:
inlineBtn1
inlineBtn2
inlineBtn3
...
not:
inlineBtn1 inlineBtn2 inlineBtn3 ...
I Solved it
await bot.SendTextMessageAsync(e.Message.Chat.Id, "test", replyMarkup: new InlineKeyboardMarkup(
new InlineKeyboardButton[][]
{
new [] { new InlineKeyboardButton() { Text = "btn 1",CallbackData="Some data1" } }, // buttons in row 1
new [] { new InlineKeyboardButton() { Text = "btn 2", CallbackData = "Some data2" } }, // buttons in row 2
new [] { new InlineKeyboardButton() {Text = "btn 3", CallbackData = "Some data3" } }// buttons in row 3
}));
We must use exactly one of the optional fields.
So you have to pass either url, callback_data or switch_inline_query The button would be useless if you don't pass any of those fields.
To send a message to a chat with an inline keyboard use the replyMarkup parameter of TelegramBot.SendMessage or TelegramBot.SendMessageAsync method. It can be either ReplyKeyboardMarkup or InlineKeyboardMarkup. A constructor of InlineKeyboardMarkup accepts an array of button rows (each of them, in turn, comprises an array of buttons in the given row). To create an inline keyboard with several buttons one per row pass an array with several rows with one element each:
TelegramBot bot = ...;
Chat chat = ...;
await bot.SendMessageAsync(chat.Id, "A message. Use the keyboard below.",
replyMarkup: new InlineKeyboardMarkup(
new InlineKeyboardButton[][]
{
new [] { new InlineKeyboardButton("inlineBtn1") }, // buttons in row 1
new [] { new InlineKeyboardButton("inlineBtn2") }, // buttons in row 2
new [] { new InlineKeyboardButton("inlineBtn3") } // buttons in row 3
}));
The message should look like this:
I have a series of RadioGroups with two options (Radios) 'Yes' and 'No'. I would like to make the RadioGroup required such that one of the options need to be selected.
I can set the required property of each Radio to 'true' but then both must be selected.
How do I achieve this using the DocuSign Api?
---- EDIT
This appears only to be possible using the form designer. The API appears unable to handle this requirement currently.
I've used the designer to create a template and I'm able to achieve making a radio group required with needing to pre-fill an option (which results in a poor user experience and a high chance of inaccurate data).
RadioGroupTabs = new List<RadioGroup>
{
new RadioGroup
{
DocumentId = "1",
RecipientId = "1",
GroupName = "InvestedInEISFundBefore",
RequireAll = "true",
Shared = "true",
Radios = new List<Radio>
{
new Radio
{
PageNumber = "7",
XPosition = "490",
YPosition = "277",
TabOrder = "17",
Value = "Yes"
},
new Radio
{
PageNumber = "7",
XPosition = "480",
YPosition = "277",
TabOrder = "18",
Value = "No"
}
}
}
}
I think what you want is to use the Select = true; in one and Selected = false in the other. The radioGroup automatically has logic to require exactly one radio button to be selected (thus it's not a checkbox, but a radio button!) so all you have to decide is how is the default state when the user just opens the envelope. Hope this makes sense.
I am creating a bot using bot application.I want to call another method when tapping the card.I couldn't call another method within the tap property in receipt card.
Can anyone help me in calling a method within tap property?
If you check the ReceiptCard class, you can find it enable us to specify CardAction for Tap property.
//
// Summary:
// This action will be activated when user taps on the card
[JsonProperty(PropertyName = "tap")]
public CardAction Tap { get; set; }
I couldn't call another method within the tap property in receipt card.
As far as I know, we can not call and execute user defined methods directly via ReceiptCard Tap property. If you want retrieve and display further details after user click on the card, you can try to send back message to bot via a postBack (or imBack) CardAction and then retrieve more detailed information based on postback value. The following sample is for your reference.
CardAction pbv = new CardAction()
{
Value = "postbackval-category-C1",
Type = "imBack",
Title = "image Page"
};
ReceiptCard plCard = new ReceiptCard()
{
Title = "Receipt Card",
Items = receiptList,
Total = "112.77",
Tax = "27.52",
Tap = pbv
};
if (activity.Text.StartsWith("postbackval"))
{
string category = activity.Text.Split('-')[2].ToString();
//retriveve more details based on postback value
}
else
{
//do other operations
}
I create a desktop app c# where i use some references :
using Microsoft.Toolkit.Uwp.Notifications;
using System.Windows;
using Windows.ApplicationModel.Activation;
using Microsoft.QueryStringDotNET;
And where i added some reference related to UWP application :
- Windows.System
- Windows.UI
- Windows.data
- Windows.Foundation
- Windows.ApplicationModel
Then i created a simple procedure to create and show my toast notification with the followin code :
private void Button_Click(object sender, RoutedEventArgs e)
{
var toastContent = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = "Surface Launch Party"
},
new AdaptiveText()
{
Text = "Studio S / Ballroom"
},
new AdaptiveText()
{
Text = "4:00 PM, 10/26/2015"
}
}
}
},
Actions = new ToastActionsCustom()
{
Inputs =
{
new ToastSelectionBox("status")
{
DefaultSelectionBoxItemId = "yes",
Items =
{
new ToastSelectionBoxItem("yes", "Going"),
new ToastSelectionBoxItem("maybe", "Maybe"),
new ToastSelectionBoxItem("no", "Decline")
}
}
},
Buttons =
{
new ToastButton("RSVP", "action=rsvpEvent&eventId=63851")
{
ActivationType = ToastActivationType.Foreground
},
new ToastButtonDismiss()
}
},
Launch = "action=viewEvent&eventId=63851"
};
Windows.Data.Xml.Dom.XmlDocument xmldoc = new Windows.Data.Xml.Dom.XmlDocument();
xmldoc.LoadXml(toastContent.GetContent());
var toast = new ToastNotification(xmldoc);
toast.Activated += OnActivated1;
// Create the toast notification
//var toastNotif = new ToastNotification(xmlDoc);
// And send the notification
ToastNotificationManager.CreateToastNotifier("Test").Show(toast);
Now my problem is that i don't know how to retrieve the item i selected in the list :-(
I created an procedure based toast.Activated event :
void OnActivated1(ToastNotification sender, object e)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
}
With this event, i can retrieve the argument (to know the button i clicked on) but getting the UserInput thanks to the class "ToastNotificationActivatedEventArgs" seems to be not possible...
Do you know if it's possible ? Is it a limitation of using reference UWP in a desktop app ?
Thank you very much !
Vincent
If you're building a Win32 Desktop app using the Desktop Bridge, you currently cannot use inputs and selection boxes in your toast, as there's no way to retrieve the input.
If you're building a normal Win32 app, you must set up a COM server to handle activation, which will include the inputs that the user selected. This quickstart explains how to set this up for normal Win32 apps. Plus, this will also allow your toasts to persist in Action Center, so if the user missed the popup, they can still access your toast from Action Center.
thank you for your answers.
The issue i have with my sub OnActivated :
void OnActivated1(ToastNotification sender, object e)
{
var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
}
is that the "e" object is recocgnized as a Windows.UI.Notifications.ToastActivatedEventsArgs and not as "ToastNotificationActivatedEventArgs" from Windows.ApplicationModel.Activation (where the properties Kind, UserInput.. should be very useful for me to get the content of selected item).
In my OnActivated1 sub, the var toastActivationArgs value equals to null because it cannot be converted to ToastNotificationActivatedEventArgs.
During my test the e.arguments equals to string "action=rsvpEvent&eventId=63851" but there is no XML returned. This is the only property available of the object e. (but this is useful to get the button where i clicked on)
I'm going to check the link from Andrew Bares to try to setup a COM server but i can see that's in c++ language..
Thank you !
The ToastNotificationActivatedEventArgs e.Arguments should be an xml string with what you need ready to parse.
First look at the string and see if it has what you need. Then go about using XMLReader or something to parse it.
Could you post the string you get?