Indesign 2020 ScriptUI add text frame - javascript

I have a problem with a script for Indesign 2020.
I am not a programmer and don't know javascript (I just created some simple script).
I want to create a simple panel with a button that add a textframe, but doesn't seems to work.
Here's the code
var document = app.activeDocument;
document.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.MILLIMETERS;
document.viewPreferences.verticalMeasurementUnits = MeasurementUnits.MILLIMETERS;
app.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
app.activeDocument.zeroPoint = [0,0];
var Labelpanel = new Window("dialog");
Labelpanel.text = "Printer";
Labelpanel.orientation = "column";
Labelpanel.alignChildren = ["center","top"];
Labelpanel.spacing = 10;
Labelpanel.margins = 16;
var Button1 = Labelpanel.add("button", undefined, undefined, {name: "Button 1"});
Button1.text = "Magenta 1";
Button1.onClick = function() {
var Label = document.pages[0].textFrames.add();
Label.properties = {
geometricBounds : [ 25,284.5,15,226.5 ],
contents : "1234_Mag1"
}
Label.paragraphs[0].appliedFont = app.fonts.item("Arial");
Label.paragraphs[0].pointSize = "30";
Label.paragraphs[0].justification = Justification.RIGHT_ALIGN;
Labelpanel.close();
}
Labelpanel.show();
The code in the button normally works, but in ScriptUI it does nothing.
Can someone tell me what am I doing wrong?

In your case the script will work (I'm not sure about your goal, though) if you add this line:
#targetengine session
at the start of the code.
And change "dialog" with "palette" here:
var Labelpanel = new Window("palette");
The problem is a dialog window can't change a document until the dialog will be closed.
Not like a palette that has access to documents always.
Your script can be rewritten in order to use a dialog window instead of palette. But it will need to change more than just two lines.
Update
Here is the example how it can be done with a dialog window:
// set the dialog window
var labelDialog = new Window("dialog");
labelDialog.text = "Printer";
labelDialog.orientation = "column";
labelDialog.alignChildren = ["center","top"];
labelDialog.spacing = 10;
labelDialog.margins = 16;
// set a variable that we will convey to the main function
var contents = '';
// a couple buttons
var button1 = labelDialog.add("button", undefined, undefined, {name: "Button 1"});
button1.text = "Magenta 1";
var button2 = labelDialog.add("button", undefined, undefined, {name: "Button 2"});
button2.text = "Magenta 2";
// if click --> change the variable an close the dialog
button1.onClick = function() {contents = '1234_Mag1'; labelDialog.close()};
button2.onClick = function() {contents = '5678_Mag2'; labelDialog.close()};
labelDialog.show(); // show the dialog
// if the variable is not empty --> run the main function
if (contents != '') main(contents);
// the main function, get the variable and does the work
function main(contents) {
app.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
app.activeDocument.zeroPoint = [0,0];
var document = app.activeDocument;
document.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.MILLIMETERS;
document.viewPreferences.verticalMeasurementUnits = MeasurementUnits.MILLIMETERS;
var label = document.pages[0].textFrames.add();
label.properties = {
geometricBounds: [ 25,284.5,15,226.5 ],
contents: contents // <-- our variable goes here
}
label.paragraphs[0].appliedFont = app.fonts.item("Arial");
label.paragraphs[0].pointSize = "30";
label.paragraphs[0].justification = Justification.RIGHT_ALIGN;
}
I've made two buttons. I suspect it would be your next question: "How to add more buttons?"
The main point: A dialog window should be closed before you try to change a document. A palette should not. This 'subtle difference' changes the algorithm significantly.

Related

Creating Bootstrap Modal Dialog using JavaScript

I am trying to create a Bootstrap Modal dialog using JavaScript. The reason I am doing it with JavaScript is because I want to be able to render it later using custom elements (i.e. title, error message). I am fairly new to JavaScript so I do not understand why the code is not executed when I call the function errorMessage(). Can anyone please help out by letting me know what the mistake is and how I can correct it? Is there a more efficient way of doing it? Thank you very much.
By the way I did link the modal.js file to the HTML doc and I am aware of bootboxjs, but I don't want to use it for now.
// Creation of the alert message box.
function errorMessage() {
var Modal = document.createElement('div');
Modal.id = 'myModal';
Modal.className = 'modal fade show';
// To set up the attributes.
Modal.setAttribute("data-backdrop", "static");
Modal.setAttribute("data-keyboard", false);
document.body.appendChild(Modal);
var dialog = document.createElement('div');
dialog.className = 'modal-dialog';
Modal.appendChild(dialog);
var content = document.createElement('div');
content.className = 'modal-content';
dialog.appendChild(content);
var header = document.createElement('div');
header.className = 'modal-header';
content.appendChild(header);
var title = document.createElement('h4');
title.className = 'modal-title';
title.createTextNode = 'Data Error';
header.appendChild(header);
var body = document.createElement('div');
body.className = 'modal-body';
dialog.appendChild(body);
var message = document.createElement('p');
message.createTextNode("Oh... snap. We can't find any items in your list. Please make sure your entry is structured as following:");
body.appendChild(message);
var representation = document.createElement('div');
representation.className = 'well';
body.appendChild(representation);
var representationTxt = document.createElement('p');
representationTxt.style.fontStyle = 'italic';
representationTxt.createTextNode('> Subheader , tag1 , tag2, tag3');
representation.appendChild(representationTxt);
var footer = document.createElement('div');
footer.className = 'modal-footer';
dialog.appendChild(footer);
var closeBtn = document.createElement('button');
closeBtn.setAttribute("data-dismiss", "modal");
closeBtn.setAttribute("type", "button");
closeBtn.className = 'btn btn-primary btn-inverse';
closeBtn.value = 'I got it. Thanks.';
footer.appendChild(closeBtn);
// Show modal dialog box
$("#myModal").modal('show');
}
It is failing on this line: header.appendChild(header); because it cannot append header to itself. Did you mean this?
var title = document.createElement('h4');
title.className = 'modal-title';
title.createTextNode = 'Data Error';
header.appendChild(title);
A debugging tool is invaluable in javascript development (Firebug add-on for Firefox or the built-in tools in Chrome, for example). You would have seen this error right away :)

