Script to Change selected item to a Swatch Color - javascript-objects

I have a basic JavaScript that should change the selected item from CMYK Black to a Swatch Color Named Bronze but it's not working. Any advice on haw the code should look?
// Get the active document
var doc = app.activeDocument;
// Check if there is a selection
if (doc.selection.length > 0) {
// Get the first selected object
var obj = doc.selection[0];
// Check if the object has a fill
if (obj.fillColor > 0) {
// Set the object's fill color to the "Bronze" swatch
obj.fillColor = 5;
}
}

Change your code to this, this works, I have tested it.
// Get the active document
var doc = app.activeDocument;
// Check if there is a selection
if (doc.selection.length > 0) {
// Get the first selected object
var obj = doc.selection[0];
//change your code to lines below ---v
if (obj.filled)
obj.fillColor = activeDocument.swatches["Bronze"].color
}

Related

How do you use multiple scripts in the same spreadsheet?

I have a spreadsheet that tracks legal cases from start to finish. In that spreadsheet I used a script to create dependent dropdown menus on multiple rows (I'll share the script at the end). The main dropdown menu tells me what Department the case is in. The Departments are Transcription; Doctor; Scheduling; Records; QA; and Billing.
I also have a script that is supposed to moves an entire row of data to a separate tab labeled Billing when the department dropdown menu is set to Billing. I had this script working before I made the dependent dropdown menus and was just using data validation to create my dropdown menu.
Both of these scripts work separately but when I try to use them together the dependent dropdown menus quit working and when the department is set to Billing that row disappears like its supposed to except it doesn't show up on the Billing tab like its supposed to. I have no idea where it goes.
Can someone please tell me how to get both scripts to work at the same time? And, why the row of data disappears when the department is set to Billing but doesn't go to the Billing tab?
Dependent Dropdown Menu Script
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Database");
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("options");
var options = wsOptions.getRange(2,1,wsOptions.getLastRow()-1,2).getValues();
function myFunction() {
var list = ["a","b","c","f"];
var cell = ws.getRange("J2");
applyValidationToCell(list,cell);
}
function onEdit(event){
var activeCell = event.range;
var value = activeCell.getValue();
var row = activeCell.getRow();
var column = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName == "Database" && column === 5 && row > 1){
if(value === ""){
ws.getRange(row,10).clearContent();
ws.getRange(row,10).clearValidations();
} else{
ws.getRange(row,10).clearContent();
var filteredOptions = options.filter(function(options){ return options[0] === value });
var listToApply = filteredOptions.map(function(options){ return options[1] });
Logger.log(listToApply);
var cell = ws.getRange(row,10);
applyValidationToCell(listToApply,cell);
}
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
Billing Script
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Database");
var wsOptions = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("options");
var options = wsOptions.getRange(2, 1,wsOptions.getLastRow()-1,2).getValues();
function myFunction() {
var list = ["a","b","g"];
var cell = ws.getRange("K2");
applyValidationToCell(list,cell);
}
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getName();
if(wsName == "Database" && c === 5 && r > 1){
var filteredOptions = options.filter(function(o){return o[0] === val});
var listToApply = filteredOptions.map(function(o){ return o[1]});
console.log(listToApply);
var cell = ws.getRange(r, 10);
applyValidationToCell(listToApply,cell);
}
}
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp
.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if (r.columnStart != 5|| r.rowStart == 2 || e.value == src.getName()) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(e.value);
src.getRange(r.rowStart,1,1,30).moveTo(dest.getRange(dest.getLastRow()+1,1,1,30));
src.deleteRow(r.rowStart);
}
All functions have to have a unique name and all functions have access to all sheets. onedit triggers are generated on every user edit and it's up to the onEdit function to route edits from the appropriate sheets using information gathered from the event object. Note: Sheet Name = e.range.getSheet().getName() where e is populated by the event object in the function declaration function onEdit(e) {}
The if statement below limits access to edits that occur on Sheet name "Database" and e.range.columnStart == 5 and rows greater than one
if(wsName == "Database" && column === 5 && row > 1){
if(value === ""){
ws.getRange(row,10).clearContent();
ws.getRange(row,10).clearValidations();
} else{
ws.getRange(row,10).clearContent();
var filteredOptions = options.filter(function(options){ return options[0] === value });
var listToApply = filteredOptions.map(function(options){ return options[1] });
Logger.log(listToApply);
var cell = ws.getRange(row,10);
applyValidationToCell(listToApply,cell);
}
}
if you require actions from other sheets then you must add more if statements or other conditional logic to route the appropriate edit traffic to the the correct processing statements.

Flashcards Test/Memorization in Andoird Studio/Kotlin

