Passing variable to htp.p in a PL/SQL Dynamic Content - html

I am trying to pass a value in a variable for validation based on a db column and a checkbox on the UI component.
NOTE: Max_Set is the variable holding the maximum number from the DB column which is to be validated against the numberOfChecked items. However, when i pass Max_Set to the htp.p script, i am unable to use the value in the variable.
select num into Max_Set from table where column_name = name;
htp.p('<script type="text/javascript">');
htp.p('function ValidateSelection1()
{
var checkboxes = document.getElementsByName("student");
var numberOfCheckedItems = 0;
var Max_num = Max_Set
for(var i = 0; i < checkboxes.length; i++)
{
if(checkboxes[i].checked)
numberOfCheckedItems++;
}
if(numberOfCheckedItems > Max_num)
{
alert("You cant select more than the required number for this SL Site!");
return false;
}
}');
htp.p('</script>');
How can I use the value from Max_Set into htp.p script without it being considered as a string?

In your pl/sql code, everything within the htp call is treated as a string. If you want to use variables that are declared in pl/sql, you can concatenate (||) to put it all together. I replaced the "Max_Set" with "l_max_set" to indicate that this is a local pl/sql variable and not a javascript variable and the initcap tends to make it look like javascript.
select num into l_max_set from table where column_name = name;
htp.p('<script type="text/javascript">');
htp.p('function ValidateSelection1()
{
var checkboxes = document.getElementsByName("student");
var numberOfCheckedItems = 0;
var Max_num = '||l_max_set||';
for(var i = 0; i < checkboxes.length; i++)
{
if(checkboxes[i].checked)
numberOfCheckedItems++;
}
if(numberOfCheckedItems > Max_num)
{
alert("You cant select more than the required number for this SL Site!");
return false;
}
}');
htp.p('</script>');

Related

Is using a variable on HTMLElement.style.variable in Angular/TypeScript possible?

I try to implement an updateStyle(...)-method inside of an Angular-Component.
With this method specific elements with unique id's shall be styled.
Following code-snippet leads to:
Property 'variable' does not exist on type 'CSSStyleDeclaration'.
Is it possible to make angular compile anyway, so the variable is filled with a legit value in runtime or do I have to implement the method for every style-declaration, that I am going to use the method on?
updateStyle(id, variable, value){
var components = document.querySelectorAll("[id]") as NodeListOf<HTMLElement>;
for(var i = 0; i < components.length; i++) {
if(components[i].getAttribute("id") == id) {
components[i].style.variable = value;
}}}
You can put variable in square brackets like this:
updateStyle(id, variable, value) {
var components = document.querySelectorAll("[id]") as NodeListOf<HTMLElement>;
for (var i = 0; i < components.length; i++) {
if (components[i].getAttribute("id") == id) {
***components[i].style[variable] = value;***
}
}
}

Javascript: Using reviver function, I seem can't get to alter all the keys, while concating the numbers

I just want to change all the keys in batchesX. But I can't seem to alter all keys, because of concat. This is what I learned from post.
Please advise how I can change all keys with numbers.
var batchesX = '[{"batch":"0010002033"},{"batch":"0010001917"},{"batch":"0000020026"},{"batch":"0000017734"},'+
'{"batch":"0000015376"},{"batch":"0000014442"},{"batch":"0000014434"},{"batch":"0000014426"},'+
'{"batch":"0000013280"},{"batch":"0000012078"},{"batch":"0000012075"},{"batch":"0000012072"},'+
'{"batch":"0000011530"},{"batch":"0000011527"},{"batch":"0000011342"},{"batch":"0000010989"},'+
'{"batch":"0000010477"},{"batch":"0000008097"},{"batch":"0000007474"},{"batch":"0000006989"},'+
'{"batch":"0000004801"},{"batch":"0000003566"},{"batch":"0000003565"},{"batch":"0000001392"},'+
'{"batch":"0000001391"},{"batch":"0000000356"},{"batch":"0000"},{"batch":"000"},{"batch":""},'+
'{"batch":null}]'; // 30 elements
//in JSON text
var batchi = "batch";
var obj_batchesY = JSON.parse(batchesX);
console.debug(obj_batchesY);
var obj_batchesYlength = obj_batchesY.length;
console.debug(obj_batchesYlength);
var obj_batchesX = JSON.parse(batchesX,
function(k,v)
{
for(var i=1; i <= obj_batchesYlength; i++ )
{
if(k=="batch")
{
this.batchi.concat(string(i)) = v;
}
else
return v;
}
}
);
console.debug(obj_batchesX);
Is the code too long winded?
Many thanks in advance.
Clement
The return value of the reviver function only replaces values. If you need to replace keys, then use stringify and replace before the parse call, like this:
JSON.parse(JSON.stringify({"alpha":"zulu"}).replace('"alpha":','"omega":'))
Here is how to replace all numeric keys:
function newkey()
{
return Number(Math.random() * 100).toPrecision(2) + RegExp.$1
}
//Stringify JSON
var foo = JSON.stringify({"123":"ashanga", "12":"bantu"});
//Replace each key with a random number without replacing the ": delimiter
var bar = foo.replace(/\d+("?:)/g, newkey)
//Parse resulting string
var baz = JSON.parse(bar);
Make sure each replaced key is unique, since duplicate keys will be removed by the parse method.

GoogleScript Spreadsheet Custom Function Handling a range of cells and getting their values

I have a Goggle Spreadsheet with some data, and I want to write a custom function to use in the sheet, which accepts a range of cells and a delimiter character, takes each cell value, splits it by the delimiter, and counts the total.
For example
Column A has the following values in rows 1-3: {"Sheep","Sheep,Dog","Cat"}
My function would be called like this: =CountDelimitedValues(A1:A3;",");
It should return the value: 4 (1+2+1)
The problem I am having is in my custom script I get errors like
"TypeError: cannot get function GetValues from type Sheep"
This is my current script:
function CountArrayList(arrayList, delimiter) {
var count = 0;
//for (i=0; i<array.length; i++)
//{
//count += array[i].split(delimiter).length;
//}
var newArray = arrayList.GetValues();
return newArray.ToString();
//return count;
}
I understand that the parameter arraylist is receiving an array of objects from the spreadsheet, however I don't know how to get the value out of those objects, or perhaps cast them into strings.
Alternatively I might be going about this in the wrong way? I have another script which extracts the text from a cell between two characters which works fine for a single cell. What is it about a range of cells that is different?
That's something you can achieve without using script but plain old formula's:
=SUM(ARRAYFORMULA(LEN(A1:A3)-LEN(SUBSTITUTE(A1:A3; ","; "")) + 1))
Credit goes here: https://webapps.stackexchange.com/q/37744/29140
something like this works :
function CountArrayList(arrayList) {
return arrayList.toString().split(',').length
}
wouldn't it be sufficient ?
edit Oooops, sorry I forgot the user defined delimiter, so like this
function CountArrayList(arrayList,del) {
return arrayList.toString().split(del).length
}
usage : =CountArrayList(A1:C1;",")
NOTE : in this example above it would be dangerous to use another delimiter than "," since the toString() joins the array elements with commas... if you really need to do so try using a regex to change the commas to what you use and apply the split on that.
try like this :
function CountArrayList(arrayList,del) {
return arrayList.toString().replace(/,/g,del).split(del).length
}
Another solution I have was that I needed to implicitly cast the objects in the array being passed as a string.
For example this function accepts the array of cells, and outputs their contents as a string with del as the delimiter (similar to the String.Split() function). Note the TrimString function and that it is being passed an element of the array.
function ArrayToString(array,del) {
var string = "";
for (i=0; i < array.length; i++) {
if (array[i] != null) {
var trimmedString = TrimString(array[i]);
if (trimmedString != "") {
if (string.length > 0) {
string += del;
}
string += trimmedString;
}
}
}
return string;
}
Below is the TrimString function.
function TrimString(string) {
var value = "";
if (string != "" && string != null) {
var newString = "";
newString += string;
var frontStringTrimmed = newString.replace(/^\s*/,"");
var backStringTrimmed = frontStringTrimmed.replace(/\s*$/,"");
value = backStringTrimmed;
}
return value;
}
What I found is that this code threw a TypeError unless I included the declaration of the newString variable, and added the array element object to it, implicitly casting the array element object as a string. Otherwise the replace() functions could not be called.

STRING COMPARSION FLASH AS3

I got an input textfield in the UI.
When user key in "GIRAFFEEE", "GIRAFEAAA" OR "GIRAFFE123" and submit. The score value should be 0. However it returns 1.
How do I compare case sensitive string correctly?
qns1 = qns1_txt.text.toLowerCase();
qns1Ans = "giraffe"
//.toLowerCase();
if (qns1 == qns1Ans)
{
score = 1;
}
else
{
score = 0;
}
If you test following:
var correct:String = "giraffe";
var userAns:String = "giraffeaaaa";
trace(correct == userAns);//false - as expected
it means that string comparison works:)
I assume that your test code is in the CHANGE event of the textfield which may result in false positive as user may type part of correct answer, I think you should do a function:
function validate()
{
qns1 = qns1_txt.text.toLowerCase();
qns1Ans = "giraffe"
score = 0;
if(qns1 == qns1Ans)
{
score = 1;
}
}
and call it when user will hit submit, you could also compare the length of strings but equal operator will do just fine.

post all values in select box /listbox

I have a selectbox on a form - which I've turned in to a list box by putting
<select id="Select1" name="D1" size="5" style="width: 220px">
I'm filling this select/listbox with values...
When I post the form how can I get all the values in the select box..is this possible or am I only able to get one that has been selected.
Trouble is I want all the values in the select (I'm not selecting any as such)
Any ideas?
Before submitting the form you can use some JavaScript to pull the items out of the select and put them into a hidden text field (as a delimited string)
For example, you can get the values using
var select1 = document.getElementById('select1');
var values = new Array();
for(var i=0; i < select1.options.length; i++){
values.push(select1.options[i].value);
}
var allValues = values.join(";");
alert(allValues);
Hope that helps.
How are you adding the values to the list box? Are they static or are they pulled from a database.
If you're pulling from the database I would create a function that you use to get the data and bind to the list box.
Then use that same function when you want to get those values after the post. You may have to use some hidden fields to pass along any parameters you use to get the values for the list box in the first place.
example:
function get_models_for_make(int make_id)
mydata_rs = SELECT name, id FROM models WHERE make_id = make_id
return mydata_rs
end
so you could use this data to bind the objects to your listbox and also use it to get the values later that you did bind to your list box.
for (int i = source.Items.Count - 1; i >= 0; i--)
{
ListItem item = source.Items[i];
if (moveAllItems)
item.Selected = true;
if (item.Selected)
{
// if the target already contains items, loop through
// them to place this new item in correct sorted order
if (target.Items.Count > 0)
{
for (int j = 0; j < target.Items.Count; j++)
{
if (target.Items[j].Text.CompareTo(item.Text) > 0)
{
target.Items.Insert(j, item);
item.Selected = false;
break;
}
}
}
// if item is still selected, it must be appended
if (item.Selected)
{
target.Items.Add(item);
item.Selected = false;
}
// remove the item from the source list
source.Items.Remove(item);
}
}