Dynamically Change Option Set Values in CRM - javascript

I am using CRM Online 2013.
I am trying to remove 3 values from an optionset under a certain condition.
The optionset has six options by default: they are listed at the top of my JS code below.
When I run my code, the correct amount of options appear; but they all say undefined.
Here is what I have at the moment:
var customer = 100000000;
var partner = 100000001;
var partnerCustomer = 100000002;
var customerAndBeta = 100000003;
var partnerAndBeta = 100000004;
var partnerCustomerAndBeta = 100000005;
function populateBetaOptionSet(beta) {
var options = Xrm.Page.getAttribute("intip_websiteaccess").getOptions();
var pickListField = Xrm.Page.getControl("intip_websiteaccess");
for(i = 0; i < options.length; i++)
{
pickListField.removeOption(options[i].value);
}
if (beta == false) {
pickListField.addOption(customer);
pickListField.addOption(partner);
pickListField.addOption(partnerCustomer);
}
pickListField.addOption(customerAndBeta);
pickListField.addOption(partnerAndBeta);
pickListField.addOption(partnerCustomerAndBeta);
}
This is being called from another function which is wired up to a separate field's onchange event. I am sure this is working correctly as I am getting the correct beta value through when it is called.
I am removing all the options before re-adding them to avoid duplicates.
Any idea what I am doing wrong here/or know of a better way of doing this?

Re-wrote your function to match the criterion. The option is an object with both text and value. This is why you see undefined (missing text);
So instead of
var customer = 100000000
it needs to be
var customer = { value : 100000000 , text : "Customer" };
The code below saves each option in global scope and uses it each time you call populateBetaOptionSet
function populateBetaOptionSet(beta) {
var xrmPage = Xrm.Page;
var pickListField = xrmPage.getControl("intip_websiteaccess");
var options = pickListField.getOptions();
//save all options
if (!window.wsOptions)
{
window.wsOptions = {};
wsOptions.customer = pickListField.getOption(100000000);
wsOptions.partner = pickListField.getOption(100000001);
wsOptions.partnerCustomer = pickListField.getOption(100000002);
wsOptions.customerAndBeta = pickListField.getOption(100000003);
wsOptions.partnerAndBeta = pickListField.getOption(100000004);
wsOptions.partnerCustomerAndBeta = pickListField.getOption(100000005);
}
//clear all items
for(var i = 0; i < options.length; i++)
{
pickListField.removeOption(options[i].value);
}
if (beta == false) {
pickListField.addOption(wsOptions.customer);
pickListField.addOption(wsOptions.partner);
pickListField.addOption(wsOptions.partnerCustomer);
}
pickListField.addOption(wsOptions.customerAndBeta);
pickListField.addOption(wsOptions.partnerAndBeta);
pickListField.addOption(wsOptions.partnerCustomerAndBeta);
}

Example use Xrm.Page.getControl(..).addOption :
var low = {value : 100000000, text : "Low"};
var medium = {value : 100000001, text : "Medium"};
var high = {value : 100000002, text : "High"};
var pickList = Xrm.Page.getControl("control_name");
var options = pickList.getOptions();
for (var i = 0; i < options.length; i++)
pickList.removeOption(options[i].value);
pickList.addOption(low);
pickList.addOption(medium);
pickList.addOption(high);

Related

Oracle apex and jQuery - changing values from a select list