Sorry for the long post! I am trying to make a memorization flashcard and I have been stuck with this for a week
Here is the array
val sentenceArray = arrayOfNulls<String>(8)
sentenceArray[0] = ""
sentenceArray[1] = "Array 1 (1)"
sentenceArray[2] = "Array 2 (2)"
sentenceArray[3] = "Array 3 (3)"
sentenceArray[4] = "Array 4 (4)"
sentenceArray[5] = "Array 5 (5)"
This is the code. To generate the test there are 2 spinners (left and right) If the user selected 1 for the left spinner and 3 on the right spinner then it will only display Array 1 to 3 each time the user clicks on textView
leftSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener
{
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long)
{
//Stores value of the selected Left Spinner
val selectedLeftSpinner = leftSpinner.getItemAtPosition(position).toString()
rightSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener
{
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long)
{
//Actions when buttonStart is clicked
buttonStart.setOnClickListener {
//Stores value of the selected Right Spinner
val selectedRightSpinner = rightSpinner.getItemAtPosition(position).toString()
//Stores selectedLeftSpinner value to firstSentence so that it can be used
var firstSentence = selectedLeftSpinner.toInt()
//Stores selectedRightSpinner value to lastSentence so that it can be used
val lastSentence = selectedRightSpinner.toInt()
//Displays (1)
textView.text = sentenceArray[firstSentence]?.takeLast(3)
//Waiting for an action on the TextView
textView.setOnClickListener {
//Displays (Array 1)
textView.text = sentenceArray[firstSentence]
//Waiting for an action on the TextView
textView.setOnClickListener {
while (firstSentence < lastSentence) {
//This while loop displays Array 1 to 5 each time a user clicks on textView
firstSentence++
textView.text = sentenceArray[firstSentence]
//Ends the test when it reaches the last array
if (firstSentence == lastSentence) {
buttonStart.text = "DONE"
}
break
}
}
}
}
}
}
}
}
What I am trying to do:
After the user selected a value from the left spinner (for example 1) and right spinner (for example 3) They would click on the buttonStart to start the flashcard. The textView starts off displaying a (1). To reveal the answer, they could click on textView and then it will display "Array 1" They would then click on textView and it will display a (2)... etc
So the flow should be like this, after clicking on textView on each step
(1)
Array 1
(2)
Array 2
(3)
Arra3 3
DONE
With my current while loop
while (firstSentence < lastSentence) {
//This loop displays Array 1 to 5 each time a user clicks on textView
firstSentence++
textView.text = sentenceArray[firstSentence]
//Ends the test when it reaches the last aya
if (firstSentence == lastSentence) {
buttonStart.text = "DONE"
}
break
}
This is the current flow
(1)
Array 1
Array 2
Array 3
DONE
I have tried a lot of things but I could not get it to work and I have no idea way
Here are 2 different codes that I tried that did not work. This was inside the while loop
textView.setOnClickListener {
if (textView.text == sentenceArray[firstSentence])
textView.text = sentenceArray[firstSentence]?.takeLast(3)
}
and this code
if (firstSentence < lastSentence)
{
textView.setOnClickListener {
textView.text = sentenceArray[firstSentence]?.takeLast(3)
}
}
The 2 codes result into this flow
(1)
Array 1
Array 2
(2)
DONE when its supposed to continue to (3)
Your dont really need a loop, since looping is handled by the user clicking the text view, in your case an if condition will suffice.
One other thing that I observed is that you are setting up your click listeners and spinner listeners inside other listeneres. this is not required and makes your code unreadable and complex to parse, Please note that in your case you can define all the listeners on the same level to achieve what you want, you dont have to nest them.
You can do something as following. I have lifted out the nested listener configuration.
class Temp {
lateinit var leftSpinner: Spinner
lateinit var rightSpinner: Spinner
lateinit var buttonStart: Button
lateinit var sentenceArray: Array<String>
lateinit var textView: TextView
var selectedLeftSpinner = -1
var selectedRightSpinner = -1
private fun setup() {
/** Define left spinner item selected listener, capture the selected position */
leftSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(
parent: AdapterView<*>?, view: View?,
position: Int, id: Long) {
selectedLeftSpinner = position
}
}
/** Define right spinner item selected listener, capture the selected position */
rightSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(
parent: AdapterView<*>?, view: View?,
position: Int, id: Long) {
selectedRightSpinner = position
}
}
/** Define button start click listener, show text if left spinner is selected. */
buttonStart.setOnClickListener {
/** only set text if left spinner is selecte */
if(selectedLeftSpinner != -1){
textView.text = sentenceArray[selectedLeftSpinner]?.takeLast(3)
}
}
/** Handle edge cases, such as what happens if spinner is not selected */
textView.setOnClickListener {
/** if currently selected item's last 3 chars are being shown,
* then show the answer.
*/
if(textView.text == sentenceArray[selectedLeftSpinner]?.takeLast(3)){
textView.text = sentenceArray[selectedLeftSpinner]
}
/** if answer is being shown then show last three chars of next item */
else if(selectedLeftSpinner < selectedRightSpinner){
selectedLeftSpinner++
textView.text = sentenceArray[selectedLeftSpinner]?.takeLast(3)
}
/** else we have reached the last item */
else{
buttonStart.text = "DONE"
/** reset left spinner to not selected state */
selectedLeftSpinner = -1
}
}
}
}
This should work but I have not considered any edge cases, so you will have to take care of them and there is space for other improvments such as usig a key, value structure(ex map) to store your flash card question and answers an code can still be reduced as both of listeners for spinners are identical, I leave it as an exercise.

