WebViewer from Scratch issue + How to convert docs via cloud and load in personal application?

1,090 views
Skip to first unread message

Jack Brown

unread,
Jan 21, 2014, 4:18:39 PM1/21/14
to pdfnet-w...@googlegroups.com
To whom it may concern,

I have read over the Webviewer Developer Guide and I am trying to create my own WebViewer from scratch using the instructions detailed on the "Using JavaScript with WebViewer" section of the Guide. I have followed the instructions and have made a number of attempts to display the WebViewer but nothing is working. I am using XAMPP and localhost is my server name. I have tried placing the jQuery in the head section of my HTML after the jQuery and WebViewer files and even after the "viewer" div. Neither attempts work. What am I doing incorrectly? I have the jQuery, WebViewer, and .xod files as the only files in my XAMPP htdocs folder. Please have a look at my code below...

<!DOCTYPE html>
<html>
<head>
<title>Viewer Test</title>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="WebViewer.min.js"></script>
</head>
<body>
<div id="viewer"></div>
<script type="text/javascript">
$(function() {
var viewerElement = document.getElementById('viewer');
var myWebViewer = new PDFTron.WebViewer({
type: "html5,Silverlight,flash",
initialDoc: "GettingStarted.xod"
}, viewerElement);
});
</script>
</body>
</html>

Also, I would like to use the cloud service PDFTron provides to convert docs to .xod, but how can I connect my web application to your servers so users can upload their files and convert them via the cloud and then are able to view them in my application?

Thank you

Kevin Kuo

unread,
Jan 21, 2014, 6:40:11 PM1/21/14
to pdfnet-w...@googlegroups.com
WebViewer.js is technically a wrapper JavaScript API that creates HTML5/Silverlight/Flash viewers for you. 
So the easiest way is just to copy over the entire lib folder in the download.

If you want to change the folder hierarchy, you can specify an alternate path where the lib folder is located on your server.
To do this, use the "path" option in the WebViewer constructor.
eg.

    var myWebViewer = new PDFTron.WebViewer({
        type
: "html5,Silverlight,flash",
        initialDoc
: "GettingStarted.xod",

        path
: "your/path/to/lib/folder"
       
}, viewerElement);
       
});



You may also want to look at the WebViewer Universal viewer. This tutorial goes through how to set it up on your own server: http://www.pdftron.com/webviewer/demo/tutorials/01.html



Regarding the PWS Cloud service...
We strongly recommend you have your end users upload their files to your server, and have your server upload the file to PWS Cloud.
Several reasons:
1. You will want to keep your PWS API Key and Secret safe on your own server. (not in the hands of your end-users)
2. You will want to record extra information about your users documents, so you should be aware of what your users are uploading.


We have a sample application that shows how this is done.
Or download the source code here: http://www.pdftron.com/pws/cloud/samples.html

Jack Brown

unread,
Jan 28, 2014, 1:32:29 AM1/28/14
to pdfnet-w...@googlegroups.com
This worked perfectly. Thank you. I hate to bore you with lesser questions but I am a novice with JavaScript/jQuery. I have read through your API references and they are quite clear and have gotten a number of methods to work on my own but I would like to know how I can go about doing the following...

Is there a way I can change the text highlight color? Also is there a way I can highlight text in the document viewer and turn the highlighted text into an external hyperlink to a web page?

Kevin Kuo

unread,
Jan 28, 2014, 1:59:34 PM1/28/14
to pdfnet-w...@googlegroups.com
Glad that worked for you!

You can change the default text select color with the DocumentViewer SetTextHighlightColor method.

Can you clarify what you are trying to do with the external link?
  • are you trying to turn text content in URL format within the document into an real link? In that case, you could try using the "generate URL" option during conversion, under the advanced options tab
  • are you referring to "text selection", or the "text highlight annotation"?
  • if its just text selection, you could use listen to the document viewer's "textSelected" event and do your own thing (e.g. create a DOM element with an actual link and insert it on the page)
    • however it gets more complicated if you need to persist this...