On this question here I finally succeed to change two values from the same column - priority. I tried to do it on select list - column priority lov - but with no conclusive success. Selects don't have "default values" properties like text fields, so I tried to get it from the source.context.index properties. Here the oracle apex app, user and password test.
I'm considering to use pure Javascript, to deal with it.
The Javascript is triggered after change the select list:
var source = apex.jQuery(this.triggeringElement).find('select[name="f31"]')
console.log(source)
var lista = apex.jQuery(source.context.form).find('select[name="f31"]')
console.log(lista)
console.log('source.context.selectedIndex inicial ' +source.context.index)
var valor_default = lista[0].selectedIndex
console.log(valor_default)
var index_default = apex.jQuery(this.triggeringElement).closest('select[name="f31"]').find('option[selected]')[0].index
console.log('indice default:' + index_default)
for (var x=0;x<lista.length;x++){
if (source.context.selectedIndex == lista[x].selectedIndex && source.context != lista[x]){
console.log('selectedIndex ' + source.context.selectedIndex)
console.log('source.context')
console.log(source.context)
console.log('lista[x]')
console.log(lista[x])
lista[x].selectedIndex = index_default
index_default = source.context.selectedIndex
// lista[x].defaultValue = source.context.defaultValue
// source.context.defaultValue = source.context.value
}
}
Fellows,
A possible solution was found.
On form properties - footer text, an array is build to get the indexes of object f31 - select list:
<script >
var listaOriginal = document.getElementsByName('f31')
var valordefault = []
for (item of listaOriginal) {
valordefault.push(item.selectedIndex)
}
console.log(valordefault)
</script>
on change from select list the array is used to compare with the changes:
var source = apex.jQuery(this.triggeringElement).find('select[name="f31"]')
var lista = apex.jQuery(source.context.form).find('select[name="f31"]')
var valueDefault = lista[0].selectedIndex
var happyIndex = ''
for (var happy=0;happy<lista.length; happy++){
if (source.context === lista[happy]){
happyIndex = happy
}
}
for (var x=0;x<lista.length;x++){
if (source.context !== lista[x] && source.context.selectedIndex == lista[x].selectedIndex){
var my_table = {};
my_table.source_context_selectedIndex = source.context.selectedIndex
my_table.lista_x_selectedIndex = lista[x].selectedIndex
my_table.valueDefault = valueDefault[x]
console.table(tabela)
lista[x].selectedIndex = valueDefault[happyIndex]
valueDefault[happyIndex] = valueDefault[x]
valueDefault[x]=lista[x].selectedIndex
// source.context.defaultValue = source.context.value
}
console.log(valueDefault)
}

Replace placeholder of an input in a dynamic form

What I am trying to achieve is to set the placeholder of an input field dynamically. I have an input where I say how many inputs I want to render in the form. On that created inputs I set an onchange event:
function inputOnchange (){
setTimeout(function(){
var createdInputs = document.querySelectorAll("*[class^='createInput']");
createdInputs.forEach( function(item){
item.onchange = function() {
changeFormPlaceholder();
}
})
}, 200);
}
As you see it runs an function when the onchange event is triggered below the function:
function changeFormPlaceholder(){
var inputs = document.querySelector('.formFieldInputs');
var num = 0;
var valueArray = {};
inputs.childNodes.forEach( function(input){
var inputValue = input.value;
var name = 'value' + num++;
valueArray[name] = inputValue;
})
for( var newPlaceholder in valueArray ){
if(valueArray.hasOwnProperty(newPlaceholder)){
console.log("newPLH", newPlaceholder, valueArray[newPlaceholder])
var form = document.querySelectorAll("*[class^='exitIntentInput']");
for(var i = 0; i < form.length; ++i){
// console.log("aaraay", form[i].placeholder);
form[i].placeholder = valueArray[newPlaceholder];
}
}
}
}
Now It changes only on the last input field and sets all input field to the second value.
So how can I change them individually?
Here is an FIDDLE
Type in something in the inputs on the sidebar you will see them appear on the right and now change the input value on the left you see my issue
You run a for loop in the other for loop,
for( var newPlaceholder in valueArray ){
if(valueArray.hasOwnProperty(newPlaceholder)){
console.log("newPLH", newPlaceholder, valueArray[newPlaceholder])
var form = document.querySelectorAll("*[class^='exitIntentInput']");
for(var i = 0; i < form.length; ++i){
// console.log("aaraay", form[i].placeholder);
form[i].placeholder = valueArray[newPlaceholder];
}
}
}
and when the second time of the outer for loop, the new Placeholdee="value1",
for(var i = 0; i < form.length; ++i)
// console.log("aaraay", form[i].placeholder);
form[i].placeholder = valueArray[newPlaceholder];
}
then the inner loop will set placeholder of all indexes of form to valueArray["value1"], the last value of inputs.
The simplest way to solve this problem is that declarie var valueArray as an array but object.
Thus no need to run twice for loops.
Code as follows:
function changeFormPlaceholder(){
var inputs = document.querySelector('.formFieldInputs');
var num = 0;
var valueArray = [];
inputs.childNodes.forEach( function(input){
var inputValue = input.value;
var name = 'value' + num++;
valueArray.push(inputValue);
})
var form = document.querySelectorAll("*[class^='exitIntentInput']");
for(var i = 0; i < form.length; ++i){
// console.log("aaraay", form[i].placeholder);
form[i].placeholder = valueArray[i];
}
}