Trying to generate a button-based interface in javascript

I am trying to build an interface with javascript. The interface is a grid of buttons. Each row is a different musical instrument and on each column you have a rhythm pattern you can trigger.
When the user click on a button, I want it to change its class so the background-color changes, telling to user it's been activated.
The problem is, my script is always targeting the last button of a row. When I try to force it to target a specific button (which is NOT the last button), it says the button in "undefined".
pattern1 = ["Clave 1",[1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0],"description"];
pattern2 = ["Clave 2",[1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,0,1],"description"];
pattern3 = ["Clave 3",[1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1],"description"];
pattern4 = ["Clave 4",[1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0],"description"];
pattern5 = ["Clave 5",[1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1],"description"];
pattern6 = ["Clave 6",[1,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0],"description"];
pattern7 = ["Clave 7",[1,0,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,1],"description"];
pattern8 = ["Clave 8",[1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0],"description"];
var pattern_collection = [pattern1, pattern2, pattern3, pattern4, pattern5, pattern7, pattern8];
function generate_buttons(instrument_id) {
for (var key in pattern_collection)
{
//creating an array of button for each instrument
var button = new Array();
//creating the button label
var button_text;
button_text = document.createTextNode(pattern_collection[key][0]);
//creating the button in the DOM
button[key] = document.createElement('div');
//by default, the first pattern is shown as playing
if (pattern_collection[key]==pattern1)
button[key].className = "isplaying_pattern_button";
else
button[key].className = "notplaying_pattern_button";
button[key].onclick = function() {
//picking the currently playing button to change its class to not playing
var playing_button = document.querySelector("#"+instrument_id+" .isplaying_pattern_button");
playing_button.className = "notplaying_pattern_button";
//this is where the problem occurs: the script is always targeting the last button of the row
button[key].className = "isplaying_pattern_button";
};
button[key].appendChild(button_text);
var instrument_patterns = document.getElementById(instrument_id);
instrument_patterns.appendChild(button[key]);
}
}

Dynamic img creation through a link without attaching multiple instances