Google Sheets Script to Hide Row if Checkbox Checked

I am trying to find a working code that will automatically hide a row if the checkbox in column F of that row is checked.
I have tried every script I have found and nothing seems to work. Unfortunately I am not code savvy and I am unable to find the issue.
This is what I currently have:
function onOpen() {
var s = SpreadsheetApp.getActive().getSheetByName("Checklists");
s.showRows(1, s.getMaxRows());
s.getRange('F2:F200')
.getValues()
.forEach( function (r, i) {
if (r[0] == "TRUE")
s.hideRows(i + 1);
});
}
The sheet I am working on is "Checklists" and the column that contains the checkbox is F. The value of the checkbox is either TRUE or FALSE. If the value is TRUE, I want that row to be hidden.
Can someone please help!!!
The quick test I was able to run was to set up a column of checkboxes in column F, then to create a function that catches each edit event on the sheet. This will immediately catch when the user checks a box and will then hide that row.
The trick with using the onEdit event is with determining which cell was actually changed. In your case, you only want to fully follow your logic if the change happens to a checkbox in column F. In my code, I've been using a function to make sure the change is in the desired range. The function looks like this:
function isInRange(checkRange, targetCell) {
//--- check the target cell's row and column against the given
// checkrange area and return True if the target cell is
// inside that range
var targetRow = targetCell.getRow();
if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;
var targetColumn = targetCell.getColumn();
if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;
//--- the target cell is in the range!
return true;
}
So then all your onEdit function has to do is to make a quick call when the edit event is fired to see if the change falls within the range you're looking for. In this case, I set up a variable with my range to check:
var thisSheet = SpreadsheetApp.getActiveSheet();
var checkRange = thisSheet.getRange("F2:F200");
if (isInRange(checkRange, eventObj.range)) {
After that, it's just a matter of picking the row number and hiding or showing. Here's the full example solution:
function isInRange(checkRange, targetCell) {
//--- check the target cell's row and column against the given
// checkrange area and return True if the target cell is
// inside that range
var targetRow = targetCell.getRow();
if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;
var targetColumn = targetCell.getColumn();
if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;
//--- the target cell is in the range!
return true;
}
function onEdit(eventObj) {
//--- you could set up a dynamic named range for this area to make it easier
var thisSheet = SpreadsheetApp.getActiveSheet();
var checkRange = thisSheet.getRange("F2:F200");
if (isInRange(checkRange, eventObj.range)) {
//--- so one of the checkboxes has changed its value, so hide or show
// that row
var checkbox = eventObj.range;
var rowIndex = checkbox.getRow();
Logger.log('detected change in checkbox at ' + checkbox.getA1Notation() + ', value is now ' + checkbox.getValue());
if (checkbox.getValue() == true) {
Logger.log('hiding the row');
thisSheet.hideRows(rowIndex, 1);
} else {
Logger.log('showing the row');
thisSheet.showRows(rowIndex, 1);
}
}
}

Custom caption next to CheckEdit Editor in XtraGrid

I have a XtraGrid bound to a Datasource, where I want a single column to have a Check Box in it, and have a caption next to the Check Box in the same cell. I can get the Checked True or False from another column in the Datasource, and also I need to get the caption text from another column in the Datasource...That part is easy, once I get a handle on implementing the caption changes.
My question is:
How do I programmatically change the text that is displayed next to the CheckEdit in the same cell?
Similar to (Tick and Untick represent the check box state):
Tick Apples
Untick Bananas
However, my attempts only display the text 'Check' - obviously the default caption in the CheckEdit editor:
Tick Check
Untick Check
I have searched the DevExpress support centre and they only have instructions for the CheckEdit Repository item when used in the TreeList (not the XtraGrid). I understand it will involve managing the CustomDrawCell event and some others - which is fine.
I think, your instructions for XtraTreeList can be also applied to XtraGrid. But I can suggest to you the other way.
You can use GridView.CustomRowCellEdit event and two ResositoryItemCheckEdit objects:
private RepositoryItemCheckEdit editTick;
private RepositoryItemCheckEdit editUntick;
Just set your Tick text to editTick.Caption property and Untick text to editUntick.Caption property.
Here is example:
//Initialize repository items:
editTick = new RepositoryItemCheckEdit() { GlyphAlignment = HorzAlignment.Near, Caption = "Apples" };
editUntick = new RepositoryItemCheckEdit() { GlyphAlignment = HorzAlignment.Near, Caption = "Bananas" };
//Add handler for CheckedChanged event:
Action<object, EventArgs> action = (s, e) =>
{
var ownerEdit = s as CheckEdit;
if (ownerEdit == null)
return;
ownerEdit.Text = ownerEdit.Checked ? editTick.Caption : editUntick.Caption;
};
editTick.CheckedChanged += new EventHandler(action);
editUntick.CheckedChanged += new EventHandler(action);
//Some sample DataSource:
var table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Bool", typeof(bool));
table.Rows.Add(0, false);
table.Rows.Add(1, false);
table.Rows.Add(2, true);
table.Rows.Add(3, false);
table.Rows.Add(4, true);
table.Rows.Add(5, true);
table.Rows.Add(6, false);
table.Rows.Add(7, true);
gridControl.DataSource = table;
//Here comes the CustomRowCellEdit:
gridView1.CustomRowCellEdit += (s, e) =>
{
if (e.Column.FieldName != "Bool" || e.CellValue == null) //Put your own field name here instead of "Bool".
return;
e.RepositoryItem = (bool)e.CellValue ? editTick : editUntick;
};
//Add CustomColumnDisplayText event, so you can see your "Apples" in group rows and filters:
gridView1.CustomColumnDisplayText += (s, e) =>
{
if (e.Column.FieldName != "Bool")
return;
e.DisplayText = (bool)e.Value ? editTick.Caption : editUntick.Caption;
};

How can I delete a hyperlink in a Silverlight RichTextBox?

I have a RichTextBox that the user can edit to create a hyperlink (in my case to another page with the document rather than an external URL). Having successfully created the link I now need to be able to remove it.
I have code that identifies that I've got a hyperlink in the current selection:
TextSelection linkText = richTextBox.Selection;
if (linkText != null && !string.IsNullOrWhiteSpace(linkText.Text))
{
XElement root = XElement.Parse(linkText.Xaml);
XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XElement linkElement = root.Element(ns + "Paragraph").Element(ns + "Hyperlink");
if (linkElement != null)
{
// Get here if have a Hyperlink. How do I remove or update?
}
}
However, I'm now stuck on the bit that goes inside the if test. How do I find the hyperlink so I can remove it completely?
My code for setting up the hyperlink is:
TextSelection linkText = richTextBox.Selection;
var hyperlink = new Hyperlink();
hyperlink.Inlines.Add(linkText.Text);
if (!String.IsNullOrEmpty(selectedTopic)) // A string holding the link target
{
// Setup hyperlink here
}
linkText.Insert(hyperlink);
I've managed to work out how to update the hyperlink:
foreach (var block in richTextBox.Blocks)
{
Paragraph p = block as Paragraph;
foreach (var inline in p.Inlines)
{
var hyperlink = inline as Hyperlink;
if (hyperlink != null && hyperlink.NavigateUri.AbsoluteUri.Contains(currentLink))
{
hyperlink.NavigateUri = new Uri(newLink);
}
}
}
I could use the same approach to delete the hyperlink, but how do I convert the Hyperlink to a normal Inline?
Looks like you are getting close you just need to hold a reference to the link then use Remove. Something like the following (I like to use Linq to make things a little more succinct):-
foreach (var p in richTextBox.Blocks.OfType<Paragraph>())
{
var hyperlink = p.Inlines.OfType<HyperLink>()
.FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));
if (hyperlink != null)
{
p.Inlines.Remove(hyperlink);
break;
}
}
Edit: Want to leave the content of hyperlink in place? (i.e., just remove the wrapping hyperlink),
foreach (var p in richTextBox.Blocks.OfType<Paragraph>())
{
var hyperlink = p.Inlines.OfType<HyperLink>()
.FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));
if (hyperlink != null)
{
int index = p.Inlines.IndexOf(hyperlink);
Span span = new Span();
foreach (var inline in hyperlink.Inlines.ToArray())
{
hyperlink.Inlines.Remove(inline);
span.Inlines.Add(inline);
}
// You may need code here to preserve the Font properties etc from hyperlink to span.
p.Inlines[index] = span;
break;
}
}

Resources