Friday 23 May 2014

Loading Remote Content into Bootstrap Modal

Another one which puzzled me for a short while after stumbling and bumbling my way through the awesome Bootstrap framework which provides so many useful front-end tools to help develop the user interface, was loading remote content into a bootstrap modal.

On the surface of the system looked very easy: declare a target in the href and of you go (go to http://getbootstrap.com/javascript/#modals for a summary:

<button class="btn btn-primary" data-toggle="modal" data-target="#modaltoopen">open</button>

This will style up a simple link as a medium sized blue button which when clicked will open a modal window if the following code is enclosed in the body:

<div id="modaltoopen" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

<!-- Small modal -->
<button class="btn btn-primary" data-toggle="modal" data-target=".bs-example-modal-sm">Small modal</button>

<div class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>


OK, so good so far (assuming you've also included the bootstrap.js and css files in the same page.

But what if you wanted to pull in a bunch of data, say if you had a loop for a series of records from a database. In our example we have a bug tracking system which looks a little like this:


so that when the blue button is clicked on we can pull in a template page into a modal dialog to let the user see the content of the bug reported, thus:



Remote Content
Supposedly, pulling in a page is an easy process, and to be honest it is but with a few caveats. If you want to access a URL you should just apply an href into the link and this will in turn grab the page and place it into the modal pop-up.

Something like this:

<a  data-toggle="modal" href="loadbug.php?id=<?php echo $ibugid; ?>" data-target="#modeltoopen" class="btn btn-xs btn-info">view info</a>

This works fine, except that identifying the modal popup in the data-target attribute does exactly what it should, it adds the content into the modal pop-up but overwrites everything in the modal:


What this does is effectively grab the content from the remote HTML (or this case PHP) file and replaces the modal content with the HTML. What's wrong with you might ask? Well the problem with this is that we really want to preserve the pretty modal title and close buttons but there doesn't seem to be a real way of dynamically writing this into the script other than performing a hack to the modal.js functionality.

OK so how do we achieve this? You want simple, think simple. If we need to have the modal title and close buttons, do they need to be dynamic? Probably not. In that case why not add them into the remote page which we are calling?

For example the remote HTML from that basic modal looks a little like this:

<p>Bug Reported on {date}</p>
<p>Platform: {app system}</p>
<p>Reported by: {user}</p>
<p>Description:</p>
<p>{details}</p>


but if we wrapped the modal attributes around that we would have:

<div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
       <p>Bug Reported on {date}</p>
<p>Platform: {app system}</p>
<p>Reported by: {user}</p>
<p>Description:</p>
<p>{details}</p>

      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
      </div>
    </div><!-- /.modal-content -->

So ultimately we see that the content we draw into the modal dialog can have the nice features without too much of the hard work!

For more examples of our web development work, drop us a note or get in touch through our website.

SMALL AMEND:

Noticed that once called the modal will keep the first call's data in the modal content div so to get the modal dialog to dump the central body of the remote content each time it's closed, it's best to force a little data removal, thus:

 <script>
 $(function(){
   $('#myModal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
   });
 </script>

All better now!

Sunday 11 May 2014

500 error with osTicket installation on Parallels Plesk panel

We use Parallels Plesk and occasionally have need of some of (generally) useful bundled applications which come with the Linux flavour of Plesk.

One the funky application bundles we've come across is osTicket. a neat little ticketing system provided by the lovely people over at www.osticket.com. This Open Source system seems to tick all the boxes as far as our needs were concerned for an independent project and seemed to be a doddle when reading through the installation of the version we wanted (v1.8.1.2) so we took a look at the local catalogue version which came with Plesk and thought - that'll do us.

The thing about the bundled applications with Plesk is that they do somewhat "take care" of the installation which bugged me a little bit as I wanted to have little more control over the installation.

So of I headed to get the local version of the catalog (APS) application and started the install. (btw this assumes you've set up the subscription into Plesk and have a domain mapped etc)

 
so clicking on the applications tab showed me (after a search for ticket) that is was in fact available (plesk 11.5 shown) so I adopted the "I want control" install option by clicking the small side arrow and choosing install (custom). Then I was presented with a number of dialog screens including one for additional options which allowed me to add in a database I had already created (there's no problem with allowing it to add it for you, I just had one myself)
 
The installation went fine after that until....I tried to browse to the live installation and got the dreaded 500 Server error. Now these errors, with the white page from hell which tells you absolutely nothing about the error which has caused the application to die, you need to open the error log file and see what that tells you.
 
In Plesk the error logs are location in the domain's file system in a logs folder thus:
which are accessible through FTP. Downloading the error log file and opening it in Notepad ++ I saw this:
 

I fixed the error about premature end of script which was some erroneous white space at the end of an include file (not of my doing) and then then focussed on the mod_fcgid warning. This was quite an odd one as it pointed to the FastCGI module not behaving itself. (Having seen these before I've seen the issue fixed with a hosting settings selection so tried it out)
 
In the Plesk Hosting Settings for the domain (Websites & Domains > {domain} > Hosting Settings)

clicking on the hosting settings will let you make any minor configuration changes to the subscription:
 
The thing to try out is changing the FastCGI option back to the CGI application type and then saving this configuration back into the subscription. I've found that normally this doesn't need any server restarts or the like and lo! the change worked - I refreshed the page for the 500 Server Error and the application started behaving as it should.
 
 
 
Hope this helps some other poor soul who has been pulling their hair out trying to configure osTicket - it looks like a top system just installing it can be a total pain!