VBScript: Using a variable within a DOM element - javascript

I'm looking to use a VBScript variable within a reference to a DOM element for a web-app I'm building. Here's a brief excerpt of the affected area of code:
dim num
num = CInt(document.myform.i.value)
dim x
x = 0
dim orders(num)
For x = 0 To num
orders(x) = document.getElementById("order" & x).value
objFile.writeLine(orders(x))
Next
This is my first venture into VBScript, and I've not been able to find any methods of performing this type of action online. As you can see in the above code, I'm trying to create an array (orders). This array can have any number of values, but that number will be specified in document.myform.i.value. So the For loop cycles through all text inputs with an ID of order+x (ie, order0, order1, order2, order3, order4, etc. up to num)
It seems to be a problem with my orders(x) line, I don't think it recognizes what I mean by getElementById("order" & x), and I'm not sure exactly how to do such a thing. Anyone have any suggestions? It would be much appreciated!

I was able to get this working. Thanks to both of you for your time and input. Here is what solved it for me:
Rather than using
document.getElementById("order" & x).value
I set the entire ID as a variable:
temp = "order" & x
document.getElementById(temp).value
It seems to be working as expected. Again, many thanks for the time and effort on this!

I can only assume that this is client side VBScript as document.getElementById() isn't accessible from the server.
try objFile.writeLine("order" & x), then check the source to make sure all the elements are in the document.
[As I can't put code in comments...]
That is strange. It looks to me like everything should be working.
Only other thing I can think of is: change
orders(x) = document.getElementById("order" & x).value
objFile.writeLine(orders(x))
to
orders(x) = document.getElementById("order" & x)
objFile.writeLine(orders(x).value)

It looks as if you're mixing client vs server-side code.
objFile.writeLine(orders(x))
That is VBScript to write to a file, which you can only do on the server.
document.getElementById
This is client-size code that is usually executed in JavaScript. You can use VBScript on IE on the client, but rarely does anyone do this.
On the server you'd usually refer to form fields that were part of a form tag, not DOM elements, (assuming you're using classic ASP) using request("formFieldName").
To make server-side stuff appear on the client (when you build a page) you'd embed it in your HTML like this:
<% = myVariable %>
or like this (as part of a code block):
document.write myVariable

Don't you need to change your loop slightly?
For x = 0 To num - 1
E.G. With 4 items you need to iterate from 0 to 3.

Related

Rails/Rspec/Capybara: Interpreting quotes for javascript string for execute script

Given that I need to set an element's selected index with javascript in capybara by the input name...
var element = document.querySelector("select[name='user[user_locations_attributes][0][location_attributes][state]']").selectedIndex = '50';
What is the proper way to interpret this as a string so it can be executed in Capybara with execute_script(function_name_string)? Because I keep getting syntax errors, unsure how to nest the " and ' quotations.
Easiest solution to your question is to use a heredoc
page.execute_script <<~JS
var element = document.querySelector("select[name='user[user_locations_attributes][0][location_attributes][state]']").selectedIndex = '50';
JS
Although if you have need for the element for anything else it's probably nicer to find the element in ruby and then just call execute_script on the element
el = find("select[name='user[user_locations_attributes][0][location_attributes][state]']")
el.execute_script('this.selectedIndex = 50;')
As a related question - is there a reason you're doing this via JS rather than just clicking on the correct option? If you're just scraping a page there's no issue, but if you're actually testing something this basically makes your test invalid since you could potentially be doing things a user couldn't
Since you commented that you are testing, you really shouldn't be doing this via JS, but should instead be using select or select_option. select takes the options string (which you should have - otherwise why have a select element in the first place)
select('the text of option', from: 'user[user_locations_attributes][0][location_attributes][state]')
select_option is called on the option element directly, which can be found in a number of ways, such as
find("select[name='user[user_locations_attributes][0][location_attributes][state]'] option:nth-child(50)").select_option

Can I call custom javascript from an R jupyter notebook

I have a Jupyter Notebook which is using the R programming language. I would like to call javascript functions within this R notebook.
I know there is a way to do this, because there are javascript based libraries that you can call from R, but I cannot find any examples of wrapping a javascript function, so it can be used by R.
Even an example of assigning javascript to a R variable and then calling that R variable would be helpful.
js::js_eval() can evaluate a string of JavaScript within R. From ?js::js_eval:
# Stateless evaluation
js_eval("(function() {return 'foo'})()")
For more complicated JavaScript operations, check out V8, which lets you keep a JavaScript instance for more than one line. From ?V8::v8:
# Create a new context
ctx <- v8();
# Evaluate some code
ctx$eval("var foo = 123")
ctx$eval("var bar = 456")
ctx$eval("foo+bar")
Ultimately it's going to get really frustrating for anything beyond little hacks, but it does work. You could likely source a whole script if you're clever, but I'm not sure it's worth it unless there's something that can absolutely only be done in JavaScript. Happy hacking!
I just wanted to add this answer in case anyone was interested in using javascript/html in Jupyter R. The following is a very basic example:
test="<input type=\"file\" id=\"myFile\"/>"
as.factor(test)
The as.factor() removes the quotes but you can basically just assigned javascript/html to an r variable and call that variable. For example:
test="<input type=\"file\" id=\"myFile\"/>"
test
So I found another way to do this by using the HTML function. Here is an example that will show and hide the code in a cell by clicking the text.
from IPython.core.display import HTML
HTML("""
<style>
// add your CSS styling here
</style>
<script>
var code_show=true; //true -> hide code at first
function code_toggle() {
$('div.prompt').hide(); // always hide prompt
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<a href="javascript:code_toggle()"
style="text-decoration:none; background-color: none;color:black;">
<h1 align="center">Example</h1>
</a>
""")

