# Can you conditionally wrap a custom element's slot in a parent element?

**URL:** <https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797>\
**Category:** Help Requests\
**Created:** [August 1, 2019, 4:43pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797 "2019-08-01T16:43:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![zshall](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zshall/32/1577_2.png) [@zshall](https://discourse.aurelia.io/u/zshall)\
**Post date:** [August 1, 2019, 4:43pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/1 "2019-08-01T16:43:24Z")

</div>

When I’m working on a custom element that has a slot, sometimes I’d like to wrap the `slot` in a parent element. For example, in this component the `slot` element is a child of `card-body`:

`card.html`:

```
<template>
    <card-header>
        ${title}
    </card-header>
    <card-body>
        <slot></slot>
    </card-body>
</template>

```

`index.html`:

```
<card title="My Card">
    <h1>Some content</h1>
</card>

```

Now suppose I have a second component that I already use which has its own `card-body` and `card-footer` components:

`my-form.html`:

```
<template>
    <card-body>
        <slot></slot>
    </card-body>
    <card-footer>
        <button>Submit</button>
    </card-footer>
</template>

```

Since `my-form` has a footer, I don’t want to put it inside the `card-body` of `card`. Is there a way to conditionally omit the `card-body` tag in `card.html`? Something like:

```
<card title="My Card" no-body="true">
    <my-form>
        <input /> etc.
    </my-form>
</card>

```

when using the template and:

`card.html`:

```
<template>
    <card-header>
        ${title}
    </card-header>
    <card-body (include this wrapping tag if no-body is false)>
        <slot></slot> (but include this always)
    </card-body>
</template>

```

Thanks for any and all help! (I accidentally submitted the post before I was done writing… it’s complete now)

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [August 1, 2019, 5:19pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/2 "2019-08-01T17:19:28Z")

</div>

Sounds like a conditional containerless or as-element but Im honestly not sure as I rarely use those features. @bigopon this might be one for you.

Oh and btw welcome @zshall 😉

---

<div class="post-metadata">

**Author:** ![arnederuwe](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/arnederuwe/32/737_2.png) [@arnederuwe](https://discourse.aurelia.io/u/arnederuwe)\
**Post date:** [August 2, 2019, 7:02am UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/3 "2019-08-02T07:02:57Z")

</div>

You could do this with `processContent()`  
@bigopon has a good writeup [here](https://discourse.aurelia.io/t/better-know-a-framework-18-what-processcontent-is-and-what-it-is-used-for/1785)  
If you need help, set up your non-working example on codesandbox, post it here, and I will give it a shot this weekend

---

<div class="post-metadata">

**Author:** ![zshall](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zshall/32/1577_2.png) [@zshall](https://discourse.aurelia.io/u/zshall)\
**Post date:** [August 2, 2019, 1:28pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/4 "2019-08-02T13:28:20Z")

</div>

Thanks for the welcome and the recommendations!! I’m reading through @bigopon’s post and the rest of the thread now and will try a few things out. `processContent` is new to me so I’ll take some time to learn it. If I figure it out I’ll post my solution. Otherwise I’ll post the non-working example.

---

<div class="post-metadata">

**Author:** ![zshall](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zshall/32/1577_2.png) [@zshall](https://discourse.aurelia.io/u/zshall)\
**Post date:** [August 2, 2019, 4:28pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/5 "2019-08-02T16:28:54Z")

</div>

I’ve been working at it for the last few hours and am a bit stumped. Here’s what I’ve got so far:

[Code Sandbox link](https://codesandbox.io/s/component-wrapping-0y0s1?fontsize=14&module=%2Fsrc%2Ftab.js)

When I was reading through the thread my first thought would be to remove the `card-body` wrapper (while keeping its children) using the `node` parameter of `processContent`. I imagined that `processContent` would give me the whole custom element in `node` but realized it gives me the `slot` contents only. Calling `node.parentNode` doesn’t seem to work either.

My second idea was to go into the `node` and unwrap the first direct child which is a `card-body` element. This didn’t work since the slot contents aren’t compiled at this point and my `form-base` component uses a nested `card-body` which hasn’t been compiled yet.

Will continue to work on this.

The end result I’m looking for is that when I have `form-base` as a child of `tab`, only one `card-body` element will be used.

Here’s an image that shows what I’m trying to accomplish:

 ![image](https://canada1.discourse-cdn.com/flex027/uploads/aurelia/original/2X/4/4976445d5f995a081dec8fea71493c6926f811f4.png)

There may be other, better ways to deal with this problem that I haven’t thought of yet too.

Thanks for all the help so far 🙂

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [August 4, 2019, 1:24pm UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/6 "2019-08-04T13:24:12Z")

</div>

A small note for your form buttons: you need to clearly define which buttons are able to submit your form, and which are not. Button inside a form will have `type=submit`, which could be very undesirable.  
So it should look like this in your form base:

```auto

  <card-footer>
    <button type=submit>Submit</button>
    <button type=button>Back</button>
  </card-footer>

```

About what you want to achieve, it seems to me if you define `card-body` in each of the element, you should have `card-body`, it’s expected. Maybe change how you compose your tab? Normally I would advise against needlessly creating custom element, in your case, it’s the `<form-base/>`. Aurelia, with its close to bare html characteristic, and many powerful binding should give you an easy time dealing with big big html view, unlike other html in JSS frameworks.

---

<div class="post-metadata">

**Author:** ![khuongduybui](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/khuongduybui/32/44_2.png) [@khuongduybui](https://discourse.aurelia.io/u/khuongduybui)\
**Post date:** [August 5, 2019, 2:27am UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/7 "2019-08-05T02:27:53Z")

</div>

What if you just style it so that card-body’s inside a card-body does not have border?  
Like this: [https://codesandbox.io/s/component-wrapping-x92w0](https://codesandbox.io/s/component-wrapping-x92w0)

---

<div class="post-metadata">

**Author:** ![khuongduybui](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/khuongduybui/32/44_2.png) [@khuongduybui](https://discourse.aurelia.io/u/khuongduybui)\
**Post date:** [August 5, 2019, 2:45am UTC](https://discourse.aurelia.io/t/can-you-conditionally-wrap-a-custom-elements-slot-in-a-parent-element/2797/8 "2019-08-05T02:45:12Z")

</div>

As for actually “conditionally wrap a slot in a parent element”, I hoped we could do it with

```auto
<compose view="card/card-body.html">
    <slot></slot>
</compose>

```

Unfortunately that didn’t work because the content of `<slot>` is rendered into the view BEFORE the content of `<card-body>`.

I also tried

```auto
<section as-element.bind="omitBody ? 'div' : 'card-body'">
    <slot></slot>
</section>

```

and of course that didn’t work either because `as-element` doesn’t seem to be bindable. (`as-element="${...}"` didn’t work either.)
