I’ve searched a script that automates google form from my question banks (g-sheets).
All of my questions are multiple choice. I already added the setPoints() and setRequired(), however, for the answer key, I can’t find a way on how to script the value of my Answer’s column into TRUE when it meets the criteria. Below are the codes:
function getSpreadsheetData(sheetName) {
// This function gives you an array of objects modeling a worksheet's tabular data, where the first items — column headers — become the property names.
var arrayOfArrays = SpreadsheetApp.openById("GoogleSheetID").getSheetByName(sheetName || 'question').getDataRange().getValues();
console.log("Spreadsheet: " + arrayOfArrays[0]);
console.log("Spreadsheet: " + arrayOfArrays[1]);
var headers = arrayOfArrays.shift();
return arrayOfArrays.map(function (row) {
return row.reduce(function (memo, value, index) {
if (value) {
memo[headers[index]] = value;
}
return memo;
}, {});
});
}
function onOpen(e){
var form = FormApp.openById("GoogleFormID");
form.setTitle('DO ANY TITLE YOU WANT HERE');
form.setDescription('This is an example of Form generation');
getSpreadsheetData().forEach(function (row) {
var capitalizedName = row.Number.charAt(0).toUpperCase() + row.Number.slice(1);
console.log("Spreadsheet: " + capitalizedName);
form.addPageBreakItem()
.setTitle(capitalizedName);
var item = form.addMultipleChoiceItem();
item.setTitle(row.Questions)
.setPoints(1)
.setRequired(true)
.setChoices([
item.createChoice(row.Option1),
item.createChoice(row.Option2),
item.createChoice(row.Option3),
item.createChoice(row.Option4)
]);
});
}
function onSubmit(e) {
var form = FormApp.getActiveForm();
var items = form.getItems();
while(items.length > 0){
form.deleteItem(items.pop());
}
}
I’ve also search that to make choices the right answer, you just put TRUE or something like this:
item.createChoice(row.Option1, true),
item.createChoice(row.Option2, false),
item.createChoice(row.Option3, false),
item.createChoice(row.Option4, false)
However, this will only set Option1 as always the right answer. I want that TRUE or FALSE will be automatically place when found the right answer as stated in column G of my google sheets. Attach is my sheet:
GoogleSheet
This took me a while and I experience a weird issue, which is: After the Questions are set and the form saved, refreshing the page or trying to answer deletes all the options from one of the options (not always the same option).
I still have no clue why does this happen and I will investigate it later, but my code can give you an idea.
I changed your code a bit and added a new function which returns true or false for each option depending on the value of the G column:
form.addPageBreakItem()
.setTitle(capitalizedName);
var item = form.addMultipleChoiceItem();
item.setTitle(row.Questions)
.setPoints(1)
.setRequired(true)
.setChoices([
item.createChoice(row.Option1, checktrue(row, row.Option1)),
item.createChoice(row.Option2, checktrue(row, row.Option2)),
item.createChoice(row.Option3, checktrue(row, row.Option3)),
item.createChoice(row.Option4, checktrue(row, row.Option4))
]);
});
}
function checktrue(row, option){
var numRow = 2;
var sprsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var colA = sprsheet.getRange("A2:A5").getValues();
for (var i = 0; i < colA.length; i++){
if (colA[i] == row.Number){
numRow += i;
}
}
var answer = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("G"+numRow).getValue();
if (option == answer){
return true
} else {
return false
}
}
I'am new to angularjs, I'm creating an application of attendance. When i check the checkall checkbox all the checkbox of name is also check and What i really wanted to achieve is to get the value of checked checkboxes. I'm done with checking all checkboxes. I just want to store all the value of checkboxes in an array. I can only get data when i check those checkboxes one by one. Thank you in advance.
In my html here is my code.
<ion-checkbox ng-model="Selected" ng-click="checkAll()">
<div class="wew">
Check All Checkbox
</div></ion-checkbox>
</label></div>
<table><tr><th><center>
List of Names
</center></th>
<th colspan="3">
Actions
</th></tr><tr><td><label>
<ion-checkbox ng-repeat="role in roles" ng-model="isChecked" ng-
change="format(isChecked,role,$index)"><div class="wew">
{{role}}
</div></ion-checkbox>
</label></td>
And in my controllers code. First this is my code where i get the list of names.
$http.post(link1, {section: section}).success(function(attendance){
for(a = 0; a<attendance.length; a++){
$scope.roles = [
attendance[0].Full_Name,
attendance[1].Full_Name,
attendance[2].Full_Name,
attendance[3].Full_Name,
attendance[4].Full_Name,
attendance[5].Full_Name,
attendance[6].Full_Name,
attendance[7].Full_Name,
attendance[8].Full_Name,
attendance[9].Full_Name,
]
}
})
.error(function(err) {
console.log(err)
})
And this is my code where i wanted to execute the checkall and automatically store the data in $scope.selected = []; if i click the check all checkbox..
$scope.checkAll = function () {
if ($scope.Selected) {
$scope.Selected = false;
} else {
$scope.Selected = true;
}
$scope.isChecked= $scope.Selected;
$scope.selected = [];
$scope.format = function (isChecked, role, $index) {
if (isChecked == true) {
$scope.selected.push(role);
}
else {
var _index = $scope.selected.indexOf(role);
$scope.selected.splice(_index, 1);
}
var students = $scope.selected;
console.log(students);
}
}
try this code
<script>
$(function(){
var numbers = $("input[type='checkbox']:checked").map(function(_, el) {
return $(el).val();
}).get();
});
</script>
I am using MEAN stack in my application with AngularJS as my front-end. How Can I clear selected filed in input element,My Plunker
Look at my plunker for reference.
I have used Start date and End date inputs , which is used to filter the Due_date. If we select Start Date like:- 16-09-2016 the data's has filtering in the table.
In that date input has one X close button to clear the field, but which is not working, if we click that x clear button the table is showing like empty data's.
What we excatly looking for , if we click that x clear button it's should to be clear selected fileds and need to display all datas in table ....like we have given the exaple plunker is here :- http://plnkr.co/edit/QuJvCXFpKbwVd0OlkHZ2?p=preview for this plunker x clear button is working perfectly, I don't where I made a mistake,
Please help us.
My controller for daterange filter:-
.filter("myfilter", function() {
return function(items, from, to) {
var df = from;
var dt =to;
var result = [];
console.log(to);
for (var i=0; i<items.length; i++){
var date = moment(items[i].invoice_date);
date.add(items[i].terms,'d');
var tf = date;
if (date.isAfter(moment(from)) && date.isBefore(moment(to))) {
result.push(items[i]);
}
}
//console.log(items);
return result;
};
});
My html :-
<input type="date" class="form-control" name="from" ng-model="from">
<input type="date" class="form-control" name="to" ng-model="to">
Filter for daterange:-
<tr ng-repeat="data in record | myfilter:from:to">
<td> {{addDays(data.invoice_date,data.terms) | date:'yyyy-MM-dd'}}</td>
</tr>
I have created my plunker to reference :- My Plunker
Add date validation in your filter
app.filter("myfilter", function() {
return function(items, from, to) {
if(from.length!=0 && to.length!=0)
{
var df = from;
var dt =to;
var result = [];
console.log(to);
for (var i=0; i<items.length; i++){
var date = moment(items[i].invoice_date);
date.add(items[i].terms,'d');
var tf = date;
if (date.isAfter(moment(from)) && date.isBefore(moment(to))) {
result.push(items[i]);
}
}
//console.log(items);
return result;
}else
{
return items;
}
};
});
Change the filter condition to:
if (date.isAfter(moment(from)) || from == null && date.isBefore(moment(to)) || to == null)
This will remove the date constraint if from or to is not set.
Plunkr
Edit: Please add brackets like this:
if ((date.isAfter(moment(from)) || from == null) &&
(date.isBefore(moment(to)) || to == null)) {
//...
}
Updated Plunkr
I am using jQuery as:
$(document).ready(function(){
test("price");
alert("hi");
$("#item2").change(function()
{
sort= $("#item2").val();
test(sort);
});
});
Function test() is some JavaScript function, my problem is when page loads function calls by "price" parameter. Now when I select some item from select box function test() is called using sort parameter (verify by alert box). but I am not getting the correct result. I mean when I select option from select box than also my result of test() is as with "price" , I suppose it might be the problem because of jQuery's $(document).ready(function(){,. test() function make some html code based on the parameter and show it on the web page.
Please suggest me what can be the solution
EDIT:
function test() is :
function test(sort)
{
<%
Ampliflex ms = Ampliflex.getInstance();
String solrIP = ms.getSolrIP();
String solrPort = ms.getSolrPort();
String rows = ms.getSearchResultCount();
%>
solrIP='<%= solrIP %>'; // get Solr IP address
solrPort='<%= solrPort %>'; // get Solr Port number
rows='<%= rows %>'; // get number of results to return
solrURL="http://"+solrIP+":"+solrPort;
var query="${searchStr}"; // get the query string entered by ECommerce user
query=query.replace(/[^a-zA-Z 0-9*?:.+-^""_]+/g,''); // Remove special characters
query=query.replace(/\*+/g,'*'); // Replace multiple occurrence of "*" with single "*"
var newquery=query;
if(parseInt(query)==NaN)
{
var lowerCaseQuery=query.toLowerCase();
newquery=lowerCaseQuery;
}
else{
var lowerCaseQuery=query;
}
// sort= document.getElementById("item2").value;
$.getJSON(solrURL+"/solr/db/select/?qt=dismax&wt=json&&start=0&rows="+rows+"&q="+lowerCaseQuery+"&hl=true&hl.fl=text&hl.usePhraseHighlighter=true&sort="+sort+" desc&json.wrf=?", function(result){
var highlight = new Array(result.response.numFound);
$.each(result.highlighting, function(i, hitem){
var rg = /<em>(.*?)<\/em>/g;
var res = new Array();
var match = rg.exec(hitem.text[0]);
while(match != null){
res.push(match[1])
match = rg.exec(hitem.text[0]);
}
highlight[i]=res[0]
for (j=1 ;j<res.length;j++)
{
highlight[i]= highlight[i]+","+res[j];
}
});
var html="<table><tr>"
var count=0;
var alt="NoImage";
var size="3pt";
var id;
var flag=1; // Flag for error messages
border="1";
// If no search results
if(result.response.numFound==0)
{
var msg= "<hr /><font size="+size+" >We're sorry, we found no results for <b>"+document.getElementById("queryString").value+"</font><hr />";
}
else
{
/* var msg= "<hr /><font size="+size+" >Total Results Found <b> "+ result.response.numFound+"</b> for "+"<b>"+document.getElementById("queryString").value+"</b> keyword</font><hr /> ";*/
if (newquery==lowerCaseQuery)
{
var msg= "<hr /><font size="+size+" >Total Results Found <b> "+ result.response.numFound+"</b> for "+"<b>"+query+"</b> </font><hr /> ";
}
else
{
var msg= "<hr /><font size="+size+" >There were no exact matches for <b> "+ query+"</b> , so we searched automatically for "+"<b>"+query+"</b> and yielded "+result.response.numFound+" result(s)</font><hr /> ";
}
// Parse solr response and display it on web page
$.each(result.response.docs, function(i,item){
var word = new Array();
word=highlight[item["UID_PK"]].split(",");
var result="";
var j=0;
for (j=0 ;j<=item.text.length;j++)
{
result = result+item.text[j]+"<br>";
}
for (j=0 ;j<word.length;j++)
{
result=result.replace(word[j],'<em>' + word[j] + '</em>');
}
html+="<td><table>";
var src=item.image;
id="id";
if(src!= null && src!= ""){
html+="<p><tr><td><br>"+"<img id= "+id+ " src="+src+ " border="+border+ " /></td></tr>";
count=count+1;
html += "<tr><td><b>ImagePath</b> "+ item.image+"</td></tr>";
}
// If not insert a default image
else
{
src="images/products/default.jpg";
html+="<tr><td><br><p>"+"<img id= "+id+ " src="+src+ " border="+border+" /></td></tr>";
count=count+1;
html += "<tr><td><b>ImagePath</b> "+"No image path found" +"</td></tr>";
}
html += "<tr><td>UID_PK: "+ item.UID_PK+"</td></tr>";
html += "<tr><td>Name: "+ item.name+"</td></tr>";
html+="<tr><td><b>Price: $"+item.price+"</td></tr>";
html+="<tr><td> "+result+"<br></td></tr>";
html+="</p></table></td>"
if(count%3==0)
{
html+="</tr>"
html+="<tr>"
}
});
html+="</table>"
}
$("#text_container").html(msg);
$("#result").append(html);
}
});
});
}
Your question isn't particularly clear, but your alert code only fires when the document is ready - it is not inside the "change" event function.
Try using the following to see what value is being returned when you change the select box:
$(document).ready(function(){
test("price");
$("#item2").change(function()
{
sort= $("#item2").val();
alert(sort);
test(sort);
});
});
When changing the select box, you should get an alert with the value you have chosen, which will help you understand why the test() function isn't functioning as you expect.
If you amend your question to include the HTML of the select box and the test() function itself I will amend my answer to help.
The JQuery code that you have posted is working fine. Demo: http://jsfiddle.net/DtnUr/
We need more details to figure out the issue, such as your HTML code and JS functions.
I'm trying to submit a query using the postal code to my DB whenever the googlemaps viewport center changes. I know that this can be done with reverse geocoding with something like:
google.maps.event.addListener(map, 'center_changed', function(){
newCenter();
});
...
function newCenter(){
var newc = map.getCenter();
geocoder.geocode({'latLng': newc}, function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
var newzip = results[0].address_components['postal_code'];
}
});
};
Of course, this code doesn't actually work. So I was wondering how I would need to change this in order to extract the postal code from the results array.
Thanks
What I've realized so far is that in most cases the ZIPCODE is always the last value inside each returned address, so, if you want to retrieve the very first zipcode (this is my case), you can use the following approach:
var address = results[0].address_components;
var zipcode = address[address.length - 1].long_name;
You can do this pretty easily using the underscore.js libraray: http://documentcloud.github.com/underscore/#find
_.find(results[0].address_components, function (ac) { return ac.types[0] == 'postal_code' }).short_name
Using JQuery?
var searchAddressComponents = results[0].address_components,
searchPostalCode="";
$.each(searchAddressComponents, function(){
if(this.types[0]=="postal_code"){
searchPostalCode=this.short_name;
}
});
short_name or long_name will work above
the "searchPostalCode" var will contain the postal (zip?) code IF
and only IF you get one from the Google Maps API.
Sometimes you DO NOT get a "postal_code" in return for your query.
Alright, so I got it. The solution is a little uglier than I'd like, and I probably don't need the last for loop, but here's the code for anyone else who needs to extract crap from address_components[]. This is inside the geocoder callback function
// make sure to initialize i
for(i=0; i < results.length; i++){
for(var j=0;j < results[i].address_components.length; j++){
for(var k=0; k < results[i].address_components[j].types.length; k++){
if(results[i].address_components[j].types[k] == "postal_code"){
zipcode = results[i].address_components[j].short_name;
}
}
}
}
$.each(results[0].address_components,function(index,value){
if(value.types[0] === "postal_code"){
$('#postal_code').val(value.long_name);
}
});
You can also use JavaScript .find method which is similar to underscore _.find method but it is native and require no extra dependency.
const zip_code = results[0].address_components.find(addr => addr.types[0] === "postal_code").short_name;
This takes only two for loops. The "results" array gets updated once we found the first "type" to be "postal_code".
It then updates the original array with the newly found array set and loops again.
var i, j,
result, types;
// Loop through the Geocoder result set. Note that the results
// array will change as this loop can self iterate.
for (i = 0; i < results.length; i++) {
result = results[i];
types = result.types;
for (j = 0; j < types.length; j++) {
if (types[j] === 'postal_code') {
// If we haven't found the "long_name" property,
// then we need to take this object and iterate through
// it again by setting it to our master loops array and
// setting the index to -1
if (result.long_name === undefined) {
results = result.address_components;
i = -1;
}
// We've found it!
else {
postcode = result.long_name;
}
break;
}
}
}
You can also use this code, this function will help to get zip on button click or onblur or keyup or keydown.
Just pass the address to this function.
use google api with valid key and sensor option removed as it doesn't required now.
function callZipAPI(addSearchZip)
{
var geocoder = new google.maps.Geocoder();
var zipCode = null;
geocoder.geocode({ 'address': addSearchZip }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//var latitude = results[0].geometry.location.lat();
//var longitude = results[0].geometry.location.lng();
var addressComponent = results[0].address_components;
for (var x = 0 ; x < addressComponent.length; x++) {
var chk = addressComponent[x];
if (chk.types[0] == 'postal_code') {
zipCode = chk.long_name;
}
}
if (zipCode) {
alert(zipCode);
}
else {
alert('No result found!!');
}
} else {
alert('Enter proper address!!');
}
});
}
I use this code to get "Postal code" and "locality", but you can use it to get any other field just changing the value of type:
JAVASCRIPT
var address = results[0].address_components;
var zipcode = '';
var locality = '';
for (var i = 0; i < address.length; i++) {
if (address[i].types.includes("postal_code")){ zipcode = address[i].short_name; }
if (address[i].types.includes("locality")){ locality = address[i].short_name; }
}
I think rather than depending on the index it better checks address type key inside the component. I solved this issue by using a switch case.
var address = '';
var pin = '';
var country = '';
var state = '';
var city = '';
var streetNumber = '';
var route ='';
var place = autocomplete.getPlace();
for (var i = 0; i < place.address_components.length; i++) {
var component = place.address_components[i];
var addressType = component.types[0];
switch (addressType) {
case 'street_number':
streetNumber = component.long_name;
break;
case 'route':
route = component.short_name;
break;
case 'locality':
city = component.long_name;
break;
case 'administrative_area_level_1':
state = component.long_name;
break;
case 'postal_code':
pin = component.long_name;
break;
case 'country':
country = component.long_name;
break;
}
}
places.getDetails( request_details, function(results_details, status){
// Check if the Service is OK
if (status == google.maps.places.PlacesServiceStatus.OK) {
places_postal = results_details.address_components
places_phone = results_details.formatted_phone_number
places_phone_int = results_details.international_phone_number
places_format_address = results_details.formatted_address
places_google_url = results_details.url
places_website = results_details.website
places_rating = results_details.rating
for (var i = 0; i < places_postal.length; i++ ) {
if (places_postal[i].types == "postal_code"){
console.log(places_postal[i].long_name)
}
}
}
});
This seems to work very well for me, this is with the new Google Maps API V3. If this helps anyone, write a comment, i'm writing my script as we speak... so it might change.
Using JSONPath, it's easily done with one line of code:
var zip = $.results[0].address_components[?(#.types=="postal_code")].long_name;
In PHP I use this code. Almost in every conditions it works.
$zip = $data["results"][3]["address_components"];
$zip = $index[0]["short_name"];
Romaine M. — thanks! If you just need to find the postal code in the first returned result from Google, you can do just 2 loops:
for(var j=0;j < results[0].address_components.length; j++){
for(var k=0; k < results[0].address_components[j].types.length; k++){
if(results[0].address_components[j].types[k] == "postal_code"){
zipcode = results[0].address_components[j].long_name;
}
}
}
In a word, that's a lot of effort. At least with the v2 API, I could retrieve those details thusly:
var place = response.Placemark[0];
var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
myAddress = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName
myCity = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName
myState = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName
myZipCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber
There has got to be a more elegant way to retrieve individual address_components without going through the looping jujitsu you just went through.
This simple code works for me
for (var i = 0; i < address.length; i++) {
alert(address[i].types);
if (address[i].types == "postal_code")
$('#postalCode').val(address[i].long_name);
if (address[i].types == "")
$('#country').val(address[i].short_name);
}
Using Jquery
You cant be sure in which location in the address_components array the postal code is stored. Sometimes in address_components.length - 1 > pincode may not be there. This is true in "Address to latlng" geocoding.
You can be sure that Postal code will contain a "postal_code" string. So best way is to check for that.
var postalObject = $.grep(results[0].address_components, function(n, i) {
if (n.types[0] == "postal_code") {
return n;
} else {
return null;
}
});
$scope.query.Pincode = postalObject[0].long_name;
return $http.get('//maps.googleapis.com/maps/api/geocode/json', {
params: {
address: val,
sensor: false
}
}).then(function (response) {
var model= response.data.results.map(function (item) {
// return item.address_components[0].short_name;
var short_name;
var st= $.each(item.address_components, function (value, key) {
if (key.types[0] == "postal_code") {
short_name= key.short_name;
}
});
return short_name;
});
return model;
});
//autocomplete is the text box where u will get the suggestions for an address.
autocomplete.addListener('place_changed', function () {
//Place will get the selected place geocode and returns with the address
//and marker information.
var place = autocomplete.getPlace();
//To select just the zip code of complete address from marker, below loop //will help to find. Instead of y.long_name you can also use y.short_name.
var zipCode = null;
for (var x = 0 ; x < place.address_components.length; x++) {
var y = place.address_components[x];
if (y.types[0] == 'postal_code') {
zipCode = y.long_name;
}
}
});
It seems that nowadays it's better to get it from the restful API, simply try:
https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR_KEY_HERE
Using an AJAX GET call works perfect!
Something like:
var your_api_key = "***";
var f_center_lat = 40.714224;
var f_center_lon = -73.961452;
$.ajax({ url: "https://maps.googleapis.com/maps/api/geocode/json?latlng="+f_center_lat+","+f_center_lon+"&key="+your_api_key,
method: "GET"
})
.done(function( res ) { if (debug) console.log("Ajax result:"); console.log(res);
var zipCode = null;
var addressComponent = res.results[0].address_components;
for (var x = 0 ; x < addressComponent.length; x++) {
var chk = addressComponent[x];
if (chk.types[0] == 'postal_code') {
zipCode = chk.long_name;
}
}
if (zipCode) {
//alert(zipCode);
$(current_map_form + " #postalcode").val(zipCode);
}
else {
//alert('No result found!!');
if (debug) console.log("Zip/postal code not found for this map location.")
}
})
.fail(function( jqXHR, textStatus ) {
console.log( "Request failed (get postal code via geocoder rest api). Msg: " + textStatus );
});
As I got it zip is the last or the one that before last.
That why this is my solution
const getZip = function (arr) {
return (arr[arr.length - 1].types[0] === 'postal_code') ? arr[arr.length - 1].long_name : arr[arr.length - 2].long_name;
};
const zip = getZip(place.address_components);
i think this is the most accurate solution:
zipCode: result.address_components.find(item => item.types[0] === 'postal_code').long_name;
Just search for postal_code in all types, and return when found.
const address_components = [{"long_name": "2b","short_name": "2b","types": ["street_number"]}, { "long_name": "Louis Schuermanstraat","short_name": "Louis Schuermanstraat", "types": ["route"]},{"long_name": "Gent","short_name": "Gent","types": ["locality","political" ]},{"long_name": "Oost-Vlaanderen","short_name": "OV","types": ["administrative_area_level_2","political"]},{"long_name": "Vlaanderen","short_name": "Vlaanderen","types": ["administrative_area_level_1","political"]},{"long_name": "België","short_name": "BE","types": ["country","political"]},{"long_name": "9040","short_name": "9040","types": ["postal_code"]}];
// address_components = results[0]address_components
console.log({
'object': getByGeoType(address_components),
'short_name': getByGeoType(address_components).short_name,
'long_name': getByGeoType(address_components).long_name,
'route': getByGeoType(address_components, ['route']).long_name,
'place': getByGeoType(address_components, ['locality', 'political']).long_name
});
function getByGeoType(components, type = ['postal_code']) {
let result = null;
$.each(components,
function() {
if (this.types.some(r => type.indexOf(r) >= 0)) {
result = this;
return false;
}
});
return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>