Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Wednesday, March 1, 2017

Prevent Ionic Header from Auto-Scrolling Content to Top when Header is Tapped

An interesting piece of functionality in Ionic that only became aware of today is "tap-scroll" which auto-scrolls to the top of the screen when the header/title of the view is tapped. This only seems to work in iOS and caused some strange behavior in a view that had some custom scrolling related javascript code. This led me to look for ways to disable this cleanly. It turns out there is an attribute available on ion-header-bar called "no-tap-scroll" that can disable this behavior when set to "true".

Take a look at ionic.bundle.js and you'll see this defined for ion-header-bar.


When setting no-tap-scroll="true" on the ion-header-bar element, you'll be able to disable this auto-scroll to top functionality, which I think is rather unexpected behavior.

Wednesday, July 6, 2016

Creating a PDF on the fly with Ionic/Cordova

So you've got an Ionic app and you need to create PDFs from within the app. You don't want to offload to a server for PDF generation/download because the PDF is user specific and unique each time it is generated, so why not just generated it client side? For one, that was near impossible a number of years ago. Two, you've tried before and it just never worked right. Well, I managed to get PDF generation in an Ionic app and wanted to share my experience so you can do the same.

What we are going to do is capture a portion of the HTML, turn it into a PDF, and trigger the download for the user.

The first step is to add the required libraries:
Cordova Plugins:
"cordova-plugin-file-transfer"
"cordova-plugin-file-opener2"

index.html (install via bower or point to CDN):
<script src="lib/jspdf/dist/jspdf.min.js"></script>
<script src="lib/html2canvas/dist/html2canvas.js"></script>

Next, we create the PDF generation function:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
$scope.generatePDF = function (method) {

       //set the margins for the PDF
 var margins = {
  top: 40,
  left: 40
 };

        // function to create a hidden clone of the target element,
        // allowing manipulation specific for the PDF output without changing the actual target element.
 var hiddenClone = function (element) {
  document.documentElement.style.overflow = 'visible';
  document.body.style.overflow = 'visible';

  // Create clone of element
  var clone = element.cloneNode(true);

  // Position element relatively within the
  // body but still out of the viewport
  var style = clone.style;
  style.position = 'relative';
  style.top = window.innerHeight + 'px';
  style.left = 0;
  style.width = '535px';
  style.zIndex = '9999';

  // Append clone to body and return the clone
  document.body.appendChild(clone);
  return clone;
 }

        // now create the clone of your target element and send it to html2canvas
 var html2Pdf = hiddenClone(document.getElementById('pdfTarget'));
 html2canvas(html2Pdf, {
  onrendered: function (canvas) {
                        // once the canvas is rendered, create new jsPDF object and working variables
   var doc = new jsPDF('p', 'pt', 'letter');
   var dataUrl = canvas.toDataURL('image/jpeg');

   doc.addImage(dataUrl, margins.top, margins.left, canvas.width, canvas.height);
   var dataUrlPdf = doc.output();
   var dataUrlPdfBase64 = 'data:application/pdf;base64,' + btoa(dataUrlPdf);

                        // once we've got the canvas, we can remove the clone element and reset styles
   document.body.removeChild(html2Pdf);
   document.documentElement.style.overflow = 'hidden';
   document.body.style.overflow = 'hidden';

   var filename = 'PDF-' + $filter('date')(new Date(), 'yyyy-M-d') + '.pdf';

   // Save location
   var targetPath = cordova.file.externalRootDirectory + filename;

                        // use the cordova file transfer plugin to send the file to the cordova file opener plugin,
                        // allowing user to pick download method (only seems to work on Android)
   $cordovaFileTransfer.download(dataUrlPdfBase64, targetPath, {}, true).then(function (fileEntry) {
    console.log('Success');
    console.log(fileEntry);
    fileEntry.file(function (file) {
     cordova.plugins.fileOpener2.open(
      file.localURL,
      file.type, {
       error: function (e) {
        console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
       },
       success: function () {
        console.log('file opened successfully');
       }
      }
     );
    });
   }, function (error) {
    console.log('Error');
    console.log(error);
   }, function (progress) {
    // PROGRESS HANDLING GOES HERE
   });
  }
 });
};

