How can I move to subsequent web pages after POST (ing) a html form in R? - html

A happy and a prosperous New Year, 2016 to everyone.
Here, I am using NCDC website to download weather data from say 01-Jan-2015 to 31-Mar-2015 for a state in the US say Connecticut. The link is mentioned below in the script. From filling details on this webpage to page in which you click on submit after entering your email id, there are intermediate pages that require some inputs before continuing on to a next page. My goal is to write a R script that automatically triggers download (submit order) for different states for different time periods after providing required inputs.
For purpose of ease, I am putting steps that one need to follow to download data for Connecticut. These steps are (please go through 2 snapshots attached):
Step-1 : Here, you select a dataset, State name, and time period-
4 values that would go in the form on landing page are Daily Summaries, 2015-01-01 to 2015-03-31, States, and Connecticut.
library(httr)
url <- "http://www.ncdc.noaa.gov/cdo-web/search?datasetid=GHCND"
fd <- list(
submit = "Search",
searchStartDate = "2015-01-01",
searchEndDate = "2015-03-31",
resultType = "States",
searchString = "Connecticut"
)
resp<-POST(url, body=fd, encode="form")
Step-2 : Here, you would need to click first on ADD TO CART and then on View All Items under Cart. This would be possible, if we operate on resp from above step. I am not able to figure out a way to do this operation.
Step-3 : Here, you need to select 2nd option under "Select the Output Format" before clicking on CONTINUE.
Step-4 : Here, you have to select many options as highlighted in the image before clicking on CONTINUE.
Step-5: Finally, you enter the email id and click on "SUBMIT ORDER".
If you need any other input from my end, do let me know.
Thanks

Related

How do I use a google apps script to auto fill a google form with info taken from the user? [duplicate]