I have a link that is attached with an "onclick" function. When pressed it attaches an img element into a separate div called "mediaBox". The problem I'm having is that if it's pressed multiple times then it attaches more instances of the img. How can I control this. I'm still new to JavaScript and I prefer to receive this answer in pure Javascript not jQuery, as I will cross that bridge after I have a full understanding of Javascript.
var rkf = document.getElementById("submenulinks").getElementsByTagName("li")[0];
rkf.onclick = function(){
var client = document.getElementById('client');
var description2 = document.getElementById('description2');
var role = document.getElementById('role');
var mediaBox = document.getElementById('mediaBox');
var thumb = document.getElementById("thumb");
var client2 = document.getElementById("client2");
var newImage = document.createElement("img");
client2.innerHTML = "Role - Applications";
client.innerHTML = "RKF Real Estate";
client2.innerHTML = "Role - Applications";
description2.innerHTML = "Quarterly Catalog of Exclusive Listings managed by RKF";
role.innerHTML = "Custom designed Cover and listings content. Tables were also utilized within Indesign. <br><br><b><i> Photoshop and Indesign</i></b>";
newImage.setAttribute("src", "../images/rkf_cover.jpg");
newImage.setAttribute("height", "500px");
newImage.setAttribute("width", "387px");
newImage.setAttribute("alt", "rkf");
newImage.setAttribute("href", "#");
mediaBox.style.backgroundImage = "none";
document.getElementById("mediaBox").appendChild(newImage);
newImage.style.display = "block";
newImage.style.marginLeft = "auto";
newImage.style.marginRight = "auto";
newImage.style.marginTop = "25px";
}
rkf.onclick = function(){
var client = document.getElementById('client');
...
...
...
// Remove the handler after it ran once.
this.onclick = null; // <<<<<========================
}
Since you do want to use jQuery in the future, it's equal to:
$('#submenulinks li:first').one('click', handler);

Open a blank window, write to it, and select the written text

I'm trying to open a blank window with Javascript, write text to it, and then select the text that I wrote, all automatically.
I have:
var myWindow=window.open('');
myWindow.document.write("hey");
myWindow.select();
which opens the window and writes the text, but does not select it.
This should do it:
var myWindow=window.open('');
myWindow.document.write("<div id='hello'>hey<div>");
var range = myWindow.document.createRange();
range.selectNode(myWindow.document.getElementById('hello'));
myWindow.getSelection().addRange(range);
myWindow.select();
var popup = window.open('message.html',"'" + name + "'",'height=300,width=300,location=no,resizable=yes,scrollbars=yes');
var element = document.createElement('div');
element.setAttribute('id', 'mydiv');
element.appendChild(document.createTextNode('blah blah'));
popup.window.onload = function() {
var win = popup.document.body;
win.appendChild(element);
var el = popup.window.document.getElementById('mydiv').innerHTML;
alert(el); //tested - ouputs 'blah blah'
};

Confirm replacement in JavaScript

