Swipeout on card in accordion

I have 9 accordions. Each accordion can have anything from ZERO cards to X cards. I want to allow a swipeout on each card.

So far this is what I have but I get nothing

<div class="list accordion-list">
    <ul>
        <!-- originally had the swipeout in this li but it deleted the entire accordion -->
        <li class="accordion-item">
            <a href="" class="item-link item-content">
                <div class="item-inner">
                    <span id="kill_count" class="card-count">1</span>
                    <div class="item-title">Murders</div>
                </div>
            </a>
             <!-- I also tried the swipeout on the following div -->
            <div class="accordion-item-content">
              <span class="swipeout" data-comment="this does nothing">
              <a href="/message/13/" class="item-link">
              <div class="card alert-read">
                <div class="card-content card-content-padding">
                  <span class="alert-title">Murder</span>
                  <span class="kill-location">On a Train</span>
                  <span><br>Sat Nov 9 2019 09:23:51</span>
                </div>
              </div>
              </a>                
              <div class="swipeout-actions-right">
                <a href="#" data-confirm="Are you sure you want to delete this item?" class="swipeout-delete swipeout-overswipe">Delete</a>
              </div>
              </span>
            </div>
        </li>

Here you can try this:

<div class="list accordion-list">
<ul>
    <!-- originally had the swipeout in this li but it deleted the entire accordion -->
    <li class="accordion-item">
        <a href="" class="item-link item-content">
            <div class="item-inner">
                <span id="kill_count" class="card-count">1</span>
                <div class="item-title">Murders</div>
            </div>
        </a>
         <!-- I also tried the swipeout on the following div -->
        <div class="accordion-item-content">
        	<ul>
				<li class="swipeout">
					<div class="item-content swipeout-content">
						<div class="item-inner">
							<div class="item-title-row">
								<div class="item-title">...</div>
								<div class="item-after">...</div>
							</div>
							<div class="item-text">...</div>
						</div>
					</div>
					<div class="swipeout-actions-right">
						<a href="#" class="swipeout-delete">Delete</a>
					</div>
				</li>
			</ul>
        </div>
    </li>
</ul>
</div>

I didnā€™t customize the swipeout card. You can configure it as it suits your needs.