Jack Brown

unread,
Feb 2, 2014, 8:13:26 PM2/2/14
to pdfnet-w...@googlegroups.com
Hello Kevin,

I finally know what I need to do. I want to be able to highlight/select text in a webviewer document and link it to an external div located outside of the webviewer. So when a user is using my application and they click on that hyperlinked text, it will link them to that div.

Kevin Kuo

unread,
Feb 4, 2014, 3:56:16 PM2/4/14
to pdfnet-w...@googlegroups.com
Okay it sounds like you need two parts:

1. an "admin" that can highlight text to create links
2.  in WebViewer, you need to override the default behavior of links. So when a user clicks, you define your own action (default is opening the url in a new tab.)


For 1)
WebViewer does not provide features for creating/editing links. See my previous posts on how to extend WebViewer to do this.
The easiest way is really to just create the links in PDF.


For 2)
You can easily override the link action behavior in WebViewer. There are some sample code in ReaderControl.js that shows this.


         
//Example of overriding the default link appearance and behavior
         
//==============================================================
         me
.docViewer.on('linkReady', function(e, linkElement, link){
           
if(link instanceof CoreControls.Hyperlink){
                linkElement
.onclick = function(){
                   
//external link clicked
                    window
.open(link.GetTarget());
               
};
       
           
}else if(link instanceof CoreControls.Link) {
                linkElement
.parentClick = linkElement.onclick;
                linkElement
.onclick = function(){
                   
this.parentClick();
               
//override the default behavior of internal links
               
};
           
}
         
});

Jack Brown

unread,
Feb 10, 2014, 2:59:36 PM2/10/14
to pdfnet-w...@googlegroups.com
So placing this exact code in my config file will allow users the ability to highlight any text which will automatically be linked to the div that I will create?

Jack Brown

unread,
Feb 11, 2014, 10:28:08 PM2/11/14
to pdfnet-w...@googlegroups.com
I don't think you understand. ALL I want to do is..

A. "Highlight text"
B. Using some function (attached to a button or something) turn that highlighted text INTO hyperlink (ON THE FLY) that will then be linked to a div! (A div that I will create).

Can it really be that hard to accomplish this? This WebViewer is so advanced and I really can't do something so simple as this?

Kevin Kuo

unread,
Feb 17, 2014, 4:09:18 PM2/17/14
to pdfnet-w...@googlegroups.com
Here's some sample code (config.js) that you can try out.

This code will add a new button called "create link" on the toolbar.
When some text is selected with the text select tool (selected text is blue), you can click on the button.
A prompt will appear, where you can enter a URL address.

Now the selected text has turned into a click-able link.

There is also code included for overriding the default behavior when a link is clicked.
It is unclear what you mean by "linked" to a div. (e.g. a div will be "popped up"  on screen?)
In any case, you can specify the behavior yourself.