Yes, I've searched high and low on Stack Overflow and seen some great solutions to this problem that's been solved time and time again with things like SimpleModal, jQuery.confirm and the like.
Problem is, I am developing for this low level device that doesn't allow for a JS framework to be utilized AND I am having to shoehorn this modal confirm into existing JS.
There is an existing script that I am at liberty to edit (but not rewrite) that does a few things like validate, concatenate a few inputs into a single variable, and more.
The script was written to:
Take some session variables and assign new variable names to them and format accordingly
Present a confirm to the user to see whether they want to use those variables to pre-populate the form on the page
Get some functions ready to validate inputs.
other stuff, like offer an abandonment scenario, among other things
Now, all was good when the "confirm" was in place as the script would pause until an OK or Cancel was provided. I am now presenting a modal on the page that I want to mock this behavior and the only way I can think of doing it is to remove that reliance on the line that goes through the confirm thing and NOT run the script until the user interacts with the modal.
Does anyone have an idea how to take what's in place and "wrap" it in a "listening" if/else scenario for each of the YES or NO possibilities?
Sorry if this is jumbled... my brain is all blended up at the moment, too.
As far as I know there is - so far - no way to halt scripts like the Browser specific alert() or confirm() Dialog does.
Frameworks like dojo for example try to mock this behaviour by putting a transparent DIV over the whole window to prevent clicks or other input while the Dialog is showing.
This is quite tricky as I have experienced, since Keyboard-Input may be able to activate Input Fields or Buttons behind this curtain. Keyboard Shortcuts or Field-Tabbing for example.
One sollution is to disable active Elements manually, which works quite well with me in most cases.
One or more function is passed to this "mock" Dialog to execute when an option was chosen.
Escpecially with ajax background activity the responsibilty to stop conflicting function calls while the Dialog is open lies with the developer.
Here is an example I came up with:
<html>
<head>
<title>Modal Dialog example</title>
<script type="text/javascript">
<!--
var ModalDialog = function(text,choices){
this._text = text;
this._choices = choices;
this._panel = null;
this._modalDialog = null;
this._disableElements = function(tag){
var elements = document.getElementsByTagName(tag);
for(i=0; i < elements.length; i++){
elements[i].disabled = true;
}
};
this._enableElements = function(tag){
var elements = document.getElementsByTagName(tag);
for(i=0; i < elements.length; i++){
elements[i].disabled = false;
}
};
this._disableBackground = function(){
if(this._panel){
this._panel.style.display = 'block';
}
else{
// lower the curtain
this._panel = document.createElement('div');
this._panel.style.position = 'fixed';
this._panel.style.top = 0;
this._panel.style.left = 0;
this._panel.style.backgroundColor = 'gray';
this._panel.style.opacity = '0.2';
this._panel.style.zIndex = 99; // make sure the curtain is in front existing Elements
this._panel.style.width = '100%';
this._panel.style.height = '100%';
document.body.appendChild(this._panel);
// Disable active Elements behind the curtain
this._disableElements('INPUT');
this._disableElements('BUTTON');
this._disableElements('SELECT');
this._disableElements('TEXTAREA');
}
};
this.close = function(){
// Hide Curtain
this._panel.style.display = 'none';
// Hide Dialog for later reuse - could also be removed completely
this._modalDialog.style.display = 'none';
// reactivate disabled Elements
this._enableElements('INPUT');
this._enableElements('BUTTON');
this._enableElements('SELECT');
this._enableElements('TEXTAREA');
};
this.open = function(){
var _this = this;
this._disableBackground();
if(this._modalDialog){
this._modalDialog.style.display = 'block';
}
else{
// create the Dialog
this._modalDialog = document.createElement('div');
this._modalDialog.style.position = 'absolute';
this._modalDialog.style.backgroundColor = 'white';
this._modalDialog.style.border = '1px solid black';
this._modalDialog.style.padding = '10px';
this._modalDialog.style.top = '40%';
this._modalDialog.style.left = '30%';
this._modalDialog.style.zIndex = 100; // make sure the Dialog is in front of the curtain
var dialogText = document.createElement('div');
dialogText.appendChild(document.createTextNode(this._text));
// add Choice Buttons to the Dialog
var dialogChoices = document.createElement('div');
for(i = 0; i < this._choices.length; i++){
var choiceButton = document.createElement('button');
choiceButton.innerHTML = this._choices[i].label;
var choiceAction = _this._choices[i].action
var clickAction = function(){
_this.close();
if(choiceAction)choiceAction();
};
choiceButton.onclick = clickAction;
dialogChoices.appendChild(choiceButton);
}
this._modalDialog.appendChild(dialogText);
this._modalDialog.appendChild(dialogChoices);
document.body.appendChild(this._modalDialog);
}
};
};
var myConfirm = function(text,okAction){
var dialog = new ModalDialog(text,[
{
label:'ok',
action : function(){
console.log('ok')
okAction();
}
},
{
label:'cancel'
}
]);
dialog.open();
};
-->
</script>
</head>
<body>
<form name="identity" action="saveIdentity.do">
<label>Firstname</label><input name="name" type="text"><br>
<label>Lastname</label><input name="name" type="text"><br>
<input type="button"
value="submit"
onclick="if(myConfirm('Do you really want to Commit?',function(){ document.forms['identity'].submit();}));">
</form>
</body>
</html>
In this code there is still an error concerning the availability of the stored choice-function (undefined) at execution time. The function variable is no longer available in the closure. If anyone has a sollution for this you are welcome to add to it.
Hope that comes near to what you need to know.
Updated version: fixed choiceAction undefined, added IE compatibility. Internet Explorer is one main reason to use this, since confirm() is now blocked by default.
<!doctype html>
<html><head>
<title>Modal Dialog example</title>
<script type="text/javascript"><!-- //http://stackoverflow.com/questions/4739740/yet-another-confirm-replacement-quesiton
var ModalDialog = function(text,choices) {
this._text = text;
this._choices = choices;
this._panel = null;
this._modalDialog = null;
this._disableElements = function(tag) {
var elements = document.getElementsByTagName(tag);
for(i=0; i < elements.length; i++) {
elements[i].disabled = true;
}
};
this._enableElements = function(tag) {
var elements = document.getElementsByTagName(tag);
for(i=0; i < elements.length; i++) {
elements[i].disabled = false;
}
};
this._disableBackground = function() {
if(this._panel) {
this._panel.style.display = 'block';
}
else {
// lower the curtain
this._panel = document.createElement('div');
this._panel.style.position = 'fixed';
this._panel.style.top = 0;
this._panel.style.left = 0;
this._panel.style.backgroundColor = '#000';
this._panel.style.opacity = '0.3';
this._panel.style.filter = 'alpha(opacity=30)'; //ie7+
this._panel.style.zIndex = 99; // make sure the curtain is in front existing Elements
this._panel.style.width = '100%';
this._panel.style.height = '100%';
document.body.appendChild(this._panel);
// Disable active Elements behind the curtain
this._disableElements('INPUT');
this._disableElements('BUTTON');
this._disableElements('SELECT');
this._disableElements('TEXTAREA');
}
};
this.close = function() {
// Hide Curtain
this._panel.style.display = 'none';
// Hide Dialog for later reuse - could also be removed completely
this._modalDialog.style.display = 'none';
// reactivate disabled Elements
this._enableElements('INPUT');
this._enableElements('BUTTON');
this._enableElements('SELECT');
this._enableElements('TEXTAREA');
};
this.open = function() {
var _this = this;
this._disableBackground();
if(this._modalDialog) {
this._modalDialog.style.display = 'block';
}
else {
// create the Dialog
this._modalDialog = document.createElement('div');
this._modalDialog.style.position = 'absolute';
this._modalDialog.style.backgroundColor = 'white';
this._modalDialog.style.border = '1px solid black';
this._modalDialog.style.padding = '16px';
this._modalDialog.style.top = '35%';
this._modalDialog.style.left = '30%';
this._modalDialog.style.zIndex = 100; // make sure the Dialog is in front of the curtain
var dialogText = document.createElement('div');
dialogText.style.padding = '0 10px 10px 0';
dialogText.style.fontFamily = 'Arial,sans-serif';
dialogText.appendChild(document.createTextNode(this._text));
// add Choice Buttons to the Dialog
var dialogChoices = document.createElement('div');
for(i = 0; i < this._choices.length; i++) {
var choiceButton = document.createElement('button');
choiceButton.style.marginRight = '8px';
choiceButton.name = i;
choiceButton.innerHTML = this._choices[i].label;
var clickAction = function() {
_this.close();
if(_this._choices[this.name].action) _this._choices[this.name].action();
};
choiceButton.onclick = clickAction;
dialogChoices.appendChild(choiceButton);
}
this._modalDialog.appendChild(dialogText);
this._modalDialog.appendChild(dialogChoices);
document.body.appendChild(this._modalDialog);
}
};
};
var myConfirm = function(text,okAction){
var dialog = new ModalDialog(text,[
{
label : 'OK',
action : function() {
console.log('ok');
okAction();
}
},
{
label : 'Cancel'
}
]);
dialog.open();
};
-->
</script>
</head>
<body>
<form name="identity" action="saveIdentity.do">
<label>Firstname</label><input name="name" type="text"><br>
<label>Lastname</label><input name="name" type="text"><br>
<input type="button" value="submit"
onclick="if(myConfirm('Do you really want to Commit?',function(){ alert('submitted') }));">
<!-- document.forms['identity'].submit(); -->
</form>
</body>
</html>

Categories

Resources