Cannot set the printBlack printPreference in InDesign - javascript

I've learned an enormous amount of scripting for InDesign CS6 thanks to all of the helpful folks here! Now, it's a problem with setting the printPreferences for a document. Here is the code I have:
with(document.printPreferences) {
activePrinterPreset = outputPreset;
pageRange = outputRange;
for (var j = 0; j < allInks.length; j++) {
document.inks.item(allInks[j]).printInk = false;
}
for (var k = 0; k < printInks.length; k++) {
if (printInks[k].toString() === "Black") {
$.writeln("Found Black!");
printBlack = true;
$.writeln("Set Black!");
} else {
document.inks.item(printInks[k]).printInk = true;
}
}
if (offsetJob) {
// If it's an offset job, we might need to change page sizes.
if (productType === "HI-N13W") {
paperSize = PaperSizes.custom;
paperHeight = 12.5;
paperWidth = 8.5;
} else if (productType.subString(3,5) === "PC") {
paperSize = PaperSizes.custom;
paperHeight = 8;
paperWidth = 12.5;
} else if (couldBeBothJobs.toString().indexOf(productType.subString(3,5)) > -1) {
paperSize = "US Letter";
} else {
paperSize = PaperSizes.custom;
paperHeight = 8;
paperWidth = 25;
}
}
}
In the second for loop, you'll see that I have first turned off ALL of the inks in the document for printing. I then only turn on the ones in the printInks array. If, however, the word "Black" exists in the array, there isn't an Ink for it, so instead, I want to set the built-in printPreference "printBlack". (This complements the other three—printCyan, printMagenta, and printYellow.)
It's just supposed to be a boolean value, according to the InDesign CS6 Object Model Reference. However, whenever the script gets to that point, it halts. Pasting just that small bit of code to a fresh document, just so I can see the error message, gets me this:
The property is not applicable in the current state.
What does this mean? And more importantly, how can I fix it? I know that trapping has to be off before this property can be set, but I've definitely made sure that it is off.

After asking this question on the Adobe Community Forums, I was told that some of the Print Preferences cannot be set directly on the document, but must instead be set on a Print Preset, which, in turn, is then set as the Active Print Preset. Thus, I just re-built the preset I needed and assigned it to a new, temporary one. The following is the result:
try {
tempPreset.name;
}
catch(eNoSuchPreset) {
tempPreset = app.printerPresets.add({name:"tempPreset"});
}
// Let's turn off all of the spot colors before everything else.
for (var j = 0; j < allInks.length; j++) {
document.inks.item(allInks[j]).printInk = false;
}
with(document.printPreferences) {
tempPreset.printer = Printer.POSTSCRIPT_FILE;
tempPreset.ppd = "OYO Imagesetter";
tempPreset.pagePosition = PagePositions.CENTERED;
tempPreset.paperSize = PaperSizes.CUSTOM;
tempPreset.paperHeight = "12.5 in";
tempPreset.paperWidth = "6.5 in";
tempPreset.colorOutput = ColorOutputModes.SEPARATIONS;
tempPreset.trapping = Trapping.OFF;
tempPreset.screening = "60 lpi / 600 dpi";
tempPreset.sendImageData = ImageDataTypes.OPTIMIZED_SUBSAMPLING;
pageRange = outputRange;
// Now let's turn off all of the CMYK colors.
tempPreset.printCyan = false;
tempPreset.printMagenta = false;
tempPreset.printYellow = false;
tempPreset.printBlack = false;
// Then we turn back on BLACK if it exists.
for (var k = 0; k < printInks.length; k++) {
if (printInks[k] === "Black") {
tempPreset.printBlack = true;
} else {
document.inks.item(printInks[k]).printInk = true;
}
}
// If this is a four-color process job, then turn back on all of the process colors.
if (processJob) {
tempPreset.printCyan = true;
tempPreset.printMagenta = true;
tempPreset.printYellow = true;
tempPreset.printBlack = true;
}
// That concludes OYO seps.
}
var mydpp = document.printPreferences;
mydpp.activePrinterPreset = "tempPreset";
That gets my 99% of the way to completing this script. YAY!!

