Refresh or Clear GUI (Apps Script Gadget Embedded in Google Site) - gwt

I have a small form that my colleagues and I often fill out that can be seen here, with source code (view-only) here. The spreadsheet that this form posts to can be seen (view-only) here.
Basically, the apps script is solely for preventing my coworkers from having to scroll through thousands of rows of a spreadsheet (this is also used for our film collection) to check in/out inventory. It will also, soon, post detailed history of the checkout in an audit spreadsheet.
I have attempted, with no success, to clear the values of the text fields after the data has been posted to the spreadsheet. What I essentially want to do is restart the GUI so that the fields are once again blank.
I have tried accessing the text fields by id but the return type is a Generic widget, which I of course can't do anything with. And since control is passed to the handler functions, the text fields can't be accessed, or at least I can't figure out how (and I looked through the documentation and online solutions for hours last night).
So the question: how can I erase/clear the values of the text fields in the GUI after values have been posted to the spreadsheet? (return from handler function to access text fields again, or restart the GUI?
I can accomplish restarting the script runs on a spreadsheet, but I have not been able to do this when it is embedded in a Google site.

The getElementById('xxxxx').setText('') approach was the right way to do it. but the way you tried to test it doesn't work... the new value would only be available in the next handler call.
/*
This function only has the desired effect if it is called within the handler
function (not within a nested function in the handler function).
*/
function restartGUI() {
var gui = UiApp.getActiveApplication();
gui.getElementById('equipmentIDField1').setText('');
gui.getElementById('equipmentIDField2').setText('');
gui.getElementById('equipmentIDField3').setText('');
gui.getElementById('studentLastNameField').setText('');
gui.getElementById('labasstLastNameField').setText('');
return gui;
}

Related

Google Sheets not automatically creating hyperlinks when multiple files are uploaded on Google forms

Background:
I have a Google Form that asks clients to upload files. The form is attached to a Google Sheet where I want the files to be accessible to processing staff. A problem occurs when multiple files are uploaded. The Google sheet seems to not be able to create hyperlinks for the all the individual files.
There is a question about this already that has been resolved here:
https://stackoverflow.com/questions/70799922/google-app-script-to-convert-a-comma-seperated-list-of-urls-to-hyperlinks-in-she?answertab=modifieddesc#tab-top
The answer poses a custom function using Google App Script:
function onFormSubmit(e) {
// Get a Range reference to the cell containing the urls, possibly by using the event object passed in the form submit trigger:
var cell = e.range.getCell(1, urlColumn); // where urlColumn is the index of the column that contains the urls in question
var text = cell.getValue();
var richTextValueBuilder= SpreadsheetApp.newRichTextValue()
richTextValueBuilder.setText(text);
var urls = text.split(', ')
urls.forEach(function(url){
var startIndex = text.indexOf(url)
var endIndex = startIndex + url.length;
richTextValueBuilder.setLinkUrl(startIndex,endIndex,url)
})
cell.setRichTextValue(richTextValueBuilder.build())
}
My question is on how to use this as I have not had success.
First, when I run this script in the editor, I receive this:
TypeError: Cannot read property 'range' of undefined onFormSubmit # Code.gs:3
I'm pretty unfamiliar with java and have a working knowledge of python and am sure alot is missed in the details of how this script works.
As I understand it this error occurs if the script is run in the app script test function due to the formula being activated on an event which I believe is the submission of the form from the client.
I'm assuming that the custom function is to be set in a blank column that references the original results of the Google form links and converts them into the rich text links.
I've tested the script on the sheet on a blank column referencing the link information in the form results column and submitted a new form with the same result:
Link addresses appear as text and do not pull the documents.
Can anyone give me some clarity?

Xpath starting retuning None on Scrapy

I'm trying to crawl a site and to do so, I'm using Scrapy. So, when doing requests to nested pages, the procedure usually gets the the information correctly on the first trials, but, on later requests the nodes starts to return None. I'm using xpath's functionality. Below I'm pasting some lines of the parse function:
(I tried this one with the approach of explicitly comparing the class value)
title = response.xpath('//span[#class="inlineFree"]/text()').extract_first()
(With this one I used the contains function)
view = response.xpath('//span[contains(#class,"count")]/text()').extract_first()
(I've also used this one when I found more suitable)
comments = response.css('div.commentMessage > span::text').extract()
Am I doing something wrong on paths?
Is there any reason for the crawler to stop reading the nodes correctly?
Cannot say what the problem is without the log messages or the spider code but..
What happens most of the time is that websites fo not follow a strict html structure .For some properties the 'title' may be inside the span
but for the next iteration it may be
span[#class="inlineFree"]/h1/text() or or any other tag
so you should check the html for those returning None

Automatically send email about editing google spreadsheet

I'm working on a rather simple script which should handle new values in the spreadsheet and then send emails to specified addresses. And I faced with the problem. My code is listed below:
function onEdit(e) {
//part of the code for checking e.range to process only updated values
sendEmail();
}
function sendEmail() {
// arguments are missed only for demo
GmailApp.sendEmail();
}
While I'm using "simple trigger", my function "sendEmail()" works only if I start it from script editor. I allowed sending emails on behalf of my at first time and then function works fine. But if I'm changing the value in the spreadsheet - function "onEdit(e)" processes new data but function "sendEmail()" does nothing.
I partly solved this problem by using project's triggers from "current project's triggers" menu. In that case, function "sendEmail()" works properly, but I have no access to the information about update.
For my purposes I could use just second way and find new values "manually" every time, but I wish to optimize this work.
So, my questions are:
Is the process I described above proper or I made a mistake
anywhere?
If process proper, is where a way to combine both cases?
Thanks!
You correctly understood that (as the docs say) simple triggers cannot send an email, because they run without authorization. An installable trigger, created via Resources menu, can: it has the same rights as the user who created the trigger. If it is set to fire on edit, it will get the same type of event object as a simple trigger does.
So, a minimal example would be like this, set to run "on edit":
function sendMail(e) {
MailApp.sendEmail('user#gmail.com', 'sheet edited', JSON.stringify(e));
}
It emails the whole event object in JSON format.
Aside: if your script only needs to send email but not read it, use MailApp instead of GmailApp to keep the scope of permissions more narrow.

Grails: Radio button doesn't populate command obj when not selected

When I submit my form, if I do not select a value for my radio box then nothing is sent over to my command object for validation. I don't have issues with textFields or other input types.
class ApplicationCommand implements Validateable {
Map<String,String[]> questions = new LinkedHashMap<String,String[]>();
static constraints = {
questions validator: {val, obj, errors ->
for(String key : val.keySet()) {
errors.rejectValue("questions[${key}]",'required');
}
}
}
}
<g:radioGroup name="cmd.questions[1]" values="['Yes']" labels="['Yes']">
${it.radio}${it.label}
</g:radioGroup>
<g:textField name="cmd.questions[2]" />
With the above example, If i leave both fields empty and I submit I get the following
qusetions = [2: String[0]]
What I expect to see is
questions = [1: String[0], 2: String[0]]
Due to this issue, in my questions validator since key=1 is not populated I cannot validate it. The questions are dynamic all pulled from a DB so I cant hard-code anything in the validator such as if !questions.contains(1). Whatever data is populated into questions upon submission is what I have to assume the data is.
I have found 2 work-arounds, neither of which I like
1) Only for radio buttons, add a hidden field that will force a value to be populated if a radio is not selected. Horribly ugly
<g:hiddenField name="cmd.questions[1]" value="-" />
2) In my validator, I query the DB for all my questions and manually check for the existence of each one in the questions map. I want to avoid DB queries in my validators.
So while my 2 work-around options do work, I don't feel like I should have to resort to them.
I don't think this is a limitation of command objects or Grails; I think it's a limitation of HTML. I see the same question popping up in PHP.
The essential problem is that your command object doesn't know how many questions there are, but is responsible for making sure they are all there. I can think of a couple of (additional) ways to deal with this limitation:
The quick and easy way would be to put a single hidden input with the number of questions into your form. Also ugly, and open to alteration by the end-user.
The other option is to promote questions into a Domain so that the number of questions is known ahead of time, and is made available to your command object via a field or method. Then your command object can ask your questions, "How many are there supposed to be? Okay, did I get that many from the view?" This is similar to your #2 but without having to retrieve an entire collection and iterate it. This also opens up a path to perform further validation on each question (e.g., don't allow text into a numbers-only answer).
This does require hitting the DB, but it's the only way I can think of to validate the number of questions without relying on input from the view. The nice thing is that you can make it a very shallow hit, and hitting the DB can be very quick if you do it properly.

appending a form parameter to url in code igniter

I have tried my best to search for an existing question with smiliar issue but was not able to find one. Here's my situation
I have a controller named search which accepts a parameter "search term", when this controller is called directly from URL like www.xyz.com/search/red+car it returns results and the URL in browser address bar is www.xyz.com/search/red+car but when the user submits the search from a from in webpage with same term, the results are coming fine but the URL does not reflect the search term.
If I do a redirect the form POST data is lost, although resubmitting the POSt is not a solution in my case either. I need a way to change the URL so that it shows the search term.
Thanks in advance for your help, please be gentle as this is my first question.
#Vlakarados - I am trying to use same controller to provide search results from post data and controller parameter. Both work fine but when using search form on webpage the search parameter is not reflected in URL.
#Rakesh Shetty - The actual method is very long, but here is the compressed format
build query as per post data and passed parameter.
populate view with results
render the view
Thanks everyone for suggesting various solution.
I used jquery to change the form action parameter, now when ever the dropdown selection is changed the value is appended to the action parameter. I also took out the dropdown from being part of post data.
There are 2 dropdowns one for area and other for zip code. This new approach works with bot dropdowns and my exsting code of controller works without any major change.
I used the following javascript code to create new action parameter when ever user changes the area. Same goes for ZIP code.
$("#cityname").change(function(){
var action = $(this).val();
alert(action);
$("#searchform").attr("action", "search/" + action);
});
I think I was not able to clearly explain my situation otherwise you people would have suggested this long ago.
The better way to do it is in your controller:
function search($search_query) {
// .. use your query as you normally would - display products, posts, messages
$data = array('search_query' => $search_query);
$this->load->view('search', $data);
}
// use this method as the form action
function search_proxy() {
$search_query = $this->input->post('search');
// if needed urlencode or other search query manipulation
redirect('controller/search/'.$search_query);
}
This way you will have no problems and will only work with data in your url.
Edit: The second option is yo use JavaScript - when user submit's the form, change the form's action to include the searched query in form action