(function() {
   
"use strict";
    $
(document).bind("documentLoaded", function(event) {


        window
.custom = window.custom || {};
        window
.custom.links = [];


       
var textSelectedParent = Tools.TextSelectTool.prototype.textSelected;
       
Tools.TextSelectTool.prototype.textSelected = function(pageIndex, quads, text, me) {
            textSelectedParent
.call(this, pageIndex, quads, text, me);
            window
.custom.selectedQuads = {
                pageIndex
: pageIndex,
                quads
: quads
           
};


       
};


        $
("<button>").attr({
           
'id': 'optionsButton',
           
'class': 'ui-ele',
           
'type': 'button'
       
})
               
.text('Create Link')
               
.prependTo($("#control")).button({
       
}).click(function() {


           
if (window.custom.selectedQuads !== null) {
               
               
//var url = "http://google.com";
               
var url = prompt("Please enter the URL of the link", "http://google.com");
                   
               
for (var i = 0; i < window.custom.selectedQuads.quads.length; i++) {
                   
var q = window.custom.selectedQuads.quads[i];
                    window
.custom.links.push({
                        pageIndex
: window.custom.selectedQuads.pageIndex,
                        points
: q.GetPoints(),
                        url
: url
                   
});
               
}
                renderCustomLinks
();
           
}
       
});




       
function renderCustomLinks() {
           
var docViewer = readerControl.getDocumentViewer();
           
var doc = docViewer.GetDocument();
           
var pageIndex = 0;


           
for (var i = 0; i < window.custom.links.length; i++) {
               
var points = window.custom.links[i].points;
               
var pageIndex = window.custom.links[i].pageIndex;
               
var url = window.custom.links[i].url;
               
               
var point1 = doc.GetPDFCoordinates(pageIndex, points.x1, points.y1);
               
var point2 = doc.GetPDFCoordinates(pageIndex, points.x3, points.y3);


               
var pageLinks = doc.GetLinks(pageIndex);


               
// creates an external link
               
var externalLink = new CoreControls.Hyperlink([point1.x, point1.y, point2.x, point2.y], url);


                pageLinks
.push(externalLink);
           
}


           
//workaround to force links to be re-created
            readerControl
.setZoomLevel(readerControl.getZoomLevel());
       
}


       
//=============================================
       
// Override the default behavior of links
       
//=============================================
       
var docViewer = readerControl.getDocumentViewer();

        docViewer
.on('linkReady', function(e, linkElement, link) {

           
if (link instanceof CoreControls.Hyperlink) {

                linkElement
.onclick = function() {
                   
//external link clicked
                    window
.open(link.GetTarget());

                   
//handle your own logic here
                   
               
};
           
}
       
});
   
});
})();

Kevin Kuo

unread,
Feb 18, 2014, 12:39:49 PM2/18/14
to pdfnet-w...@googlegroups.com
Also see the following post regarding dynamic links:


Note that this is only supported in WebViewer 1.7 and XOD documents converted with PDFNet SDK 6.0 or higher.

Jack Brown

unread,
Feb 28, 2014, 1:50:10 AM2/28/14
to pdfnet-w...@googlegroups.com
Thank you for your help. I was wondering how can I remove certain tools from the annotations tab like "Callout". I'd like to remove the image that activates it. I only want to have users use the annotation tools I'd like them to use.

Kevin Kuo

unread,
Feb 28, 2014, 1:38:47 PM2/28/14
to pdfnet-w...@googlegroups.com
First, look at the source file lib\html5\AnnotationPanel.html
You'll see that each tool mode image is defined here in a list.


There are a couple ways you could remove the image (and button):

1. Remove the code directly in this file (AnnotationPanel.html)
For example, remove the <li> element where the id is annot-button-callout

2. You could use a config script to explicitly hide the <li> element on viewer loaded.
e.g. $("li#annot-button-callout").hide(); 

3. Use a CSS style to hide the <li> element
e.g. #annot-button-callout {
    display:none;

Jack Brown

unread,
Mar 2, 2014, 10:18:33 PM3/2/14
to
Yep works perfectly. I just commented out the tools I didn't need. Also my text underline tool is no longer working and I am not sure what I did. The image and code is proper in the annotation panel html file but when I click on the image the button doesn't work. Also I created an extra tab on the sidepanel of the webviewer and my customization works perfectly, but the problem is that when I switch to that tab, the page resets back to page one of the document. For example, if I am viewing and annotating page 10 of my document and I click on the new tab I created, the document resets back to page one instead of staying on page 10. How can I make it so where users click on my new tab and it doesn't reset the document being viewed to page one? These are my two issues, here is my code below for the new tab I created regarding my second issue...

    $("<li style='height: 27px; width: 38px;'>").attr({
        'id': 'thread',
        'class' : '.ui-icon ui-icon-thread',
        'type': 'button'
    })
    .text('Section')
        .appendTo($(".ui-tabs-nav")).button({
            text: false,
            icons: {
                primary: "ui-icon ui-icon-custom-comment"
            }
        }).click(function(){
            $("#viewer").fadeToggle();
            $("#thread").fadeToggle();
        });
       