Adding a running sum to a javascript object

I have a javascript object as below
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0},]
I want to update the object so that CumPnts contains a running points total for each Club as below
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":3},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":4},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":8},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":2},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":6},
{"Club":"Preston","EventNo":3,"Pnts":1,"CumPnts":7},]
Any help would be much appreciated
Here is a function that loops through the list and updates it after it's been added. But I suspect that the events come in one at a time so there could be another function that can look the cumPtns obj and take from that. Here is for the current list.
var cumData = {};
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0}];
function updateMyData() {
for (var i = 0; i < mydata.length; i++) {
var item = mydata[i];
if(cumData[item.Club] == undefined) {
cumData[item.Club] = {};
cumData[item.Club] = item.Pnts;
} else {
cumData[item.Club] = cumData[item.Club] + item.Pnts;
}
mydata[i].CumPnts = cumData[item.Club];
};
console.log(mydata);
//if you want to return it you can have this line below. Otherwise the object is updated so you'll probably want to do something with it once it's updated. Call back maybe?
return mydata;
}
updateMyData();
The first time it encounters a team it adds it to an array and so does with the corresponding cumPnts, so we can keep track of whether we checked a team earlier or not.
var tmArr = [];
var cumArr = [];
for(var i = 0; i < mydata.length; i++) {
var elm = mydata[i];
var club = elm.Club;
var points = elm.Pnts;
var idx = tmArr.indexOf(club);
if(idx > -1) {
cumArr[idx] += points;
elm.CumPnts = cumArr[idx];
}
else {
elm.CumPnts = points;
tmArr[tmArr.length] = club;
cumArr[cumArr.length] = points;
}
}
jsfiddle DEMO

How to find the number of form elements that are getting passed to e.parameter in GAS?