If youā€™re getting the cards dynamically, I suggest you to use Template7 (https://idangero.us/template7/) another great library from Vladimir.

1 Like

Thanks Nathanā€¦ Iā€™ll try this now.

When you say getting the cards dynamically, I do pull the card data from an IndexedDB and build the cards on page load. I may have to circle back on template7 as I have my plate full just trying to port this over from JQM.

A friend of mine over at AppStudio wrote a conversion program to convert JQM to Bootstrap4 but I think I want to stay with F7. @nolimits4web has done a really nice job on it!

Update: @NathanHarold - that worked wonderfully! (Iā€™m guessing that the default css resets all of the core elements to {}.) Is there a way to update the chevron? If I delete the last element the chevron still shows as expanded (up ^) when, as empty, it should point down.

If youā€™re using the above-mentioned example, then you can try this code, if not just adjust the class names:

// Run the function when a card gets deleted
//
$$('.accordion-item-content .swipeout').on('swipeout:deleted', () => {
    // Check if all the cards deleted or not
    //
    if (  $$('.accordion-item-content .swipeout').length - 1 === 0  ) {
        console.log( 'Let the magic begins!' )
    }
});

The code above will run whenever the delete event occurs. We are adding -1 since when the code runs the card didnā€™t removed from the DOM yet.

After, all items removed/deleted you can select the chevron like this and do your magic:
$$( '.item-inner::before' ).hide()

Though, you should consider adding an additional class next to the ā€˜item-innerā€™ and target that one to avoid any confusion.

1 Like

Thanks @NathanHarold - Iā€™m part way there!

Hereā€™s what I have so far:

    <div class="list accordion-list">
        <ul>
            <li class="accordion-item">
                <a href="" class="item-link item-content">
                    <div class="item-inner nineoneone">
                        <span id="nine_count" class="alert-count">0</span>
                        <div class="item-title">Murders</div>
                    </div>
                </a>
                <div class="accordion-item-content">
                  <ul>
                    <li class="swipeout">
                      <a href="/message/13/" class="item-link" id="13">
                      <div class="card alert-read">
                        <div class="card-content card-content-padding">
                          <span class="alert-title">Murder</span>
                          <span class="alert-location">On A Train</span>
                          <span><br>Sat Nov 9 2019 09:23:51</span>
                        </div>
                      </div>
                      </a>
                      <div class="swipeout-actions-right">
                        <a href="#" data-confirm="Are you sure you want to delete this item?" class="swipeout-delete swipeout-overswipe">Delete</a>
                      </div>
                    </li>
                  </ul>                
                </div>
            </li>
        </ul>
    </div>

And the javascript (this IS getting called during the pageinit):

$$(document).on('page:init', '.page[data-name="test"]', function (e, page) {
    $$('.accordion-item-content .swipeout').on('swipeout:deleted', () => {    
        console.log( 'checking accordion length' )

        // Check if all the cards are deleted or not
        if (  $$('.accordion-item-content .swipeout').length - 1 === 0  ) {    
            console.log( 'Let the magic begin!' )
            // the following line is not working (with or without the nineoneone class)
            $$( '.nineoneone .item-inner::before' ).hide();
        } 
    });    
});

The problem is in the last line of javascript code where weā€™re calling the .hide(). Nothing happens. Even without the nineoneone class.

Is there a way to get the id of the card where this was called?

.on('swipeout:deleted', () => {}

Typically I would do a this.id but in this code, Iā€™m not sure where to put the id=ā€˜13ā€™ because Iā€™m not real sure what element family ā€˜thisā€™ belongs to so for now I put it at the end of the a tag.

Again, thanks for all your help.

I donā€™t know what was I thinking! The ā€˜:beforeā€™ selector cannot be accessible/manipulated by JS since itā€™s not actually part of the DOM. What you can do is add a class to ā€˜.nineoneoneā€™, select the :before of that very class and add ā€˜display: noneā€™ in your CSS. Like this:

$$('.accordion-item-content .swipeout').on('swipeout:deleted', () => {
	if (  $$('.accordion-item-content .swipeout').length - 1 === 0  ) {
		$$(  '.nineoneone'  ).addClass( 'all-cards-removed' )
	}
});

For the CSS part:

.all-cards-removed:before {
    display: none !important;
}

You can access the deleted item, just pass a parameter in your function, if you would like to access to the anchor tags ID:

$$('.accordion-item-content .swipeout').on('swipeout:deleted', ( item ) => {
    console.log( item )
	let deletedId = item.srcElement.children[0].id
	console.log( deletedId )

	if ( $$('.accordion-item-content .swipeout').length - 1 === 0 ) {
		$$( '.nineoneone' ).addClass('all-cards-removed')
	}
});

The above-mentioned code will work only if the anchor tag is the first child of the deleted item, if you change the order, just dump the item to the console and look at the path youā€™re trying to find.

// Keep in mind that, you should optimize this code, if you try to add another accordion item, this code will not work since the total ā€˜swipeoutā€™ length wonā€™t be equal to 0 until all the cards in all of the accordions deleted.

(That was funny about the ::before - I stared at that several times and was thinking "I bet he means ā€˜parentā€™ but maybe he knows something I donā€™t! LOL)

The ā€œdisplay: noneā€ just removes the accordion vs collapsing itā€¦ that would get too confusing for my users (we tried it in an earlier release and it was NOT popular and people bombarded our help desk thinking they had been unsubscribed from that category).

Just removing the class ā€˜accordion-item-openedā€™ does nothing. Iā€™ve found ā€˜app.accordion.close(el)ā€™ so I need to try to implement that so let me play there for a bit and see what I can come up with.

In Jquery Mobile there was .enhanceWithin(); which would redraw the specified control (whether it be a navbar or button or whatever). Is there a similar function in F7?

UPDATE: The following will close the accordion:

<div class="list accordion-list">
        <ul>
            <li class="accordion-item">
                <a href="" class="item-link item-content nineoneone">
                    <div class="item-inner">
                        <span id="nine_count" class="alert-count">0</span>
                        <div class="item-title">Murders</div>
                    </div>
                </a>
               [snip]

And the javascript:

app.accordion.close( $$('.nineoneone').parent() );

As does this:

 app.accordion.close( $$('.accordion-item-opened') );
1 Like