With the recent study-from-home dynamics hastly implemented by budget schools, I am now facing a mindless-robot-like-task of filling in attendance for my kids everyday multiple times per child. The school shared this form:
I, being a developer, want to create a UI and have my kids submit thier attendance to this form on thier own when the teacher asks for one over Zoom. Ids it possible? I'm a .Net developer and have not developed anything for Office 365 Online and have no idea where to start looking for Google.
It is possible by reconstructing the form URL with pre-filled values.
In the Google Form, each question is named internally with "entry.". For each of the question, you need to find the entry number and assign them the right values and add it to the URL parameters like in the below image:
(Edited Oct 2021: The ids are no longer found in the name attribute of each input field in the HTML as shown in the image. They are now located in a div within the form element. #hdrz's answer below to look in the Javascript present just at the end of the body tag is now also defunct.)
I've recreated your form here https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform
And here is the reconstructed URL with prefill values
https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E
Hope it helps
As #AHunt writes, the entry number used to be in a name attribute on the form fields. As of this answer time, I can no longer find the name attribute on any of the form fields. However, now there is a script tag at the end of the body tag, with a short javascript code, and in it you can find the entry numbers, see here:
Also, it is possible to submit the form directly with pre-filled values. Just replace viewform in the URL with formResponse.
Similar URL as in the accepted answer, but now it will be submitted at once. Note that all required fields have to be filled!
https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/formResponse?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E&entry.1124370742=Art
I think I may be late but still give you a solution. I had made similar script to send my school attendance.
Every field in Google Forms is associated with a entry.<id>. You have two ways to automate the form.
One way is to extract those IDs with and make a dictionary where entry.<id> is the key and your answer is the value.Then you have to send a POST request to the form URL with the dictionary as the data. You have automated the form.
To extract the IDs, inspect the html code and look at the <script> at the (very) end of the page. It lòoks something like this :
var FB_PUBLIC_LOAD_DATA_ = [null,[null,[[2030831236,"First Name (in English)",null,0,[[1475351979,null,1]
]
]
,[86681139,"Last Name (in English)",null,0,[[280503419,null,1]
]
]
,[836880978,"Grade",null,2,[[519373518,[["KG 1",null,null,null,0]
,["KG 2",null,null,null,0]
,["1",null,null,null,0]
,["2",null,null,null,0]
,["3",null,null,null,0]
,["4",null,null,null,0]
,["5",null,null,null,0]
,["6",null,null,null,0]
,["7",null,null,null,0]
,["8",null,null,null,0]
,["9",null,null,null,0]
,["10",null,null,null,0]
,["11",null,null,null,0]
,["12",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
,[221348070,"Section",null,2,[[301819105,[["A",null,null,null,0]
,["B",null,null,null,0]
,["C",null,null,null,0]
,["D",null,null,null,0]
,["E",null,null,null,0]
,["G",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
,[366027193,"Subject",null,2,[[1124370742,[["Math",null,null,null,0]
,["Science",null,null,null,0]
,["English",null,null,null,0]
,["Arabic",null,null,null,0]
,["Islamic",null,null,null,0]
,["Social",null,null,null,0]
,["Moral",null,null,null,0]
,["Art",null,null,null,0]
,["Computer",null,null,null,0]
,["French",null,null,null,0]
,["Physics",null,null,null,0]
,["Chemistry",null,null,null,0]
,["Biology",null,null,null,0]
,["Business",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
]
,null,null,[null,null,null,null,null,[null,null,null,[3,169,244,null,1]
,[217,242,253,null,1]
]
]
,null,null,null,"Attendance Form",48,null,null,null,null,null,[2]
]
As you can see there are two numbers with each field. One of them is the ID and another one I don't know. The second number is the ID we need. Using RegEx we can extract all the numbers and collect every second number in a list. This list will contain all the IDs.
Another way, as stated by others, is to reconstruct the URL with prefilled values. But in this too you have to extract the IDs.
I have included both of them in one and made this script :
import requests
from bs4 import BeautifulSoup
import re
def get_questions(url):
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
content = soup.body.find_all(text = re.compile('var FB'))
match = re.findall('[,]["][\w\s]+["][,]', str(content))
#It will match all the questions in the form
question_strings = [x.strip('"') for x in match]
match_ids = re.findall('(?<=\[\[)(\d+)', str(content))
#It will find all the numbers in the content
question_ids = ['entry.' + x for x in match_ids[1:]]
#It will leave the first numbers (they are not the ids)
return question_ids
# Below are only for when you want to know the form fills with their corresponding entry ids
# questions = dict(zip(question_strings, question_ids))
# return questions
def send_answers(url, fname, lname, grade, section, subject): #arrange this as per your form requirements
ids = get_questions(url)
answers = [fname, lname, grade, section, subject]
response = dict(zip(ids, answers))
if 'viewform' in url:
s = url.index('viewform')
response_url = url.replace(url[s::], 'formResponse?')
try:
r = requests.post(response_url, response)
if r.status_code == 200:
return '[!] Attendence posted !'
#In case an error happens, it will raise an exception
else:
raise Exception
#After raising the exception it will retry to submit using url reconstruction with prefilled values
except:
try:
ans_list = [x + '=' + y for x, y in zip(ids, answers)]
for i in range(0, len(ans_list)):
response_url += ans_list[i]
response_url += '&'
response_url.strip("&")
r = requests.get(response_url)
status = r.status_code
if status == 200:
return '[!] Attendance sent !'
else:
raise Exception
#If still an error happens, it will print out a message.
except:
return '[!] Attendance not sent !'
url = 'Form URL here'
fname = 'Your first name here'
lname = 'Your last name here'
grade = 'Your grade here'
section = 'Section here'
subject = 'Enter subject'
print(send_answers(url, fname, lname, grade, section, subject))
Hope it helps. Sorry for my bad English.
As a Google Form editor you can get a pre-filled URL (complete with entry values) by choosing the 'Get pre-filled link' option at the top right of the page, after clicking the three dots.
This will open the form in a new tab. The Submit (or Next) button will be replaced with a 'Get link' button.
After filling in the desired form responses, clicking 'Get link' will open a preview of what users will see. If everything is correct, clicking the 'COPY LINK' button (at the bottom left of page) will provide the URL.
The URL will look like this:
https://docs.google.com/forms/d/e/yourFormidhere/viewform?usp=pp_url&entry.1890935147=exampleprefilledvalue1&entry.1928475566=exampleprefilledvalue2&entry.2145528193=exampleprefilledvalue3
You can find the IDs in the console development section of Chrome.
Fill the form open networks tabs.
You can find the ID of each query in the form.
Easiest way is to simply launch Developer Tools (F12 or Ctrl+Shift+I usually) and go to the Network tab. Enable "Preserve log". Then just submit your form as usual, with the values you want (or test values).
In the Network tab, type "formResponse" in the filter bar. Find the latest entry and select it. Then go to Payload tab and click "view source". You should see something like this.
The text you see in the form data is simply what your append to the link of your form plus a '?' (question mark). So in this case our link will be https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=test&entry.280503419=test&entry.519373518=KG+1&entry.1124370742=French&entry.301819105=A&dlut=1662432187937&hud=true&entry.519373518_sentinel=&entry.301819105_sentinel=&entry.1124370742_sentinel=&fvv=1&partialResponse=%5Bnull%2Cnull%2C%22-6523749705829110087%22%5D&pageHistory=0&fbzx=-6523749705829110087.
Now let's just remove the extra parameters that aren't answers. Find the last answer you input and remove the rest. Our new link will be https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=test&entry.280503419=test&entry.519373518=KG+1&entry.1124370742=French&entry.301819105=A
This will open the form page with pre-filled values. If you actually want to submit the response right away, replace "viewform" with "formResponse".
The google form I tried is from #AHunt's answer, so thank you for that sample google form.

Online user input into R script

I am an R programmer who unfortunately has no experience in web development or anything related, so this could be a very basic question.
I would like to know whether it's possible to create a website where user input triggers some piece of R code to run. Let's use a trivial example:
I have a .txt file on my local device.
If a user visited my website, he would be able to input a number and click a "send" button.
The user should receive the sum of his input and the number stored on my text file. Then, the number in the text file should be replaced by the user's input. This means, something like this should run:
my_number <- read.txt(my_file.txt)
write.txt(user_input, file="my_file.txt")
output <- my_number + user_input
My question is, how can I tell R what the desired value for user_input is, and how can I let my website print the output.
NOTE: I tried to use the title "Can a website trigger R code execution?", but for some reason that is an inappropriate title!

"Create or update" form behavior when hitting back button

I have the following workflow on a website:
Some user John Doe declares a company through form 1
(fields: name, head office location)
After John Doe submits (HTTP POST) form 1, he is redirected (HTTP 302) to company form 2 with additional legal information about the company.
The problem is, if John Doe hits the back button of his browser during step 2, he will land on the form 1, with data filled by the browser (using values he already submitted — that's what Firefox and major browsers seem to do).
John Doe might then think he can use this form to update some information (e.g. fix a typo in the name of the company) whereas he will actually create a new company doing so, as we don't know on the server side whether he wants to declare a new company or update the one he just created.
Do you know any simple solution to handle that problem ?
Use javascript/jquery script after the page is loaded to empty all the inputs. This will prevent confusion of "updating the company".
jQuery would look something like this:
$('#elementID').val('');
You can also handle the situation by manipulating the browser history
on load of form 2, and pass the CompanyId generated on submit of form 1 using querystring. So that you can actually update the company as the user
Suppose John submits form1.html, a unique CompanyId "1001" is generated and redirected to form2.html. Now on load of form2 you can modify the browser history form1.html?companyid=1001 using
var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 1", "form1.html?companyid=1001");
Now, when the user click back button and submits the form1 again. you can check for companyid in querystring and update the company.
I think it is more user-friendly when user can return back to previous form and update it (instead preventing the described behavior).
I use in most cases similar way to handle described problem:
Let's assume that user is on the page /some-page, that contains "Create new company" button.
When the user opens this page, will be executed special method createOrFindCompanyDraft() on the server-side. This method creates new company "draft" record in DB (only for the current user). For example, draft record has primary key id=473. When you execute this method again it will return the same record with the id=473 (with "draft" status). "Draft" record should't display on any other interfaces.
And "Create new company" has link /company/common/473.
When user go to /company/common/473, you display form 1, that will be filled from "draft" record. At first time user will see empty form.
Technically user will update the existing record, but you can display "Create new company" title on the page.
Then user go to form 2, for example, /company/legal-info/473, you create similar draft record for the this form (similar to step 1).
When user submit the form 2, you will remove "draft" status from the record id=473 (and any related records).
Next time when user open page /some-page, will be created new draft record for the current user.
Browser history will contain:
/some-page
/company/common/473
/company/legal-info/473
/some-page2
I like this approach, because all form only update records. You can go to previous/next form many times (for example "Back"/"Forward" browser buttons). You can close browser, and open not completed forms tomorrow. This way doesn't require any additional manipulation with the browser history.
try this
<form autocomplete="off" ...></form>
And Another
Use temporary tables or session to store the Page 1 form data. If the page 2 form is submitted use the temporary data of page 1 which is stored in database or in session.
Use a Separate key (Hidden field ) in both page 1 and page 2.
Actually I thought of a trick to obtain that "create on first post, update after" behavior (just like the user thinks it should behave).
Let's say the step 1 form is at the URL /create_company/. Then I could have that page generate a random code XXX and redirect to /create_company/?token=XXX. When I create the company I save the information that it was created through page with token XXX (for instance, I save it in user's session as we don't need to keep that information forever) and when the form is submitted, if I know that a company was already generated using this token, I know the user used the same form instance and must have used the back button since the token would be different if he explicitly asked for another company.
What do you think ? (I initially thought there should be a simpler solution, as this seems a little bit over-engineered for such a simple issue)
This is more like a UX question.
I'd think that the solution lies within the information given to the user on that form, to help them understand what they're doing.
Set a title that says 'Create a company', for example, and set your submit button as 'Create Company' will help your user with that. Use a unique id when you create the company object, and pass the id back to the same URL in order to perform an update. You should then update your title and button that tells user that they are updating instead of creating.
In that sense I'd say it's better to use a more generic URL like /company and /company?id=12345.
You could also consider using Restful API protocol to help your server identifies the CRUD operation. http://www.restapitutorial.com/lessons/httpmethods.html
Without the "routing" part of django it is hard to help. I can just answer my experience from the express.js-router functionality:
you can specify a post on /company, which is for new users.
you can specify another route for post on /company/:companyid for a changing form
and as a response from the create-post you can redirect to the different location.

Is HTML5 localstorage appropriate to store input field values?

I have a question, on how to best store local values of some form fields.
In my website, users use the keypad to keep a tally count of items. They can enter a label for the items they count. The problem is that each user apply different labels for their needs - and, each time they visit the labels are blank.
My sites are running through site44.com, which does not allow the use of server side php. So, in my research, I think using HTML5 localstorage may allow a user to keep the label after the exit the site?
Is this a correct interpretation?
Can someone give me a guide if I have, say 3 inputs - with different ids - how to set up the script?
you can use the local storage like this :
var fn = document.getElementById("firstname").value;
localStorage.setItem("firstname", fn);
var ln = document.getElementById("lastname").value;
localStorage.setItem("lastname", ln);
var em = document.getElementById("email").value;
localStorage.setItem("email", em);
thus the clients browser will have these items set in their local storage.
Now if a user visits the website afterwards. you can check for the value of localStorage and find the items of your need.
Suppose on users' next visit you want to send him a greet message ( he has not logged in ofcourse ) you can use a script like this below:
var name = localStorage.getItem("firstname");
alert("Hello"+name);

PowerBuilder pasting in tabbed data window

I recently started a new job with a company and my first task is to update some quite old software for them.
There is a big back story but basically the software was written in PB8 (around 1997) and no one within the company (including me) has had any experience with PowerBuilder before and as the newbie I have been tasked to update and maintain it until a replacement has been approved and can be developed.
We have the license for PowerBuilder 12.5 so I am using PB12.5 Classic to do everything. The original developer cannot be contacted for support and no documentation exists.
One thing I am trying to understand, that will be a huge help in the future, is how to determine where functions are defined and where variables get their values..
The example I am working on at the moment is the following scenario.
There is a data window with tabs, named tab_detail each tab displays different whatever little orange men are in the tree list.
One of these are called dw_detail which allows pasting of data. None of the other tabs allow pasting of data, but I would like them to. dw_detail has an event rbuttondown() with the following code in it:
Window w_parentwin
If ib_add_mode Or ib_chg_mode Then
w_parentwin = Parent.GetParent().GetParent()
m_dwpaste m_pop_paste
m_pop_paste = CREATE m_dwpaste
m_pop_paste.idw_data = This
If ii_agent_code > 0 And Not IsNull(id_period) And Clipboard() <> "" Then
m_pop_paste.m_popup.m_paste.Enabled = TRUE
Else
m_pop_paste.m_popup.m_paste.Enabled = FALSE
End If
m_pop_paste.m_popup.PopMenu(w_parentwin.PointerX(), w_parentwin.PointerY())
DESTROY(m_pop_paste)
End If
When I add that code to the rbuttondown() event of tab number 2 (dw_adjustment) tab 2 now allows paste when I right click within the dw_adjustment data window but the data gets pasted to the fields within the dw_detail tab not the fields on the dw_adjustment tab.
I have tried debugging and stepping through the code but there are thousands of values in the variable window and without the ability to search I cannot find the variables used above and what their values are or why data gets pasted to the dw_detail tab instead of the dw_adjustment tab when I paste into the dw_adjustment tab.
Basically I am looking for any helpful tips on where to look or what the above is doing and why everything pastes to tab 1 instead of the tab I clicked paste in.
If more detail is needed from code from a different location or more information is needed I am happy to provide it.
As suggested by Seki I found the m_popup when double clicked it came up with wf_pastereturn():
Integer li_idx, li_rows, li_dwrows, li_comm, li_seqno
String ls_approval_type
If tab_detail.tabpage_details.dw_detail.RowCount() > 0 Then
li_idx = 1
li_dwrows = tab_detail.tabpage_details.dw_detail.RowCount()
Do Until li_idx > li_dwrows
ls_approval_type = tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx]
If IsNull(ls_approval_type) or ls_approval_type = "" Then
tab_detail.tabpage_details.dw_detail.DeleteRow(li_idx)
Else
li_idx++
End If
li_dwrows = tab_detail.tabpage_details.dw_detail.RowCount()
Loop
End If
If li_dwrows > 0 Then
li_seqno = Long(tab_detail.tabpage_details.dw_detail.Object.seq_no [li_dwrows])
End If
li_seqno += 10
If Clipboard() <> "" Then
If tab_detail.tabpage_details.dw_detail.ImportClipboard(1, li_rows, 1, 4, 3) <= 0 Then
MessageBox("Invalid Data", "Unable to paste!", StopSign!)
Return -1
End If
li_rows = tab_detail.tabpage_details.dw_detail.RowCount()
li_dwrows++
For li_idx = li_dwrows To li_rows
tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx] = trim(tab_detail.tabpage_details.dw_detail.Object.approval_type [li_idx])
tab_detail.tabpage_details.dw_detail.Object.approval_no [li_idx] = trim(tab_detail.tabpage_details.dw_detail.Object.approval_no [li_idx])
tab_detail.tabpage_details.dw_detail.Object.agent_code [li_idx] = ii_agent_code
tab_detail.tabpage_details.dw_detail.Object.period [li_idx] = id_period
li_comm = f_new_commission(Long(tab_detail.tabpage_details.dw_detail.Object.value_of_work[li_idx]), id_period)
tab_detail.tabpage_details.dw_detail.Object.levy_payable[li_idx]= &
inv_rate.of_CalculateLevyPayable (Long(tab_detail.tabpage_details.dw_detail.Object.value_of_work[li_idx]), id_period)
tab_detail.tabpage_details.dw_detail.Object.comm_deductable [li_idx] = li_comm
tab_detail.tabpage_details.dw_detail.Object.commission [li_idx] = li_comm
tab_detail.tabpage_details.dw_detail.Object.seq_no [li_idx] = li_seqno
li_seqno += 10
tab_detail.tabpage_details.dw_detail.Object.agent_return_detail_create_date[li_idx] = Today()
tab_detail.tabpage_details.dw_detail.Object.agent_return_detail_create_user[li_idx] = SQLCA.Logid
Next
Clipboard("")
Return 0
Else
Return -1
End If
I modified the function to use the windows SelectedTab property. Data will now paste into the tab but in the wrong input fields. I looked further and the data columns for the ImportClipboard function do not line up.
How is the best way to change the order of the selected database columns?
Here is a screenshot of what I mean by tabs:
So within the main program window, there are the above tabs, within each tab (where the input fields are) there is a data window labelled with the dw_ prefix.
Thanks heaps for your help.
I think first you should do some short tutorials. Please check out these:
PowerBuilder Classic 12/12.5 guide/tutorials
These are short and useful.
On the other side you are able to select specific variables in your own "watch variable" list, so you do not have to search over the several variables. You can right click on the variable name and do a Quickwatch or you can Insert the variable name in the Watch window.
Br. Gábor
The action with a contextual menu is in 2 times :
handle the mouse right click to display a contextual menu
perform an action among the one or several actions provided by the popup menu
You shown the pbscript that is displaying the menu with PopMenu() if there is something in the clipboard (Clipboard() <> "") and maybe you did not noticed that the pasting action is somewhere else.
Look in m_popup: there must be some code inside that may be hard-coded to paste in dw_detail. If so, maybe that you could store in the window instance variables a reference to the currently processed dw for the contextual menu.
Something like :
datawindow idw_current in the instance variables
then in the rbuttondown() event idw_current = this (this being the datawindow the rbuttondown() event belongs to)
and finally in the menu reuse the id_current instead of a hardcoded dw_detail
Concerning your question about where the variables are modified: what you can do is searching the variables by their name (right click on the target or a single pbl or object then 'search'), and put a breakpoint on the lines where they are affected. If you run in debug mode (CtrlDCtrlT instead of CtrlR) you will be able to trace when a variable is modified.
Paste Problem
Pass 1
It's hard to tell for sure, but I'd look at the code of m_dwpaste.m_popup.m_paste.Clicked. The worse case scenario is that dw_detail is hard coded into that script; the slightly better case is that it has a more flexible routine in there, but somehow dw_adjustment doesn't fit into that algorithm.
Pass 2
With the new information, we can see that the code of wf_pastereturn() (I'm not sure how you got to this script, but this looks like the culprit) is not simply pasting, but doing a lot more that involves specific fields. In fact, it's not just pasting, it's importing the data, which means that it's assuming the contents of the clipboard are not only in a specific format, but match the data set of the DataWindow (see the Columns pane in the DW painter, and be careful not to confuse the data set part of the DataWindow with the UI part). The question is, do you want:
"Pasting" like copying text from Notepad into a browser form; just putting text into the current field?
"Pasting" exactly like the other DataWindow, including assumptions that all the same columns mentioned in the script are in both DataWindows?
"Pasting" something like this script, but customized for the data set in the new DataWindow?
These all require somewhat different solutions, combined with the differences I asked about in my comment about tabs vs. DataWindows.
Finding Stuff
I'm going to give an unapologetically biased point of view, because I'm the author of a tool that, among other things, helps you search PowerBuilder code called PBL Peeper.
If you're looking at code in the Browse tab, and you want to see other mentions of the variable, you can select it, right click, and either
search forward or back within the script
search for the object name in the tree on the left (it'll make more sense when you see it)
search either the rest of the object or the rest of the application
Finding where a variable is assigned is more difficult than it sounds, because of the multiple syntaxes that could be involved.
// assigns a value on instantiation
int i = 1
// assigns a value when executed
i = 1
// does not assign a value
IF i = 1 THEN
// assigns a value possibly if the parameter is passed by reference (kind of like a pointer to the variable)
f_foo (i)
Finding the setting of a variable can be helped by understanding variable scope. If the variable is local, you only need to search the script. If the scope is instance or shared, you need to search the object (as above, pretty easy) and its descendants (easy to go to a given descendant with an RMB on the treeview, harder to search on a set of descendants). If the scope is global, you want to search the entire app.
Finding where a selected function is declared is possible, but you need to know a little secret (or RTFM). The Find on the RMB menu uses the parameters from the Find page, so you need to set Portion Type to All, not just Scripts, to find where functions are declared. Alternatively, you can use the Lists / Scripts pages and find the script using the functions on that page (Find, QuickFind, Filter, etc...).
The tool has a plethora of functionalities that let you find, filter and sift through code to get at what you're after. The above is just a quick introduction.
Good luck,
Terry.