This is also a very small and minor issue and if it cannot be changed it is no problem, but is there a way to change the text that pops up on screen which displays "Annotations were successfully saved". I'd like to add my site name to this and possibly add my site's logo too.

Kevin Kuo

unread,
Mar 4, 2014, 3:59:26 PM3/4/14
to pdfnet-w...@googlegroups.com
1) Text Underline Tool not working
Can you send the browser's console log?
If there are no useful errors, then you can share your code or a sample where we can reproduce the issue?


2) Custom button in tab resetting to page one

The code you shared doesn't show the problem, it only hides the viewer and the tab button when clicked. So is there some other code that you're using somewhere?
Is the HTML page being reloaded from the button action?

Custom buttons added should not affect the document viewer's page index.


3) Text for "Annotations were successfully saved"

You change the string in the internalization file:
under lib\html5\Resources\i18n\translation-en.json

If you want more changes, you can look at the DIV with id "overlayMessage" in ReaderControl.




On Friday, February 28, 2014 1:19:02 PM UTC-8, Jack Brown wrote:
Yep works perfectly. I just commented out the tools I didn't need. Also my text underline tool is no longer working and I am not sure what I did. The image and code is proper in the annotation panel html file but when I click on the image the button doesn't work. Also I created an extra tab on the sidepanel of the webviewer and my customization works perfectly, but the problem is that when I switch to that tab, the page resets back to page one of the document. For example, if I am viewing and annotating page 10 of my document and I click on the new tab I created, the document resets back to page one instead of staying on page 10. How can I make it so where users click on my new tab and it doesn't reset the document being viewed to page one? These are my two issues, here is my code below for the new tab I created regarding my second issue...

    $("<li style='height: 27px; width: 38px;'>").attr({
        'id': 'thread',
        'class' : '.ui-icon ui-icon-thread',
        'type': 'button'
    })

    .text('Section')
        .appendTo($(".ui-tabs-nav")).button({
            text: false,
            icons: {
                primary: "ui-icon ui-icon-custom-comment"
            }
        }).click(function(){
            $("#viewer").fadeToggle();
            $("#thread").fadeToggle();
        });
       
This is also a very small and minor issue and if it cannot be changed it is no problem, but is there a way to change the text that pops up on screen which displays "Annotations were successfully saved". I'd like to add my site name to this and possibly add my site's logo too.

Jack Brown

unread,
Mar 5, 2014, 1:36:30 AM3/5/14
to pdfnet-w...@googlegroups.com
I fixed the Text Underline tool and thank your for part 3 info. Part 2 info is there an execution I can give that when the viewer div is hidden and when I "unhide" it is still in the exact same location it was when I initially hid it? There is no other code elsewhere. The HTML page may be reloaded on the button action I am not sure. All I need it to do is not reset to page when I execute fadeToggle(); Please see the code I detailed because that's all I have.

Kevin Kuo

unread,
Mar 5, 2014, 1:47:24 PM3/5/14
to PDFTron WebViewer on behalf of Jack Brown
Hi Jack,

Okay I see what you mean.
Instead of using fadeToggle, you can use the CSS visibility style to hide the viewer. This won't cause a jump to the first page.
e.g.
       ...
        }).click(function(){
            if($("#viewer").css("visibility") === "hidden"){
                $("#viewer").css("visibility", "visible");
            }else{
                $("#viewer").css("visibility", "hidden");
            }
        });


--
You received this message because you are subscribed to the Google Groups "PDFTron WebViewer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pdfnet-webview...@googlegroups.com.
To post to this group, send email to pdfnet-w...@googlegroups.com.
Visit this group at http://groups.google.com/group/pdfnet-webviewer.
For more options, visit https://groups.google.com/groups/opt_out.

Jack Brown

unread,
Mar 11, 2014, 11:42:26 PM3/11/14
to pdfnet-w...@googlegroups.com
Thank you for all your help. I am now on the backend part of coding and the problem now is that since I am a SERIOUS amateur when it comes to PHP, I need a very dumbed down version as to how I can allow users to do the following...

