I created an action using Action wizard in Acrobat Pro X.
A JavaScript is running when action started.
What this Javascript Do? suppose 100 page in opened pdf, this javascript extract all as seperate pages and rename it as user defined style.
e.g. Hello_001.pdf,Hello_002.pdf,Hello_003.pdf,Hello_004.pdf,... and so on,
i want a Custom Menu which target this action to execute.
It seems to me that you can find your answer in the link you gave. Important is that your script/function works correctly. So test it before in the js console. However here an example, where you can replace the script with yours. Regards, Reinhard
EDIT: (25.11.) Thought can use it by myself, but then I want to have it sortable. So I introduced leading zeros in the extract filename -> function changed.
//Save this in the ....\Acrobat\Javascripts\ program or user directory
// as whatever.js to load as Add-In
//-> create a submenu as first position under "Edit"
app.addSubMenu({ cName: "Specials", cParent: "Edit", nPos: 0 });
//-> now create a Menuitem for the function you will execute
app.addMenuItem({ cName: "Extract all Pages to file", cParent: "Specials", cExec: "extractAll()"});
//-> state your function (extract all Pages with leading zeros)
extractAll = app.trustedFunction(function (){
var re = /.*\/|\.pdf$/ig;
var filename = this.path.replace(re,"");
var lastPage = this.numPages;
var lz = Math.pow(10, (lastPage).toString().length); //calc full decimals (10,100,..)
app.beginPriv(); // Explicitly raise privilege
for ( var i = 0; i < lastPage; i++ ) {
var zPgNo = (lz + i+1).toString().slice(1); //calc actual, cut leading 1 = zerofilled PgNo
this.extractPages({
nStart: i,
nEnd: lastPage -1,
cPath : filename + "_page_" + zPgNo + ".pdf"
});
};
app.endPriv();
app.alert("Done!");
})
You can't trigger an Action to run from a menu item. However, you can create an application level JavaScript that contains a function that does what you want and then call that function from either an Acrobat Action or a custom Menu Item or both. The answer from ReFran shows how to add the custom menu item.
Related
For many reasons it isn't always ideal to install a plugin on multiple sites just to copy content. For pages / posts it's really easy to grab the post content and copy+paste (even when using page builders the content is available in an underlying textarea). Menus on the other hand are a pain. What is your goto method for copying menus?
This is what I whipped up today to solve copying WordPress menus via JavaScript / without a plugin.
First navigate to the menu you want to copy and paste this into the console.
var items = jQuery('#menu-to-edit li');
var json = [];
jQuery.each(items, function(i, item) {
item = jQuery(item);
var title = item.find('.edit-menu-item-title').val();
var url = item.find('.edit-menu-item-url').val();
var classes = item.find('.edit-menu-item-classes').val();
var description = item.find('.edit-menu-item-description').val();
var menuitem = {"title" : title, "url" : url, "classes" : classes, "description" : description};
json.push(menuitem);
});
JSON.stringify(json);
Copy that output and navigate to the new menu - paste the content into the parse statement below:
var json = JSON.parse('PASTED DATA HERE');
function addItem(item)
{
jQuery('#custom-menu-item-url').val(item.url);
if (item.url == "")
{
item.url = "#";
}
jQuery('#custom-menu-item-name').val(item.title);
jQuery('#submit-customlinkdiv').click();
}
Then simply shift elements out of that json element and into the addItem function.
addItem(json.shift());
Rinse and repeat until your items are added.
There is lots of room for optimization on this e.g. it could add the classes / descriptions, re-order the menu items in the correct depth, add extended properties or monitor the add menu item form and automatically add the next item for you - could become a handy bookmarklet to beat back throwaway plugins like those that do simple menu copies.
We are given a requirement such that the page should be moved to a location based on the path provided at the page properties.
How to implement that in Touch UI?
In Classic UI we can use edit config and may use listeners and write respective JS code on that.Correct me if I am wrong.
Your question alludes to wanting to use JavaScript to move the page. I've put together an example using the Touch UI dialog. It works, but would require polish to validate user input and prevent string manipulation errors.
In this example, I'm using the dialog-success event that triggers after a dialog is saved. See Touch UI Events. I check to see if the textfield with the CSS selector is populated, and if it is, I post back to the Sling Post Servlet using the #MoveFrom suffix to move the node and its children (the page and the jcr:content, etc...). If that operation is successful, navigate the user to the new page.
In your dialog, add a textfield and give it a unique class name:
<movePage
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldLabel="Move page to:"
class="move-page"/>
Then add this JavaScript to a ClientLib used only in authoring mode such as cq.authoring.editor:
(function ($, $document) {
'use strict';
$document.on("dialog-success", function(e) {
var newPath,
lastSlash,
moveFromSuffix,
newDirectory,
currentPath,
data;
e.stopImmediatePropagation();
newPath = $('.move-page').val();
if (newPath) {
lastSlash = newPath.lastIndexOf('/');
moveFromSuffix = newPath.substring(lastSlash + 1) + Granite.Sling.MOVE_SUFFIX;
newDirectory = newPath.substring(0, lastSlash);
currentPath = Granite.HTTP.getPath().replace('/editor.html', '');
data = {};
data[moveFromSuffix] = currentPath;
$.post(newDirectory, data)
.done(function(){
window.location = '/editor.html' + newPath + '.html';
})
.fail(function(){
$(window).adaptTo('foundation-ui').alert('Alert', 'Could not move page');
});
}
});
})($, $(document));
However, another option would be to do it server side by implementing a custom Sling Post Processor.
I am trying to disable view picker on account lookup in 2016.
The code works fine I mean I am not getting any error but the code not able to find the particular DIV of "parentaccountid".
Where as I can see it in Elements:
But it's returns {null} when the code try to get the elements of DIV - document.getElementByid("parentaccountid");
My code runs on load of opportunity page.
Even at this step I can see the particular DIV element- id: parentaccountid
Where as I still get {null} value:
Where as in 2013 I have seen it working pretty fine.
Sorry I don't have data to share here but it works fine.
Here is the code below:
function DisablePick()
{
VULoader();
//call this function from OnLoad handler
function VULoader(){
var myLookup1;
alert("Hello..I am Here");
var fetch = "<fetch mapping='logical'>"
+"<entity name='account'>"
+"<attribute name='name'/>"
+"<filter type='and'>"
+"<condition attribute='name' operator='eq' value='Blue Yonder Airlines (sample)' />"
+"</filter>"
+"</link-entity>"
+"</entity>"
+"</fetch>";
myLookup1 = new XrmLookupField("parentaccountid");
myLookup1.AddLockedView(
//sViewId
myLookup1.NewGuid() ,
//sEntityName
"account",
//sViewDisplayName
"My Locked Custom View",
//sFilterXml
fetch,
//sFilterLayout
layout(1, "name", "accountid")
.column("name", 200)
.toString()
);
}
function XrmLookupField(sId) {
var xlf = this;
//control instance
xlf.Ctl = Xrm.Page.getControl(sId);
//dom instance
xlf.Dom = document.getElementById(sId);
//jquery instance
xlf.$ = $(xlf.Dom);
/* 2013 addition --- Inline Control instance --- */
xlf.$i = $("#" + sId + "_i");
//use that to disable the view picker
xlf.DisableViewPicker = function () {
/* 2013 addition --- The attribute capitalization changed */
xlf.SetParameter("disableviewpicker", "1");
}
//use that to enable the view picker
xlf.EnableViewPicker = function () {
/* 2013 addition --- The attribute capitalization changed */
xlf.SetParameter("disableviewpicker", "0");
}
//set undocumented attributes
xlf.SetParameter = function (sName, vValue) {
xlf.$.attr(sName, vValue);
/* 2013 addition --- Also change the inline contorl value */
xlf.$i.attr(sName, vValue);
}
//add locked view
xlf.AddLockedView = function (sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout) {
//first enable the view picker
xlf.EnableViewPicker();
//add the custom view (last parameter set the view as default)
xlf.Ctl.addCustomView(sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout, true);
//lock the view picker
xlf.DisableViewPicker();
}
//create new guid
xlf.NewGuid = function () {
var d = new Date().getTime();
var guid = '{xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx}'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return guid;
}
}
}
Few points to mention:
I am calling DisablePicker method on load of an opportunity page.
Yes, I have already checked whether any duplicate id is there or not but I didn't find any.
I tried to run this method on load of Account field as well but nope no response.
If I change the property disableviewpicker value from 0 to 1 in DIV itself manually from browser after page gets loaded & open the lookup then it will take the effect of the changed value.
Really I am getting no clue why it's behaving this manner, I just need to know where exactly I am going wrong or it's a product bug but I don't think it is. As its a very basic behavior.
PS: For my non MS CRM friends I cannot change the DIV or anything except my JavaScript code.
Your form code executes in a frame that is separate from the actual CRM form; it runs in the ClientApiWrapper.aspx page. Therefore, to access the form element you want to modify from your form script, you form code should do parent.document.getElementById instead of document.getElementById.
When you use your browser's dev tools, the default frame that the console executes against is also not the frame that has your form elements, and it's also not the frame that has your form's code. The simplest way to execute against the correct frame is to use the function in your dev tools to switch frames. In Firefox, that button looks like this:
It's easiest to set your frame to the ClientApiWrapper.aspx one, as it provides access to both the libraries loaded on your form as well as the CRM client-side API.
i would like to clear my old post in my Facebook timeline.
I have tried using JS to automate this operation, but I am not able to make the goal.
The strange thing, for me, is that if I try the single steps they works fine, when I put all together it doesn't work.
Selecting the Story options button to open the menu (it works)
Clicking the “Delete” item in the submenu, it works putting a little delay,
Selecting - and clicking - the confirm button to delete the post (it doesn't workss)
Trying to selecting the Confirm button (Delete Post) it is null.
But if I try to execute the step no. 3 after 1 and 2 it works.
This is my code, I run it from the Firefox Scratchpad (Shift+F4) in a specific year section of the timeline (click on a year on facebook.com/me)
// Replace these values if your locale in FB is different from en-US
let l10nALabel="Story options";
let l10nDelete = "Delete";
let l10nCButton = "Delete Post";
// Change this value if the script doesn't works properly
let delay = 1000;
function sleep(delay) {
// Code snippet taken from this post https://stackoverflow.com/questions/1183872/put-a-delay-in-javascrip https://stackoverflow.com/questions/1183872/put-a-delay-in-javascript
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
getElementByText = function(selector, text){
els = document.querySelectorAll(selector);
for (i=0; i<els.length; i++) if ((els[i].textContent==text) && (els[i].children.length==0)) break;
if (i==els.length) return null;
else return els[i];
}
deletePost = function(post, delay){
post.click();
sleep(delay);
let delb = getElementByText("span", l10nDelete);
console.log(delb);
delb.click();
sleep(delay);
let cb = getElementByText("button", l10nCButton);
console.log(cb);
cb.click();
}
let a = document.querySelectorAll('[aria-label="' + l10nALabel + '"]')
deletePost(a[0], delay);
Using javascript to automate commands is not the proper way to do this! Facebook has built in security measures for these practices, and should you succeed in doing it your way the main question qould be why would you do it in such a inefficient way.
We have API's / libraries (official ones) for a reason. You should use the facebook graph API for doing such things. https://developers.facebook.com/docs/graph-api
Trying to play a sound via javascript and want to change it dynamically using sessionstorage
The following is a simplified version that plays sound/s in android/FF Linux/Win when u click the "sprite me button" - I've included other buttons for the example to set and retrieve session values in HTML5.
http://globability.org/webapp/asprite20111124_8.html
The wiki below has Android phone specs where it works: (Samsung Galaxy SII) in case you're interested
http://globability.org/wiki/doku.php?id=current_working_specs_p-tab / also see http://globability.org/wiki/doku.php?id=mobile_pointing_tablet to get a proper idea about what it is that I am working on.
What I need is to have the "play soundsprite" javascript that you can see below in the following section load from sessionstorage and insert values loaded from sessionstorage inserted into an array.
I am not looking for any changes is how the sound is played back - just need to make a dynamically built array work from within the particular javascript.
The code below is based on the soundsprite idea from www.phpied.com/audio-sprites/ by Stoyan Stefanov - made to reduce the http calls needed for playing sounds... Also stabilizes the sound quality, less choppy sound etc.
Antway here goes: YOU ONLY NEED TO LOOK AT PSEUDOCODE SECTION - The rest is functioning
<script>
var thing = 'the thing';
function shut() {
if (typeof thing.pause !== 'undefined') {
thing.pause();
}
}
function log(what) {
document.getElementById('log').innerHTML += what + "<br>";
}
var spriteme = function(){
var sprites = {
// id: [start, length]
'blank':[0.1, 0.5], //This the first sprite, it has to be the first defined and is
called first, it is a blank piece of sound in the combined sound file and needed as of
now.
'success':[13, 2,5],
/* I would like to be able to set the parameters i.e. sound bite to play dynamically -
here a pseudocode example using session storage in preparation for getting the sound
parameters from a database
'wordgen'[null,null];
//this array should be dynamically built from values read from the two session storage keys not sure you need the new thing in HTML5
sessionStorage.globabilitykey1;
sessionStorage.globabilitykey2;
strkey1=globabilitykey1
strkey2=globabilitykey2
var gkey1=parsefloat(strkey1)
var gkey2=parsefloat(strkey2)
'wordgen':[gkey1,gkey2]
and then the idea is to replace the array success in the script with the "generated"
array 'wordgen' to allow dynamic seting of sound to play back */
//the following are sound bites from the collection of soundsprites the site plays from
'word1': [0.5, 2,36], //one
'word2': [3.1, 3.0], //two
'word3': [7.0, 1.82], //three
'word4': [10.03, 2], //four ?
},
song = ['blank', 'success'],
//here you're setting the playback sequence (this is where I would like to replace 'success' with 'wordgen'
current = 0,
id = song[current],
start = 0,
end = sprites[id][1],
int;
thing = document.getElementById('sprite');
thing.play();
log('file: ' + thing.currentSrc);
log(id + ': start: ' + sprites[id].join(', length: '));
// change
int = setInterval(function() {
if (thing.currentTime > end) {
thing.pause();
if (current === song.length - 1) {
clearInterval(int);
return;
}
current++;
id = song[current];
start = sprites[id][0];
end = start + sprites[id][1]
thing.currentTime = start;
thing.play();
log(id + ': start: ' + sprites[id].join(', length: '));
}
}, 10);
};
</script>
Any ideas on how to dynamically create the 'wordgen' array within the javascript based on the values is sessionstorage ?
The whole code/working example can be seen here: http://globability.org/webapp/asprite20111124_8.html
I know the page is one ugly mess... but this is an alpha prototype :)
Argh... it was sooooo simple, I was this close to solving it myself, however a kind freelancer at freelancer.com who has perviously helped me getting one of my ideas to work did it again this time...
And without further ado:
'wordgen':eval("["+sessionStorage.globabilitykey1+","+sessionStorage.globabilitykey2+"]"),
That was what I needed - I had been trying to do the same but without the " eval " in front and the paranthesis around the arguments....
Oh and don't forget to set the value by clicking the button before you try or there will be no sound coming out of your speakers ;)
Here's a link to the working page if you care to try and if you want to see the code in it's "entirity": http://globability.org/webapp/asprite20111201_2.html - Thanks to those of you voting the question up!!!