Adaptive card:Id property in ColumnSet in body to add unique Id associated with the element not giving any custom id, need custom id to change styles at chatbot integrated in website using directline, in html.
Here is the json for adaptive card:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"speak": "Weather forecast for Monday is high of 62 and low of 42 degrees with a 20% chance of rainWinds will be 5 mph from the northeast",
"backgroundImage": "http://messagecardplayground.azurewebsites.net/assets/Mostly%20Cloudy-Background-Dark.jpg",
"body": [
{
"type": "Container",
"id":"customId",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg",
"size": "small",
"style": "person"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Matt Hidinger",
"weight": "bolder",
"wrap": true
},
{
"type": "TextBlock",
"spacing": "none",
"text": "Created {{DATE(2017-02-14T06:08:39Z,SHORT)}}",
"isSubtle": true,
"wrap": true
}
]
}
],
"selectAction": {
"type": "Action.OpenUrl",
"title": "View Sunday",
"url": "http://www.microsoft.com"
}
}
]
}
]
}
Pls suggest what is wrong in above json. What is the way to add custom id in elements so we can style these with css in chatbot integrated in websites using directline.
@saurabhu93 I am sorry but I don't understand your question. What are you trying to accomplish? Your payload renders just fine, and your ColumnSet does have an Id.
@dclaux Can u provide me example plnker with chatbot integrated in custom website using directline with the html elements having custom id.
@saurabhu93 no, sorry, I don't have such an example. Again, can you please explain what you are trying to accomplish, that is the best way to get help.
@dclaux I was looking through the issues and can relate with this one.
When I set the "id" of a "Container" and then render it with the JavaScript rendered to HTML, the .ac-container div for that "Container" does not contain the id property that I specified in my Json.
@dclaux I think what they mean is the following:
The questions derived are:
And of course the other question that transpires:
In general, be it with the HTML renderer or any other renderer we provide, we do not want developers to take a dependency on the generated UI (DOM elements, in this case) because we want to have the freedom to change how the renderer generates said UI in the future without breaking anyone's code.
In this particular case, I don't know if "it doesn't (or won't) hurt" but I have a feeling it will. If the contract becomes that generated DOM nodes have the same Id as the Adaptive element they represent, then obviously some developers will take a dependency on that and also make assumptions as to what how the DOM is built by the renderer, what element types, etc.
There is already a way to accomplish what you want, namely by extending an element class and overriding its internalRender method so as to stamp the element's Id on the generated DOM element. Then de-register the standard element class and register yours instead. E.g. this:
class MyContainer extends Container {
protected internalRender() {
let rendererdElement = super.internalRender();
renderedElement.id = this.id;
return renderedElement;
}
}
I know this is not super convenient, but it is not supposed to be. Lately I've been thinking I could add an onParseElement event handler that would be invoked after any element has been rendered, to facilitate customizations. It would make it a lot simpler to do the above, but that's precisely why I haven't added it (yet, at least.)
The bottom line is, I really don't want to get into the situation where someone starts complaining that the new version of the renderer broke their app because now FactSet doesn't use a <table> anymore.
Forgot to answer the other important question: we won because we have an amazing team and they gave it all :)
@SimonCek we agreed over coffee this morning, that we're good with it.
@saurabhu93 I think this is good and solid background as to why HTML rendering is not guaranteed to use the IDs that appertain to the card object model. There's also [an explanation](
This issue should be good to close, methinks.
where i should put above code ?
thanks
@dclaux hi, came across this thread whilst trying to do something with id's on cards myself. we're building a bot that makes use of these cards and want to build some automated tests with selenium. normally we add id's to make it easier to get at textfields/buttons etc. but dont have a way to do so. I fully appreciate the design decision to not do this, to prevent unwanted depencies on the html structure, but actually, we want the id's to remove our dependcy on the html structure and just get straight to the button via the id. just thought it would be worth posting a different point of view and requirement around the decision you've made.
@liiamjones thanks for this opinion.
To get the best of both worlds, I'm ready to consider adding an onCardObjectRendered event, triggered after any and all card objects (elements and actions) are rendered. This would give you the opportunity to easily set the DOM element's id to be the same as the card object's id, but without that behavior being built-in. To be clear, the only thing you'd have to write would be something like this:
myCard.onCardObjectRendered = (sender: CardObject) => {
if (sender.renderedElement) {
sender.renderedElement.id = sender.id;
}
}
Sound reasonable?
@dclaux would this translate to other (non-HTML) hosts too? Let's keep the API consistent if possible.
@ignacionr we're discussing a very HTML-centric issue here. Not all frameworks have a DOM equivalent and even those that do won't necessarily have an equivalent Id property.
What I am proposing (to consider) is for HTML/JS only and is merely an easier way to do what is technically already possible. The desired result can be achieved by either:
I'm not proposing a feature for all renderers to support (although that is certainly not out of the question.) Aside from this thread, I don't see evidence that this feature is required for non-HTML renderers.
@dclaux thanks very much for your quick reply. I missed out a key bit of information from my post that i now understand was quite important. I didn't fully understand the scope of AdaptiveCards. We're specifically using these cards with the bot framework in Microsoft Teams. we are able to use selenium via Teams in the browser (teams.microsoft.com) for most things as most of them have id's.
Unfortunately, the inputs and buttons on the adaptive cards don't. so it's really hard to get at them.
I don't think i'd have anywhere other than the card schema to add an id. I've got no other extension points.
Having just said that, im not sure if we could put that js straight into a selenium test, i guess i wouldn't have a reference to the card in the first instance (myCard in your example)
https://github.com/microsoft/AdaptiveCards/issues/1326#issuecomment-559169635
@dclaux Any progress on this?
I would also like to use AdaptiveCards(in js only) but the only thing which is stopping me is the ability to manually set/retrieve the id of elements.
why the adaptive card id is not assigning to HTML element.
I am using webchat js v4.
if i need to assign the id to html where i should do that?
Most helpful comment
In general, be it with the HTML renderer or any other renderer we provide, we do not want developers to take a dependency on the generated UI (DOM elements, in this case) because we want to have the freedom to change how the renderer generates said UI in the future without breaking anyone's code.
In this particular case, I don't know if "it doesn't (or won't) hurt" but I have a feeling it will. If the contract becomes that generated DOM nodes have the same Id as the Adaptive element they represent, then obviously some developers will take a dependency on that and also make assumptions as to what how the DOM is built by the renderer, what element types, etc.
There is already a way to accomplish what you want, namely by extending an element class and overriding its internalRender method so as to stamp the element's Id on the generated DOM element. Then de-register the standard element class and register yours instead. E.g. this:
I know this is not super convenient, but it is not supposed to be. Lately I've been thinking I could add an onParseElement event handler that would be invoked after any element has been rendered, to facilitate customizations. It would make it a lot simpler to do the above, but that's precisely why I haven't added it (yet, at least.)
The bottom line is, I really don't want to get into the situation where someone starts complaining that the new version of the renderer broke their app because now FactSet doesn't use a
<table>anymore.