Click on a button to allow a user to choose and upload a document (how do I restrict the size?)
I am placing separate instances of the webviewer on multiple parts of my site each with different documents just to let you know.

I am using your cloud servers to allow users to convert their documents to .XOD and I am also using your servers to allow users to save annotations.
So how do I... get users uploaded documents to convert and save in your cloud server and able to be viewed on my customized webviewer?

And.. what happens if multiple people use the webviewer and save/make changes to annotations? is there like an auto refresh or realtime thing we can do with JavaScript/jQuery?

Lastly... how do I sync my users accounts with the webviewer so their names can appear on the left panel instead of just "guest"?

I have been dreading this last step because this is all I have left to do to complete my site and I wish I was stronger in PHP. I have taken a look at your PHP Bookstore sample and I am sure it is very simple to understand and implement for PHP pros but not for me unfortunately. If a step by step tutorial is too much, can you at least give me a step by step way into possibly reading the PHP Bookstore app code and modifying it to fit my needs? If not I would be more than happy to pay you or another PDFTron to give me a written PDF with instructions.

You will be my absolute hero if you can help me with this last step.






On Wednesday, March 5, 2014 12:47:24 PM UTC-6, Kevin Kuo wrote:
Hi Jack,

Okay I see what you mean.
Instead of using fadeToggle, you can use the CSS visibility style to hide the viewer. This won't cause a jump to the first page.
e.g.
       ...
        }).click(function(){
            if($("#viewer").css("visibility") === "hidden"){
                $("#viewer").css("visibility", "visible");
            }else{
                $("#viewer").css("visibility", "hidden");
            }
        });

Kevin Kuo

unread,
Mar 13, 2014, 2:48:20 PM3/13/14
to pdfnet-w...@googlegroups.com
Hi Jack,

Unfortunately, we are unable to provide basic programming support. There are many resources on the web for PHP I'm sure you can find.
Practically speaking, the server-side handling for annotations is the most complex and does require you to be able to implement solutions yourself.
We can only give basic guidelines, because it depends on many factors: your server, database, permission requirements, authentication etc...


To get user uploaded files to display in your WebViewer instance, using the PWS Cloud web service...
I know you already know about the bookstore sample, but it has all the working code to do just that.
There's also a tutorial that might help explain this: http://www.pdftron.com/pws/cloud/tutorials.html
Though you will most likely want to store the responses from PWS Cloud into your own database. (i.e. save the document ID, so that you can fetch the file again from the PWS server).

Guidelines for multiple users using annotations:


To change the name that appears for the annotation, you can set the author in WebViewer.
You can also see a sample of this in action here:

Jack Brown

unread,
Mar 20, 2014, 11:40:21 AM3/20/14
to pdfnet-w...@googlegroups.com
Thanks Kevin for this. I'll do my best. But since I am a novice can you at least give me sample working code for the following regarding multiple user annotations?