Pass variable from JSP to Javascript

Inside a JSP, I am fetching data from a Servlet by this code
<%
String name=(String)request.getAttribute("filepath");
%>
I want to access this inside script tags, how should i go about it?
I tried this var n = "${name}" and var n = "<%=name%>" and it did not work.
Make sure the assignment in scriptlet is working. Try System.out.println(name); to see if the value is set correctly.
I often use the latter
var n = "<%=name%>";
Both options should work fine (do not forget the ;).
Just remember that the scriptlet/ EL are executed when the page is returned from the server and the JavaScript when the browser parse the HTML.
To debug this issue I would use scriptlet first and look if I have a value using browser "view source".
If you do not see any value i.e.
var n = "";
You did not set the attribute correctly in java.
As for EL usage. Make sure you have the correct setting, in older version EL was disabled by default see
http://www.mkyong.com/spring-mvc/modelandviews-model-value-is-not-displayed-in-jsp-via-el/

Need help converting vbs code to jscript. Im getting a Runtime Error Type Mismatch

Ive got this labratory equipment that is connected to my PC. It uses special OCX file to communicate with the device (reading, setting parameters and such). I got this code from manual that seems to be working. I get a message box saying "Magnification =1272.814 Last error=API not initialized".
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>
So because I have 0% knowledge in vbs and about 10% in jscript I`m trying to rewrite the same thing in Javascript. And I also have some necessary code already written in js.
<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"\n Last error="+er);
Api1.ClosingControl();
</script>
Unfortunately I get a type mismatch error in either .Get or .GetLastError methods either with var value; var er; or var value=""; var er="";
Here is what API manual has to say
long GetLastError(VARIANT* Error)
[out] Error is the error string
associated with the error code for the last error
Remarks: This call will return a VT_BSTR VARIANT associated with the last error. Return
Value: If the call succeeds, it returns 0. If the call fails, an error
code is returned from the function.
long Get(LPCTSTR lpszParam, VARIANT* vValue)
[in] lpszParam is the name of the parameter e.g. “AP_MAG”
[in][out] vValue is the value of the parameter Remarks: This call will get the
value of the parameter specified and return it in vValue. In C++,
before calling this functions you have to specify the variant type
(vValue.vt) to either VT_R4 or VT_BSTR. If no variant type is defined
for vValue, it defaults to VT_R4 for analogue parameters (AP_XXXX) and
VT_BSTR for digital parameters (DP_XXXX). If the variant type is VT_R4
for an analogue parameter, then the floating point representation is
returned in the variant. If a VT_BSTR variant is passed, analogue
values are returned as scaled strings with the units appended (e.g.
AP_WD would return “= 10mm”). For digital parameters, VT_R4 variants
result in a state number and VT_BSTR variants result in a state string
(e.g. DP_RUNUPSTATE would return state 0 or “Shutdown” or the
equivalent in the language being supported). In C++, if the variant
type was specified as VT_BSTR then the API will internally allocate a
BSTR which the caller has to de-allocate using the SDK call
::SysFreeString (vValue.bstrVal)
Welcome to StackOverflow!
Well, each language is made with purpose. Then come to deal with ActiveX objects in browser (or WSH) environment, VBScript is the best choice, while JavaScript is most worst.
JavaScript hasn't so-called out parameters. That mean all function arguments are passed by value (as copy). Lets show you this with examples.
' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8
Sub Foo(ByVal arg1, ByRef arg2)
arg1 = 6
arg2 = 8
MsgBox "Local args: " & arg1 & ", " & arg2
End Sub
By default in VBS the arguments are passed by reference, so ByRef prefix in function arguments declaration is optional. I include it for clarity.
What the example illustrate is the meaning of "by reference" or "out" parameter. It behave like return value because it modify referenced variable. While modifying "by value" variable has no effect outside of the function scope, because we modify a "copy" of that variable.
// JavaScript
function foo(arg1) {
arg1 = 2;
alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);
// Local var = 2
// Outer var = 0
Now take a look at this thread. Looks like there is a kind of partial solution by using empty objects. I'm not sure in which cases that will work, but for sure it's very limited hack.
If this not help in your case, then looks like it's time to go with VBScript. Starting with VBS is easy anyway. It's the most user friendly language I ever touch. I was need days, even weeks with other languages only to get started, while just after a few hours with VBS I was able to use it freely.
[EDIT] Well, I made a lot more efforts to reply as may looks like at the glance :) Starting with the language limitation you met. Afterwards going to explain the nature of that limitation (what's "in/out" parameter), and the best way to do that is via example, and this is what I did. Afterwards I show you the only workaround out there to deal with this limitation in JS. Can we consider this as complete answer?
You not mention whether you test this "empty-object-trick", but as you still asking I presume you did that and it's not work with your OCX, right? Then, in this case, you're just forced to deal with your OCX via VBScript, what was my answer from the beginning. And as you prefer to stay with JS then you need to integrate a piece of VB code in your solution.
And as you noted too, this VBs/Js integration is a whole new question. Yes, good question of course, but it's a metter of new topic.
Ok, lets say that the question you append below: "why it should work with passing objects as a function parameter", is still a part of the main question. Well, as you see, even people using JS daily (am not one of them) has no idea what happens "behind the hood", i.e. do not expect an answer on what the JS-engine do in this case, or how this cheat the JS-engine to do something that it's not designed to do. Personally, as I use JS very rarely and not for such tasks, am not even sure if this trick works at all. But as the JS-guys assert it works (in some cases) then we s'd trust them. But that's all about. If this approach fail then it's not an option.
Now what's remain is a bit of homework, you s'd research all available methods for VBs/Js integration, also test them to see which one is most applicable to your domain, and if by chance you meet with difficulties, just then come-back to the forum with new topic and the concrete issue you're trying to resolve.
And to become as helpful as possible, I'll facilitate you with several references to get started.
Here is the plan...
1. If it's possible to work without VBs/Js integration then use stay-alone .VBS files (in WSH environment), else ...
2. In case you work in browser environment (HTML or HTA) then you can embed both (VBs/Js), and your integration w'd be simple.
3. Or may integrate VBs/Js with Windows Script Files (.wsf).
4. Or use ScriptControl that allow running VBScript from within JScript (or backward/opposite).
Links:
Using the ScriptControl
How To Call Functions Using the Script Control
An example VBs/Js integration using ScriptControl via
Batch-Embeded-Script
What is Batch-Embeded-Script:
VBS/Batch Hybrid
JS/Batch Hybrid
5. Some other method (if you find, that am not aware of).
Well, after all this improvements I not see what I can append more, and as I think, now
my answer is more than complete. If you agree with my answer then accept it by clicking on the big white arrow. Of course, if you expect to get better reply from other users, you may still wait, but keep in mind that unanswered questions stay active just for awhile and then become closed.

Trying to fire off a bunch of onclicks all containing a different number

There is a page I can access that contains a bunch of links like this:
<a href="#" onclick="navigate(___VIEW_RAID_2, {raid_inst_id:556816});return false;">
The number after the raid_inst_id: is always going to be different and there will be multiples on the same page all with different numbers. I'm trying to put together a javascript that will scrape the page for these links, put them in an array and then cycle through clicking them.
Ideally, an alert causing a pause between onclicks would be helpful. I've been unsuccessful so far even trying to gather the numbers and just echoing them out let alone manipulating them.
Any hints or help would be greatly appreciated!
Below is a function I tried putting together just to see if I could capture some of the onclick values for further processing but, this produces nothing...
function closeraids(){
x=document.getElementsByTagName('a');
for(i=0;i<x.length;i++)
{
attnode=x.item(i).getAttributeNode('onclick');
alert("OnClick events are: " + attnode);
}
}
Wow - 4 months later and the same problem still exists. I decided to look into this again only to find my own posted question in my Google search! Does anyone have any thoughts on what could be done here? The function I'm trying to provide will be part of a Chrome extension I already provide to users. It uses a combination of a .js file I host on my webserver and injected html content.
Any help would be appreciated!
Had some fun while making this jsfiddle: http://jsfiddle.net/Ralt/ttkGG/
Mostly because I went onto using almost fully functional style... but well. Onto your question.
I'm using getAttribute('onclick') to get the string in there. It shows something like:
"navigate(___VIEW_RAID_2, {raid_inst_id:553516});return false;"
So I just built the necessary regex to match it, and capture the number after raid_inst_id:
var re = /navigate\(___VIEW_RAID_2, {raid_inst_id:(\d+)}\);return false;/;
It's mostly rewriting the string by escaping the parentheses and putting (\d+) where you want to capture the number. (\d+ is matching a number, () is capturing the matched string.)
Using match(), I can simply get the captured string as the last element. So, rewriting the code in old IE way:
var links = document.getElementsByTagName('a'),
re = /navigate\(___VIEW_RAID_2, {raid_inst_id:(\d+)}\);return false;/;
for (var i = 0, l = links.length; i < l; i++) {
var attribute = links[i].getAttribute('onclick'),
nb;
if (nb = attribute.match(re)) {
alert(nb.pop());
}
}

Categories