Cards

For information about cards please refer to Bootstrap's documentation.

Options

Inside .card-header you can have one or more .card-toolbars:

html
<div class="card-header">
 <h5 class="card-title"> ... </h5>

 <div class="card-toolbar">
   <button type="button" class="btn btn-info">Button</button>
 </div>
</div>
  • It can also be .card-header-lg and .card-header-sm for larger and smaller sizes.
  • Add .no-border to .card-toolbar to hide the separator line.

Progressbar

The progress bar in the "Big Header with Progress" card is a custom DIV with a CSS animation that you can see in: views/pages/cards/@page-style.css

Toolbar action buttons

You can add data-action attribute to a button inside card toolbar for following actions:

  • toggle hides/shows .card-body
  • expand makes the .card fullscreen
  • reload sends a .reload.ace.widget event to the .card and display an overlay. You should later call stopLoading to remove the overlay.
  • close closes (and removes) the .card
html
<div class="card-toolbar">
  <a href="#" data-action="close" class="card-toolbar-btn text-danger-m1">
    <i class="fa fa-times"></i>
  </a>
</div>

.card-toolbar-btn adds some styling to the button.

For toggle button you can have an -up or -down icon which will be flipped or you can use dynamic styles to show/hide icons:

html
<div class="card-toolbar">
  <a href="#" data-action="toggle" class="d-style card-toolbar-btn text-grey">
    <i class="fa fa-minus d-n-collapsed"></i><!-- displayed this when NOT collapsed -->
    <i class="fa fa-plus d-collapsed"></i><!-- displayed this when collapsed -->
  </a>
</div>

Same is true for expand button:

html
<div class="card-toolbar">
  <a href="#" data-action="expand" class="d-style card-toolbar-btn text-orange">
    <i class="fa fa-expand d-n-active"></i><!-- displayed this when NOT active (not fullscreen) -->
    <i class="fa fa-compress d-active"></i><!-- displayed this when active (fullscreen) -->
  </a>
</div>

Functions

toggle

Toggles the widget

toggleFast

Toggles the widget without animation

show

Shows the widget

showFast

Shows the widget without animation

hide

Hides the widget

hideFast

Hides the widget without animation

close

Closest and removes the widget

closeFast

Removes the widget without animation

expand

Expands the widget to become fullscreen

expandFast

Expands the widget without animation

restore

Restores the widget

restoreFast

Restores the widget without animation

startLoading

Display a blocking layer over widget and it will be displayed until you call stopLoading:

js
// User wants to reload widget data, etc
$('#my-widget').aceWidget('startLoading')//or $('#my-widget').aceWidget('startLoading', 'Custom loading text or html')

//then load data
...
...
//when data is ready
$('#my-widget').aceWidget('stopLoading')

Events

hide.ace.widget

Triggered when widget body is to be collapsed

hidden.ace.widget

Triggered after widget body is collapsed

show.ace.widget

Triggered when widget body is to be shown

shown.ace.widget

Triggered after widget body is shown

close.ace.widget

Triggered when widget is to be closed and removed

closed.ace.widget

Triggered after widget is closed and removed

expand.ace.widget

Triggered when widget is to be expanded

expanded.ace.widget

Triggered after widget is expanded

restore.ace.widget

Triggered when widget is to be restored

restored.ace.widget

Triggered after widget is restored

reload.ace.widget

Triggered when widget is to be reloaded


js
$('#card-1').on('hide.ace.widget', function(e) {
  e.preventDefault()
}).on('expanded.ace.widget', function(e) {
  //do something
})
js
$('#card-1').on('hide.ace.widget', function(e) {
  e.preventDefault()
}).on('expanded.ace.widget', function(e) {
  //do something
})

Drag & Drop

SortableJS plugin is used to enable drag and drop in Widgets page.
First of all we assign an optional .cards-container class to each .col-* or element that contains .card elements:

html
<div class="col-12 col-sm-6 cards-container">
  <div class="card">
     ...
  </div>

  <div class="card">
     ...
  </div>
</div>

You should also assign an ID attribute to both .cards-container and .cards elements so they can be saved/restore to storage.
In this demo I do that in Javascript.

js
// assign an ID to containers & cards to easily save/restore data to localStorage
$('.cards-container')
.each(function(index) {
  this.setAttribute('id', 'card-container-' + (index+1))
})

$('.card')
.each(function(index) {
  this.setAttribute('id', 'card-' + (index+1))
})

// enable sortable plugin for each container
$('.cards-container').each(function() {
  Sortable.create(this, {
    // give them a common name, so `.card` elements can be drag & dropped between different `.cards-containers`
    group: 'mycards',

    draggable: '> .card',// we are interested in dragging/sorting `.card` elements that are direct children of `.cards-container` elements
    animation: 200,
    
    ghostClass: 'brc-grey-m1',
    chosenClass: '',
    dragClass: 'bgc-yellow-m3',// the highlight

    // maybe in touch devices, only allow dragging for .card-header
    handle: ('ontouchstart' in window ? '.card-header' : null),

    onEnd: function (evt) {
      // when a drag & drop has ended

      // first get our previously saved `containers` data
      var containers = _getData('card-containers')

      // clear our `from` and `to` card-containers (i.e set to empty array)
      containers[evt.to.id] = []
      containers[evt.from.id] = []

      // now find all the `.card` children and add them to the the relevant .cards-container array
      $('#' + evt.to.id)
      .find('> .card')
      .each(function() {
          containers[evt.to.id].push(this.id)
      })

      $('#' + evt.from.id)
      .find('> .card')
      .each(function() {
          containers[evt.from.id].push(this.id)
      })

      // now save them back again
      _saveData('card-containers', containers);
    }
  })
})

Saving/Restoring Positions & States

Using local storage you can easily save and restore the position and state of cards.
As you saw in the above example, we update the order of .card elements in onEnd function.
Later on page load we can restore the order like this:

js
// load are previously saved data (using _saveData in above)
var containers = _getData('card-containers')
for(var containerId in containers) {

   // retrieve the array containting ".card" IDs in a container
   var cards = containers[containerId]

   // a reference to the container
   var containerEl = document.getElementById(containerId)
   if (!containerEl) continue

   // add each card to the container
   for(var i = 0; i < cards.length; i++) {
    var card = document.getElementById(cards[i])
    if (card) {
      containerEl.appendChild( card )
    }    
   }//for
  
}//for

You can do the same thing for saving/restoring card states such as collapsed, closed, etc.
See views/pages/cards/@page-script.js for more details.

Note that, dynamically restoring cards' positions and states on page load my not look pleasing.
You can hide the entire cards area, restore positions and states and then show the cards area again:

html
<div id="cards-area" class="invisible">
  <!-- cards and containers here -->
</div>
js
// restoring positions and states
// when finished
$('#cards-area').removeClass('invisible')

However this is not needed if you do that on the server side

The above _saveData and _getData are simple functions defined in views/pages/cards/@page-script.js for easier reading from and writing to localStorage