To integrate annotations with your server, the steps are as followed:
  • use a simple javascript polling mechanism (let's say using setInterval)
  • on each tick
    • call AnnotationManager.GetAnnotCommand() to get all the "dirty" annotations
    • make a POST request to your server, with the annot command string as the body
    • now your server should process this these annot commands. This is where extra logic may be needed regarding permissions and how you persist the annotation data. It is up to your implementation.
      • an example, is that your server temporarily saves the annot commands (to database or file). And returns any new annot commands it has received (from other users).
      • in a simple scenario, you can keep track of annot commands by using timestamps on when it was sent to the server.
    • your server will respond with any new annot commands created from other clients
    • you can call AnnotationManager,ImportAnnotCommand(data) to load the annotations
    • so effectively, on every tick, a client sends to the server any changes it has made. The server will respond with changes that any other users have made since the last "tick".
And is this code good for the client side? How would this look exactly when I am to use it?

            setInterval(function(){
               
var am = me.docViewer.GetAnnotationManager();
               
var clientAnnotData= am.GetAnnotCommand();
                $
.ajax({
                    url
: serverurl
                    cache
: false,
                    data
: clientAnnotData,
                    success
: function(data) {
                       
//server returned some annotation commands
                       
if (data !== null) {
                            am
.ImportAnnotCommand(data);
                       
}
                   
},
                    error
: function() {
                       
//server gave an error
                   
},
                    dataType
: 'xml'
               
});
           
},3000); //execute this code every 3 seconds

Kevin Kuo

unread,
Mar 27, 2014, 5:52:23 PM3/27/14
to pdfnet-w...@googlegroups.com
Here is more information describing how the most basic "auto-refreshing" feature can be implemented.

The key pieces here:
-javascript setInterval, to call a method every X seconds
-a simple server script, handling saving and load a single XML file


If you search in ReaderControl.js for "setInterval", you see there is some code commented out that you can use to set up simple "auto-refreshing".

//this will call the method updateAnnotations() every 1 second
var updateAnnotsID = setInterval(this.updateAnnotations.bind(this), 1000);

The default implementation in updateAnnotations() send and receives annotation data as "annotation commands", which requires the server to handle the commands. 
The code here as is will not work, because there is no server script that understands commands. (PDFNet SDK has an API for this, or you could parse the xml yourself.)

To keep things simple, we can look at the sample server implementation annotationHandler.php and use it has the server script.
What this PHP script does:
-read the "did" param (in query parameter, or post parameter), to identify the document
-on a POST request: save the POST data (which in this case is the full annotation XML data) as a file
-on a GET request, load the file and returns it


So, you can modify updateAnnotations to trigger and save and load.

...
updateAnnotations
(){
       
//use the did to identify the document.
       
var query = '?did=' + this.doc_id;
           
if (this.doc_id === null) {
               
//Document id is not available. did will not be set for server-side annotation handling.
                query
= '';
           
}
                 
//send a POST request (save annotations)
               
var xfdfString = am.ExportAnnotations();
                $
.ajax({
                    type
: 'POST',
                    url
: this.server_url + query,
                    data
: {
                       
'data': xfdfString
                   
});


             
//send a GET request (to load annotations that may have been updated by others)
              $
.ajax({
                    url
: this.server_url + query,
                    cache
: false,
                    success
: function(data) {
                       
if (data !== null) {
                            am
.ImportAnnotations(data);
                       
}
                   
},
                    dataType
: 'xml'
               
});
}

Jack Brown

unread,
Mar 30, 2014, 5:23:04 PM3/30/14
to pdfnet-w...@googlegroups.com
Well I made a great breakthrough. I got my PHP upload script to work and I used the tutorial. Not only did I get it to work, but I also got the document ID and the share ID to work along with the conversion. So this is great and I am very happy with this! Once I finalize this then I'll implement the auto-update collaboration stuff. My next questions are as follows...

You said you recommend I store the document and share ID's into my database. How exactly would I do that? I have a MySQL database set up on my server already (remember I am PHP novice so forgive me if this sounds very base to you.)

And now that I got it to where users can upload files and have them converted in your cloud system, how do I enable it to when the document is uploaded and converted that the document is immediately displayed in MY custom webviewer interface?

I plan on running multiple but separate webviewer interfaces on my site, is there anyway I should set up my code so nothing get's mixed up? (like having the same document load in two separate webviewer interfaces on my site).

Jack Brown

unread,
Mar 31, 2014, 12:44:47 AM3/31/14
to pdfnet-w...@googlegroups.com
In addition to this here is another thing I would like to figure out, I have appended some custom code to the popups in my webviewer (basically some button functions) the problem is that the buttons show on each popup instance but the buttons work ONLY on the first popup created, on the other popups they don't work if you click the buttons. My code is below...

    $popupel.append('<button id="click1">Click 1</button>').append('<button id="click2">Click 2</button>');
    $("#click1").click(function(){
        1count++;
        $("#click1").html(upcount);
    });
    $("#click2").click(function(){
        2count++;
        $("#click2").html(downcount);
    });

Kevin Kuo

unread,
Apr 3, 2014, 2:19:22 PM4/3/14
to pdfnet-w...@googlegroups.com
We recommend you store the document id for your own records.
Why? When you create a document, PWS gives you back a document ID. If you don't keep the ID somewhere, you won't be able to access it in the future.
For production environments with a dynamic list of documents, databases are ideal for keeping the records.

How you decide to store this info is up to you. (i.e. you should design your database table schemas yourself to suit your own needs, or you could even just hard-code the list of documentIDs on your webpage)


To load XOD files created from PWS Cloud, you can do a couple of things:

  1. Download the XOD files and host your own XOD files on your servers
  2. Use PWS Cloud to get a share ID or a session ID, so that the resource can be accessed directly from the PWS servers.
    1. e.g. make a POST request to https://api.pdftron.com/v2/document/{id}/share
    2. You can then pass the ID into WebViewer through the option "cloudApiId"
    3. Or you can use the share ID to get the actual URL of the XOD, and set the initialDoc url  (GET https://api.pdftron.com/v2/download/{sessionOrShareId}?redirect=false    to get the actual URL)
    See the PWS Cloud API Reference for more info: https://api.pdftron.com/v2/docs/index.html

For hosting multiple WebViewers on your server, if you've made any changes and customizations to the 'lib' folder, it is best to maintain separate copies of it.
e.g. /myviewer1/lib
       /myviewer2/lib    (where lib is the lib folder from the WebViewer download package)

Otherwise, you can treat WebViewer.js like a "library" and reuse it for both your projects.


Regarding your popup question.
From the code you've shown, you should not use ids that, because ids should be unique. What is happening is that on the second popup created, you now have 2 elements with the id #click1 and #click2.
To fix this, generate unique IDs, or use classes instead. Or avoid using ids altogether:
      var am = window.readerControl.docViewer.GetAnnotationManager();
        am.on('annotationPopupCreated', function(e, annotation, $popupel) {

            $('<button>Click 1</button>').appendTo($popupel).click(function() {
                $(this).html(upcount);
            });
            $('<button>Click 2</button>').appendTo($popupel).click(function() {
                $(this).html(downcount);
            });
        });












Jack Brown

unread,
Apr 13, 2014, 3:21:19 PM4/13/14
to pdfnet-w...@googlegroups.com

Can you give me the code to place in my config file that will allow me to change the user interface selection color? The current color is this  #CBE6EF
I tried doing this in defaultStyleExtension.css and nothing worked. I attached an image to show you where I want the color change to take effect.

Kevin Kuo

unread,
Apr 14, 2014, 9:44:06 PM4/14/14
to PDFTron WebViewer on behalf of Jack Brown
Hi Jack,

You can override it with the following CSS in defaultStyleExtension.css :

.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
    background: yellow;
}




For more options, visit https://groups.google.com/d/optout.

Jack Brown

unread,
Apr 29, 2014, 2:44:10 AM4/29/14
to pdfnet-w...@googlegroups.com
I just did a test of my site via an iPad with "mobileRedirect: true". The whole page didn't redirect to the mobile version and take up the whole screen which I like but my custom Viewer buttons and etc don't show. Where do I make these changes to match the desktop version and etc. Also when I save the annotations via mobile, they don't show up on the desktop version when I refresh the page. I have no idea where the annotations were saved. How can I get them synced?


On Monday, April 14, 2014 8:44:06 PM UTC-5, Kevin Kuo wrote:
Hi Jack,

Kevin Kuo

unread,
May 6, 2014, 3:09:12 PM5/6/14
to pdfnet-w...@googlegroups.com
If mobileRedirect is true, then you should be redirected to a new page. (to MobileReaderControl.js).
Any custom buttons that you added outside of the config.js script will not show up.

If you meant you tried redirect = false, then it depends on where and how you've made your customizations.
You might need to look at MobileReaderControl.html to see where to place your custom buttons. The layout does not work the same way as ReaderControl.
If you share some specific code, we could give more details.

The default annotationHandler.php sample script saves the annotations separately based on browser cookie ID. So that means you won't see the same annotation on desktop and mobile.
Please change the script to your own logic.
For example, you could just save the file based on the document id directly, and ignore the cookie id.
$xfdf_file = "annotations/".$did.".xfdf";


Jack Brown

unread,
May 7, 2014, 12:44:12 PM5/7/14
to pdfnet-w...@googlegroups.com
I don't need the user cookie verification stuff so just ignore that. I am using the cloud API service to convert and host docs so please let me know if my PHP below is correct. To make it even more personalized, let me know the exact code to place the share ID as well if it is possible. Please read the code correctly and let me know if it correct and if it isn't tell me what to correct.

<?php

//Simple annotation handler
if(isset($_REQUEST['did']) && $_REQUEST['did'] != "null"){
    //get the document id
    $did = $_REQUEST['did'];
    $xfdf_file = "annotations/{$cookie_id}/".$did.".xfdf";
    $xfdf_file = "annotations/".$did.".xfdf";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    //POST request
    if(isset($_POST['data'])){
        
        if (get_magic_quotes_gpc()) {
            $xfdfData = stripslashes($_POST['data']);    
        } else{
            $xfdfData = $_POST['data'];
        }

        if(file_put_contents($xfdf_file, $xfdfData)){
            //save successful
            //echo $xfdf_file;
        }else{
            header("HTTP/1.1 500 Internal Server Error");
        }
    }
} else{
    //GET request
    if(file_exists($xfdf_file)){
        header("Content-type: text/xml");
        echo file_get_contents($xfdf_file);
    }else{
        header("HTTP/1.1 204 No Content");
    }
    
}

?>

Also I have a custom upvote downvote buttons appended to the popups via webviewer which you helped me with a month or so ago. I have the code working more or less and I want to know how I can have the button count be saved when I click the annotation "saved" button. Please see the code below and tell me what I need to do to keep the counts saved. If this isn't possible let me know why it isn't and an alternative.

var popupId = 0;
var popupId2 = 0;

var am = readerControl.docViewer.GetAnnotationManager();
    am.on('annotationPopupCreated', function(e, annotation, $popupel) {
    popupId++;
    popupId2++;
    $popupel.css('background', '#6d97a5');
    $popupel.find('textarea').css('font-family', 'Arial').css('font-size', '80%');
    $popupel.find('.popup-subject').text("");
    $('<div id="' + popupId + '" style="margin-left: 30px; float: left; font-weight: bold; color: white; font-family: Arial; margin-top: -4px;"></div>').appendTo($popupel);
    $('<div id="' + popupId2 + '" style="margin-right: 30px; float: right; font-weight: bold; color: white; font-family: Arial; margin-top: -4px;"></div>').appendTo($popupel);
        $('<div style="float: left; margin-left: 5px; margin-top: 5px;"><img style="cursor: pointer; margin-top: -13px;" src="/lib/up.png"></div>').appendTo($popupel).click(function() {
            var upcount = 0;
            upcount++;
            $("#" + popupId).html(upcount);
        });
        $('<div style="float: right; margin-right: 5px; margin-top: 5px;"><img style="cursor: pointer; margin-top: -13px;" src="/lib/down.png"></div>').appendTo($popupel).click(function() {
            var downcount = 0;
            downcount++;
            $("#" + popupId2).html(downcount);
        });
  });

Kevin Kuo

unread,
May 9, 2014, 1:58:13 PM5/9/14
to pdfnet-w...@googlegroups.com
Hi Jack,

You can use pass in the PWS Cloud share ID as the "did" in your php script. 
So you would just have to add it to your WebViewer javascript usage.
e.g.
myWebViewer = new PDFTron.WebViewer({
...
        cloudApiId : {shareid},
        documentId : {shareid} 
}, viewerElement);


Matt has answered your other question in a new thread here:

If you have more questions, please post them individually in its own thread. It will help with the question's visibility and help us with tracking.
Reply all
Reply to author
Forward
0 new messages