I'm trying to select a dropdown item via an Execute Javascript macro inside Keyboard Maestro. The code works to select and validate the dropdown item, but in the page I use this with, there are other dropdowns that should auto-populate based on the selection. When I click a dropdown item manually, the other dropdowns update accordingly. Via the javascript I'm using, it selects the item but leaves the other dropdowns. I need to use pure javascript and not jquery. Does anyone have any ideas on how to get the page to react based on the javascript selection?
// variable to enter into dropdown
var vDropdownInput = (document.kmvar.vZEROInput);
// variable to get the Element by ID
var objSelect = document.getElementById("web-selection_"+document.kmvar.vZEROIndex+"_");
// function to do the work
setSelectedValue(objSelect, vDropdownInput);
// function definition
function setSelectedValue(object, value) {
for (var i = 0; i < object.options.length; i++) {
if (object.options[i].text === value) {
object.options[i].selectedIndex = i;
return;
}
}
// Throw exception if option `value` not found.
var tag = object.nodeName;
var str = value;
return str;
}
edit: I found this related post but I just don't get the proposed solutions.
Select item in CascadingDropDown via JavaScript & invoke update
How do I programmatically force an onchange event on an input?
This answered my question.
var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);
Related
I added this inside Demo.prototype._handleSortChange to reverse the sort order if the radio is checked...
var order = true;
function reverseOrder() {
if (document.getElementById('order').checked) {
order = true;
} else {
order = false;
}
console.log('reverseOrder: '+order);
}
reverseOrder();
What I can't figure out is to call the sorting function when you check or uncheck the radio input without having to re-select the sort order dropdown.
Demo.prototype.reverseSorting = function () {
// this call resets the sort order to default, rather than just reversing the selected order...
document.getElementById('order').addEventListener('click', this._handleSortChange.bind(this));
};
Codepen https://codepen.io/midaspider/pen/ZEBwBqw
Solved it. I was looking at the wrong section as being the problem, the solution was very simple really.
Demo.prototype._handleSortChange = function (event) {
//var value = event.target.value;
var value = document.querySelector('.sort-options').value;
I realised the value of the select input wasn't being passed if I clicked the checkbox, so I changed var value to explicitly get the value from the select input rather than get the value passed from event. Now it works, I've updated the Codepen for reference in case anyone else needs this.
I'm currently using vanilla JS to match a given string, and then populate a drop down based on the match. I want to be able to click the drop down once to populate the drop down, but I currently have to click twice to then select the option, which would then add the same entries again (which isn't so much of an issue as once an option was selected, I can always reset the length to 0 so the user would likely not notice). I was thinking perhaps I need two event listeners instead of one but unsure of what direction to go or perhaps a "clickdown" and "clickup" event (if they even exist for mouse clicks?).
I'm still very much a beginner and not sure if what I am wanting to achieve is possible in one click or perhaps my approach is incorrect, so any pointers would be great.
document.getElementById('form').addEventListener('click', function() {
function addType(mactype) {
var type = document.getElementById('mode');
var option = document.createElement('option');
option.text = mactype;
type.add(option);
}
var macinput = MACinput.value;
var macoutput = MACoutput.value;
if (macinput.length > 0) {
var pattern = new RegExp("....-....-....");
if (pattern.test(macinput) == true) {
addType("Huawei -> Colon");
addType("Huawei -> HP");
addType("Huawei -> String");
}
}
I am using CSJS in the 'onChange' Event in a ComboBox, and when a user selects a value, I want an EditBox and a second ComboBox to be set (The second ComboBox value is one that is already in the list, I just want to select it).
To set the EditBox in my 'onChange' Event I used:
XSP.getElementById("#{id:fldEditBox}").value = newEditBoxValue;
But selecting a value in the ComboBox was much harder. At first I used the EditBox method:
XSP.getElementById("#{id:fldComboBox2}").value = selectedComboBoxValue;
The on screen value changed, and the ComboBox functioned normally, when the document was saved it still had the old value.
I tried all sorts of things like selectedIndex but nothing worked. Eventually I found that this:
document.getElementsByName("#{id:fldComboBox2}")[0].value = selectedComboBoxValue;
meant the change was saved, but was not visible on screen, so in my final production code I used both and it works:
XSP.getElementById("#{id:fldComboBox2}").value = selectedComboBoxValue;
document.getElementsByName("#{id:fldComboBox2}")[0].value = selectedComboBoxValue;
This seems ugly to me, there must be a better way of doing this in CSJS, does anybody know?
The way you set the value of a select element (combobox) in vanilla JavaScript is to loop through the elements options property to find the option you want to select:
var comboBox = document.getElementById("#{id:comboBox}");
for (var i=0; i < comboBox.options.length; i++) {
if (comboBox.options[i].value == "ValueYouWantSelected") {
comboBox.options.selectedIndex = i;
break;
}
}
If you have JQuery available you can do it more elegantly:
var xpageID = "#{id:comboBox}".replace(/:/gi, "\\:");
var valueYouWantSelected = "someValue";
$('#' + xpageID + ' option[value="' + valueYouWantSelected + '"]').prop('selected', true);
The xpageID variable is there because you have to escape the ':' characters that XPages puts in the generated IDs for it to work with the JQuery selector engine.
I'm trying to remove (or disable) certain list items on a NetSuite form based on the selected option of a different list. I have been able to alter the form in other ways, using custom code, but the list items appear to be created on the page dynamically. The field is actually an input field, that is altered by JavaScript, when you "open" it (apparently).
Any assistance with this would be greatly appreciated. My only other option appears to be to add all of the options to each list programatically (via SuiteScripts), but I'd rather not do that, since there are a lot of lists that need to be altered, depending on other options selected by the client.
EDITED
Well, I found a way, using some of the code from the SuiteScript functions... It's not ideal, but it could work... Unless anyone has a better way of doing it...
//Add Option
var textCustom = "test inserted option";
var valueCustom = '100';
var selectedCustom = 'T';
var fldnamCustom = 'custevent_fieldNameGoesHere';
var formCustom = document.forms['main_form'];
var fldCustom = getFormElement(formCustom,fldnamCustom.toLowerCase());
if (fldCustom != null){
addSelectOption(document,fldCustom,textCustom,valueCustom,selectedCustom);
}
//Remove Option
valueCustom2="1";
var formCustom2 = document.forms['main_form'];
var fldCustom2 = getFormElement(formCustom2,fldnamCustom.toLowerCase());
if (fldCustom2 != null){
eval( valueCustom2 != null ? 'deleteOneSelectOption(fldCustom2, valueCustom2)' : 'deleteAllSelectOptions( fldCustom2, window )' )
}
This is a very basic question (I'm a novice in GAS and JS). I have the code bellow. When a use it, I'd like that the submit function returns the itemsSelected. But, since it's returning app, how can I acess itemsSelected values from submit function?
var fact_list = ["He planted a tree", "She visited a nursing home", "They have donated books to the library"];
function showList() {
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i]);
var hidden = app.createHidden('checkbox_value_'+i, fact_list[i]);
panel.add(checkbox).add(hidden);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
var numberOfItems = e.parameter.checkbox_total;
var itemsSelected = [];
// for each item, if it is checked / selected, add it to itemsSelected
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
itemsSelected.push(e.parameter['checkbox_value_'+i]);
}
}
var app = UiApp.getActiveApplication();
app.getElementById('panel').clear().add(app.createLabel(itemsSelected));
return app;
}
In your example the function submit(e) is a handler function called by the submit button, every value that you define in that function will not be available to any other function unless you create a second handler in this submit function with another event etc... (which is obviously not the case here).
So the only way to keep that value available to another function is to store it "somewhere" where it will be available for the other functions.
From there the choice is yours... You mentioned in the comment you don't wat to use scriptProperties, but you can use scriptDb or userProperties or even the spreadsheet in which you are working but it has to be somewhere and it can't be in the UI in the example you show unless you have another event in this UI that would call the third function we are talking about.
In this case (and only in this last case) you can use a hidden widget or an invisible textBox to assign a stringified value of your array and get it back in the handler using the classical e.parameter.varName but this doesn't seem to be your use case.
Hoping I'm being clear enough....
If not then feel free to mention it.
EDIT : just a note : You are using a Label to show the value of itemsSelected . That's not the best choice since Labels can't have names , meaning we can't get a value from them even if we had a handler and an event... Labels are definitely 'one way' to show values. If it where a textBox you could use some kind of handler to trigger another function and retrieve the itemsSelected value.