In Google App Scripts (GAS), I want to be able to add and remove TextBox and TextArea elements to a FlexTable (that's being used as a form) and not worry about how many there are. I've named the text elements based on a counter to make this process easier.
So, is there a way to get the number of inputs (TextBox + TextArea) passed to e.parameter after the form is submitted?
Here's the relevant code from the FlexTable:
function doGet() {
var app = UiApp.createApplication();
var flex = app.createFlexTable().setId('myFlex');
var counter = 0;
var row_counter = 0;
...
var firstnameLabel = app.createLabel('Your FIRST Name');
var firstnameTextBox = app.createTextBox().setWidth(sm_width).setName('input' + counter).setText(data[counter]);
flex.setWidget(row_counter, 1, firstnameLabel);
flex.setWidget(row_counter, 2, firstnameTextBox);
row_counter++;
counter++;
var lastnameLabel = app.createLabel('Your LAST Name');
var lastnameTextBox = app.createTextBox().setWidth(sm_width).setName('input' + counter).setText(data[counter]);
flex.setWidget(row_counter, 1, lastnameLabel);
flex.setWidget(row_counter, 2, lastnameTextBox);
row_counter++;
counter++;
...
var submitButton = app.createButton('Submit Proposal');
flex.setWidget(row_counter, 2, submitButton);
var handler = app.createServerClickHandler('saveProposal');
handler.addCallbackElement(flex);
submitButton.addClickHandler(handler);
var scroll = app.createScrollPanel().setSize('100%', '100%');
scroll.add(flex);
app.add(scroll);
return app;
}
And here's the code for the ClickHandler (notice that I currently have 39 elements in my FlexTable):
function saveProposal(e){
var app = UiApp.getActiveApplication();
var userData = [];
var counter = 39;
for(var i = 0; i < counter; i++) {
var input_name = 'input' + i;
userData[i] = e.parameter[input_name];
}
So, is there a way to get the number of elements (in this case 39) without manually counting them and assigning this value to a variable?
I'm new at this stuff and I'd appreciate your help.
Cheers!
The simplest way is to add a hidden widget in your doGet() function that will hold the counter value like this :
var hidden = app.createHidden('counterValue',counter);// don't forget to add this widget as a callBackElement to your handler variable (handler.addCallBackElement(hidden))
then in the handler function simply use
var counter = Number(e.parameter.counterValue);// because the returned value is actually a string, as almost any other widget...
If you want to see this value while debugging you can replace it momentarily with a textBox...
You can search for arguments array based object.
function foo(x) {
console.log(arguments.length); // This will print 7.
}
foo(1,2,3,4,5,6,7) // Sending 7 parameters to function.
You could use a while loop.
var i = 0;
var userData = [];
while (e.parameter['input' + i] != undefined) {
userData[i] = e.parameter['input' + i];
i++;
};
OR:
var i = 0;
var userData = [];
var input_name = 'input0';
while (e.parameter[input_name] != undefined) {
userData[i] = e.parameter[input_name];
i++;
input_name = 'input' + i;
};

Google Apps Script: How to find a listItem object in a google document and insert a item to it?

Following the documentation sample, I'm trying to create a function that searchs for a numerated list in a google document and, if finds it, adds a new item to that list. But I get this error: Cannot find method setListId(string). (line 21, file "test") or, if I change line 21 content (replacing elementContentfor newElement), I get the message: Preparing for execution... and nothing happens. How to fix it?
This is my code:
function test() {
var elementContent = "New item testing"; // a paragraph with its formating
var targetDocId = "1R2c3vo9oOOjjlDR_n5L6Tf9yb-luzt4IxpHwwZoTeLE";
var targetDoc = DocumentApp.openById(targetDocId);
var body = targetDoc.getBody();
for (var i = 0; i < targetDoc.getNumChildren(); i++) {
var child = targetDoc.getChild(i);
if (child.getType() == DocumentApp.ElementType.LIST_ITEM){
var listId = child.getListId();
var newElement = body.appendListItem(elementContent);
newElement.setListId(newElement);
Logger.log("child = " + child);
}
}
}
Following my comment, I tried to play with your script to see what happened and I came up with that code below...
I'm not saying it solves your issue and/or is the best way to achieve what you want but at least it gives a result that works as expected.
Please consider it as a "new playground" and keep experimenting on it to make it better ;-)
function test() {
var elementContent = "New item testing"; // a paragraph with its formating
var targetDocId = DocumentApp.getActiveDocument().getId();
var targetDoc = DocumentApp.openById(targetDocId);
var body = targetDoc.getBody();
var childIndex = 0;
for (var i = 0; i < targetDoc.getNumChildren(); i++) {
var child = targetDoc.getChild(i);
if (child.getType() == DocumentApp.ElementType.LIST_ITEM){
while(child.getType() == DocumentApp.ElementType.LIST_ITEM){
child = targetDoc.getChild(i)
childIndex = body.getChildIndex(child);
Logger.log(childIndex)
i++
}
child = targetDoc.getChild(i-2)
var listId = child.getListId();
Logger.log(childIndex)
var newElement = child.getParent().insertListItem(childIndex, elementContent);
newElement.setListId(child);
break;
}
}
}

Categories