Now you can run the function and try it out...
Hopefully you'll have successful client side PDF generation from HTML. I will say these plugins/libraries are touchy, especially when used together but this formula worked for me. Best of luck and feel free to share your implementations and feedback!

Friday, July 3, 2015

How To: Minify JS and CSS with ColdFusion

If you're reading this post, I can assume two things.
  1. You're running ColdFusion and need to minify JS and/or CSS files.
  2. You've researched other solutions such as complex regex routines or CFCs and are not satisfied with those solutions.
Regarding #2, modern minification is complex and tedious. If you've tried writing your own routines, you know what I mean. Not to mention, effective minification consists of more than just code formatting. So what's the answer? Well, there is already a clear and proven minification winner: YUI Compressor. This utility is widely used, reliable, and efficient. It also includes useful options to give you some level of control as well as insight.

Now that we've picked our minification engine, how do we make it work with ColdFusion?

First you need to get YUI Compressor installed on your server and YUI Compressor relies on Rhino, so we need to get that installed as well. All of this relies on you having Java installed, but since you are running ColdFusion I am assuming you do!


DOWNLOAD RHINO (recommended release at time of this post is 1.7R5)
  • Install to directory of choice, i.e. C:\apps\rhino\rhino1_7R5
  • Add to Windows CLASSPATH
    • System Properties > Advanced > Environment Variables > System Variables > CLASSPATH
      • If CLASSPATH system variable doesn't already exist, add it with value of "c:\apps\rhino\rhino1_7R5" or your chosen install directory.
      • If CLASSPATH system variable already exists, edit it by adding ";c:\apps\rhino\rhino1_7R5" or ";" followed by your chosen install directory.

DOWNLOAD YUI COMPRESSOR (recommend release at time of this post is 2.4.8)
  • Install to directory of choice, i.e. c:\apps\yuicompressor\yuicompressor-2.4.8.jar

Verify you can run YUI Compressor from command line
  • Open a command prompt in a test directory with a non-minified JS file present, i.e. test.js
  • Run command $ java -jar c:\apps\yuicompressor\yuicompressor-2.4.8.jar -v c:\test\test.js -o test.min.js
  • The "-v" argument causes output to include analysis of the JS with tips for improvements. Don't include this option if you are minifying CSS.
  • You should see test.min.js created in the current/test directory.

Run minification from within ColdFusion:
  • Use <cfexecute> to run YUI Compressor against file in need of minification.
  • minifyResult will contain the command prompt output.
  • minifyError will contain error information.
<cfexecute name="java" arguments="-jar c:\apps\yuicompressor\yuicompressor-2.4.8.jar c:\test\test.js -o test.min.js" variable="minifyResult" errorVariable="minifyError" timeout="10"/>

  • ColdFusion runs cfexecute from the ColdFusion bin, so this is where the minified file will be generated, so we need to move the generated file from the CF bin to the desired target directory.
  • The cf_bin_path variable value will likely be different for your install, so you need to update this variable to point to your actual CF bin directory.
<cfset cf_bin_path = "c:\ColdFusion\runtime\bin">
<cffile action = "move"
source = "#cf_bin_path#\test.min.js"
destination = "c:\target-directory\test.min.js">

Thursday, November 15, 2012

Facebook Page Delete Post Function is Broken

While using Facebook tonight to manage a 'page' I noticed that the Delete Post functionality is currently broken. Take a look at the screencap below. There is a 500 (Internal Server Error) associated with a javascript file on Facebook's CDN. This is a disappointment in quality code control. This shouldn't be happening at a publicly traded mega site like Facebook. If you are experiencing this error, all we can do is wait for Facebook's fix to be released and distributed across the CDN. Not fun when page moderation is needed.