Related

Javascript Hangman Game Running Functions += Times After Reset

Ok this is my very first ever coding project. I'm self taught and thought creating a hangman game my 2 young kiddos could enjoy would be fun.
I have the game coded and it runs perfectly fine the first time through however, once I click on my reset button to restart the game, my lives start going down by 2 instead of one. After a third reset it goes down by three, and so on. Any console.log()s I put in to check run as many times as well.
I've spend hours racking my brain trying to figure it out and I've looked all over and I'm just not getting what's wrong. I thought about just saying screw it and resort to refreshing the page after every play through to avoid the problem but my brain wont let me do that.
Does anyone have any idea how to fix the problem? I know my code is probably not the most efficient and can definitely use to touch ups, but like I said, this is my first ever project and I know efficiency and skill will come with time and practice (like this). Below is the main chunk of my code.
function gameStart() {
// user writes in a word
pickedWord = prompt('pick a word').toUpperCase();
pickLetterHeading.innerText = 'Pick a Letter'
numLivesSec.hidden = false;
startBtn.disabled = true;
gameIsGoing = true;
resetBtn.disabled = false;
// enables buttons to press
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = false;
}
numLives = 7;
numLivesRemaining.innerText = numLives;
// calls the main game function
gameInProgress();
}
function reset() {
startBtn.disabled = false;
pickedWord = '';
gameIsGoing = false;
resetBtn.disabled = true;
pickLetterHeading.hidden = true;
numLivesSec.hidden = true;
while (guessedSec.firstChild) {
guessedSec.removeChild(guessedSec.firstChild);
}
for (let l = 0; l < alphabet.length; l++) {
document.getElementsByClassName('letterBtnClass')[l].disabled = true;
letters[l].classList.replace('correct', 'letterBtnClass');
letters[l].classList.replace('incorrect', 'letterBtnClass');
}
numLives = 7;
}
function gameInProgress() {
pickLetterHeading.hidden = false;
wordInProgress = '';
for (let i = 0; i < pickedWord.length; i++) {
let lettersToGuess = document.createElement('span');
lettersToGuess.innerText = '_';
guessedSec.appendChild(lettersToGuess);
wordInProgress += '_';
}
for (let btn = 0; btn < letters.length; btn++) {
letters[btn].addEventListener('click', function (e) {
letters[btn].disabled = true;
if (pickedWord.indexOf(letters[btn].innerText) == -1) {
console.log('letter not there!');
numLives -= 1;
numLivesRemaining.innerText = numLives;
console.log('TESTING!')
// checks if you have any tries left. If you have 0, then runs game over
if (numLives == 0) {
console.log('GAME OVER!')
gameIsGoing = false;
pickLetterHeading.innerText = 'You lose. Try again.'
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = true;
}
}
}
// checks if the letter picked matches anything in the chosen word
for (let x = 0; x < pickedWord.length; x++) {
if (letters[btn].innerText == pickedWord[x]) {
// adds class to chosen letter to show you guess correctly
letters[btn].classList.add('correct');
document.getElementsByTagName('span')[x].innerText = pickedWord[x];
wordInProgress[x] = pickedWord[x];
// if picked letter matches something in the chosen word, changes the "_" to the correct letter to show user progress
String.prototype.replaceAt = function (index, char) {
let a = this.split("");
a[index] = char;
return a.join("");
}
wordInProgress = wordInProgress.replaceAt(x, pickedWord[x]);
// when the word is complete. will show you win
if (wordInProgress == pickedWord) {
console.log("WINNER WINNER CHICKEN DINNER!");
pickLetterHeading.innerText = 'YOU WIN!'
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = true;
}
}
} else {
// since you chose incorrectly it adds a class to the button to show a bad choice
letters[btn].classList.add('incorrect');
}
}
})
}
}

