Open/close modals

HI,

I LOVE the new Modal Content and love to use them in many places. Perfect design :grinning:
What I can’t really find in the documentation is the triggers for the modals. I guess they’re pretty straight forward: clicking on the link triggers the opening of a model with the name that’s present in the data-attributes.
But I’d like to tweak thins a little, with custom code: clicking on a link in modal A results in closing modal A and opening model B.
So how exactly are the modals openend by default?

Note, I already found a workaround, but I always prefer to go the ‘right’ way.

//Opening a modal
$('a.modal-group-create').trigger('click');

//Closing a modal
$('.x-modal-close').trigger('click);

So although this is working, I’d love to hear how the Pro them itself handles opening/closing modals, so I can adjust my code to reflect native behavior. Thanks!

Hi there,

This isn’t fully documented as it’s an internal API and subject to change, but there are two functions available to retrieve and set the state. Here are some code examples:

var isModalOpen = window.xToggleGetState( id );


window.xToggleUpdate( id ); // Flips the state.

window.xToggleUpdate( id, true ); // Forces element open

window.xToggleUpdate( id, false ); // Forces element closed

The id is the value of the data-x-toggleable attribute. This API could potentially be used for other purposes as long as the attributes match between elements that need to synchronize. The ID value itself just comes from the element ID because we already know that’s unique. If you add a custom class, you can retrieve that value with some jQuery like this:

$('.modal-a').attr('data-x-toggleable');

So you may want to try something like this:

jQuery(function($){

  $('a.modal-group-create').on('click',function(){
    window.xToggleUpdate( $('.modal-a').attr('data-x-toggleable'), false ); // Close Modal A
    window.xToggleUpdate( $('.modal-b').attr('data-x-toggleable'), true ); // Open Modal B
  });
  
});

This works for modals, off canvas, and collapse based elements. We built this out to handle state management so the toggle itself can reflect the open/closed state regardless of how it’s triggered. For example, when you click the “x” to close the modal, or click outside the content area, we still need the actual toggle to animate back to the closed position.

Hopefully this helps get you on the right track. It’s unlikely that we’ll ever change those functions, but because they’re internal just remember that we’re not testing them for breaking changes. If you use them you’ll just want to test after each update to make sure it’s still in good order (as with any customization).

2 Likes

Hi Alexander,

thanks so much. That’s EXACTLY what I was looking for (and more)!
This is the kind of support I absolutely love, really appreciated!

Happy to hear that.

Feel free to ask us again.

Thanks.

For further reference, thanks to @Alexander, here’s what I ended up with.
I wanted to have some more flexibility in terms of being able to do all of the following:

  • open a modal with a WordPress menu
  • close that model when a link is clicked and open another modal associated with the link
    The snippet below does exactly that and possibly more. There is a possibility present to detect url parameters from the current window for opening a modal.

Based on formatting custom links in a default WordPress menu (eg: link target ‘?x-toggleable-target=group-create&x-toggleable-closeall=true’). I have left some console.log() statements in the code for demonstration purposes only.
The code could be added directly to the ‘custom JS’ section of Pro.

(function($)
{
  
  
  /***
   * All jQuery stuff (document.ready)
  */
	$(document).ready(function()
  {
    /*
     * Execute the following as soon as the document is ready
    */
    var urlParams = getUrlParams();//Get all parameters of the current window
    console.log(urlParams);
    //@TODO: if you need to open a modal when the document is ready: if(linkParams['x-toggleable-target']){var targetModal = $( '.'+linkParams['x-toggleable-target'] ).attr('data-x-toggleable');window.xToggleUpdate( targetModal, true );}
    
    /*
     * UI Interactions
    */
    $('a[href*="x-toggleable"]').on('click', function(e)
    {
      e.preventDefault();//Prevent default behaviour; following the href destination
      
      var linkParams = getStringParams( $(this).attr('href') );//Get all parameters of the clicked link
      console.log(linkParams);
      
      //If needed, close previously openend modals
      if(linkParams['x-toggleable-closeall'])
      {
      	$('button.x-modal-close').trigger('click');
      }
      
      //If x-toggleable-target is present, find out which modal to open and do so
      if(linkParams['x-toggleable-target'])
      {
      	var targetModal = $( '.'+linkParams['x-toggleable-target'] ).attr('data-x-toggleable');
      	window.xToggleUpdate( targetModal, true );
      }
    });//End a.href=x-toggleable
    
	});//End document ready
  
  /***
   * Get paremeters from the current window's url
   * 
   * @param String prop (optional) - if prop is provided this specific's parameter's value will be returned instead of all properties
   * 
   * @return String|Object - returns a string with the value of 'prop' if 'prop' was set, otherwise returns an Object with all parameters and their values
   */
  function getUrlParams( prop )
  {
      return prop ? getStringParams( window.location.href, prop ) : getStringParams( window.location.href );
  }//End function getUrlParams()
  
  /***
   * Get parameters from a string. Inspired by https://www.kevinleary.net/javascript-get-url-parameters/ .
   * 
   * @param String string (required) - the string to get the parameters from. Parameters should be formatted name=value and seperated by ?.
   * @param String|object prop (optional) - if provided, the given prop's value will be returned instead of an object of all properties 
   *
   * @return String|Object - returns a string with the value of 'prop' if 'prop' was set, otherwise returns an Object with all parameters and their values
   */
  function getStringParams( string, prop )
  {
    var params = {};
    var search = decodeURIComponent( string.slice( string.indexOf( '?' ) + 1 ) );
    var definitions = search.split( '&' );

    definitions.forEach( function( val, key ) 
    {
      var parts = val.split( '=', 2 );
      params[ parts[ 0 ] ] = parts[ 1 ];
    } );
    return ( prop && prop in params ) ? params[ prop ] : params;
  }//End function getStringParams()
  
  /*
   * 
  */
  
})(jQuery);//End jQuery
3 Likes

Thanks for sharing and this going to be very helpful :slight_smile:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.