How to change font color to a specific line in this code?

Surely there must be a way to add some color to the line in the code below where it shows m.codeletters = "&#+%?£#§$"; etc? I want to change the color to : **"&#+%?£#§$"**
var Messenger = function(el){
'use strict';
var m = this;
m.init = function(){
m.codeletters = "&#*+%?£#§$";
m.message = 0;
m.current_length = 0;
m.fadeBuffer = false;
m.messages = [
'readers',
'via feed',
'👽'
];
setTimeout(m.animateIn, 100);
};
m.generateRandomString = function(length){
var random_text = '';
while(random_text.length < length){
random_text += m.codeletters.charAt(Math.floor(Math.random()*m.codeletters.length));
}
return random_text;
};
m.animateIn = function(){
if(m.current_length < m.messages[m.message].length){
m.current_length = m.current_length + 2;
if(m.current_length > m.messages[m.message].length) {
m.current_length = m.messages[m.message].length;
}
var message = m.generateRandomString(m.current_length);
$(el).html(message);
setTimeout(m.animateIn, 20);
} else {
setTimeout(m.animateFadeBuffer, 20);
}
};
m.animateFadeBuffer = function(){
if(m.fadeBuffer === false){
m.fadeBuffer = [];
for(var i = 0; i < m.messages[m.message].length; i++){
m.fadeBuffer.push({c: (Math.floor(Math.random()*12))+1, l: m.messages[m.message].charAt(i)});
}
}
var do_cycles = false;
var message = '';
for(var i = 0; i < m.fadeBuffer.length; i++){
var fader = m.fadeBuffer[i];
if(fader.c > 0){
do_cycles = true;
fader.c--;
message += m.codeletters.charAt(Math.floor(Math.random()*m.codeletters.length));
} else {
message += fader.l;
}
}
$(el).html(message);
if(do_cycles === true){
setTimeout(m.animateFadeBuffer, 20);
} else {
setTimeout(m.cycleText, 2000);
}
};
m.cycleText = function(){
m.message = m.message + 1;
if(m.message >= m.messages.length){
m.message = 0;
}
m.current_length = 0;
m.fadeBuffer = false;
$(el).html('');
setTimeout(m.animateIn, 200);
};
m.init();
}
console.clear();
var messenger = new Messenger($('#messenger'));
I have looked up and down, to try and see where in the code I can do this. I also want to know what I need to add to be able to do this. I simply have no clue. I've seen other codes of similar where the codeletter area is colored, then the rest of the text another color.
If you're trying to color console output, you would use ANSI escape sequences that look something like this \u001b[31;1m, and which you can learn more about in this SO post. There is also an npm module available called colors that greatly simplifies the process of implementing them.
If you're trying to color HTML output, you would just wrap each character in an individual <span> element and add a class or style attribute with CSS-styling for the desired color.

JavaScript click works in console but not inside Selenium execute_script

I am using Selenium to test a site, the idea is to get all rows from a table, select the visible buttons then click them. Once clicked an event is triggered and with AJAX data is loaded right under the rows.
The following code works perfectly inside the Firefox console. Actually clicks so fast that items are all loaded at once (there are max 10 rows so I would not bother to add a wait event).
function button_visible(row) {
var opacity = row.style.opacity;
if (opacity == "" || opacity == 1) {
return true;
} else {
return false;
}
}
var table = document.querySelectorAll('div>.table');
for (x = 1; x < table.length; x++) {
row = table.item(x);
var row_buttons = row.querySelectorAll('icon-button');
for (var i = 0; i < row_buttons.length; i++) {
if (button_visible(row_buttons.item(i))) {
row_buttons.item(i).click();
}
}
}
Running this JavaScript from Selenium doesn't not work:
js='function button_visible(row) {var opacity = row.style.opacity; if (opacity === "" || opacity == 1) {return true;} else {return false;}} var table = document.querySelectorAll('div>.table'); for (x = 1; x < table.length; x++) {var row = table.item(x); var row_buttons = row.querySelectorAll('icon-button'); for (var i = 0; i < row_buttons.length; i++) {if(button_visible(row_buttons.item(i))){ row_buttons.item(i).click();}}}'
driver.execute_script(js)
Added come console.log's, they show up in the console but the click event is not triggered at all. Funny enough, after trying to run the code with Selenium, running the JavaScript from console does not work as well.
I also tried to return these rows as an array and click with Selenium but this just makes things complicated as I get stale element exception. To make sure it works I need to re-fetch the table rows after each click etc.
I cannot even think a reason why this would not work. Any opinions?
Try the following:
driver.execute_script("""
function button_visible(row) {
var opacity = row.style.opacity;
if (opacity == "" || opacity == 1) {
return true;
} else {
return false;
}
}
var table = document.querySelectorAll('div>.table');
for (x = 1; x < table.length; x++) {
row = table.item(x);
var row_buttons = row.querySelectorAll('icon-button');
for (var i = 0; i < row_buttons.length; i++) {
if (button_visible(row_buttons.item(i))) {
row_buttons.item(i).click();
}
}
}
""")
PS: For running multiline JS in Selenium (Python) should be used """ (start and end).
Hope it helps you!

Does not execute the code after a for within a function

Good! I have a problem and you do not run my code at the end of the loop, the above and what is inside the loop works fine, the problem is that after the loop is still not executing the code. Any idea why it can be?
This is my code:
var arrayp = new Array();
function botonAdelante(tabl, pasos)
{
var padreTabla = document.getElementById(tabl).rows;
var cont = 0;
for(var j = 0; j < padreTabla.length; j++)
{
var hijoTd = document.getElementById(pasos+ "-producto-" +j);
var childArray = hijoTd.children;
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}
}
alert("It is in this part of the code does not work");
}
Clarification: "continue" found at the end of long and if it will not work either.
The continue is confusing used like this, but I have a feeling your code is probably throwing an error because the cont might exceed the array length. Regardless of whether this fixes it or not I'd at least add a check to ensure that it doesn't throw an exception.
Please check for exceptions being thrown through web dev tools (F12 in Chrome).
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true && arrayp.length <= cont)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}

Hide/Show Table Columns with Javascript (fix for all browsers?)

I have a long table with many many columns and it looks really ugly for the users. What I wanted to do was create a simple button that would act as a switch, to turn on and off some of the columns.
Some of the columns are not needed, so what I did was add a class to every that wasn't needed, eg: ....
Now, what I thought I could do was this:
var hidden = 1;
function toggleTable(){
element_array = document.getElementsByClassName('disabled');
for(i = 0; i < element_array.length; i++){
if(hidden == 1){
element_array[i].style.display = 'none';
}else{
element_array[i].style.display = '';
}
}
if(hidden == 1) hidden = 0;
else hidden = 1;
}
This works for the most part in Firefox, but some quick tests in IE(7+8) and I get the following:
Message: Object doesn't support this property or method
Obviously indicating that IE doesn't want to let me simply change "display: none;" for something like table columns/rows.
I can't think of any workarounds. Ideally I'd like a fully cross-compatible solution to toggling the display of certain table columns,but if it's not compatible in the older browsers (eg: IE6) then that would also be OK.
The error that you're getting is not because IE doesn't want to set the display property, it's because the getElementsByClassName method isn't implemented in IE. If you want an implementation of that methods you can use this one which was written by Dustin Diaz.
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
Then you would re-write your method as follows.
var hidden = 1;
function toggleTable(){
var element_array = getElementsByClass('foo');
for(i = 0; i < element_array.length; i++){
if(hidden == 1){
element_array[i].style.display = 'none';
}else{
element_array[i].style.display = '';
}
}
if(hidden == 1) hidden = 0;
else hidden = 1;
}
toggleTable();
And what about jQuery.toggle()?
$(".disabled").toggle();

Categories