I have a list of US regions set up as checkboxes. When a user submits the form, I need an array of associated states. This array is used for comparing to another array in my SQL tables.
Using jQuery or javascript, what's the best way to go about this?
I've got the general idea I believe:
//populate region to state arrays here
$("input[name='region']").each(function () {
if ($(this).is(':checked')) {
// ADD TO SUPER ARRAY OF ALL REGIONS
// (this is where I need help)
}
});
Thanks in advance!!
PS. I tried using the input values var regionValue = $(this).attr('value') to identify each array, but I'm having issues with dynamically named arrays since all my functions are in static classes.
Edited to reflect the new information and incorporating GenericTypeTea's comment:
Assuming the ID of each checkbox is set to the region name, how about:
var regionStates = {};
regionStates['northeast'] = ['AB', 'CD', 'EF'];
regionStates['mountains'] = ['GH', 'IJ', 'KL'];
// etc...
var selectedStates = [];
$("input[name='region']:checked").each(function () {
var region = regionStates[this.id];
for (var i = 0; i < region.length; ++i) {
selectedStates[selectedStates.length] = region[i];
}
});
Using this, selectedStates will contain all the states of all regions that are selected.
Apologies for not knowing any real US state abbreviations.
Related
I'm new with Google scripts and now I have to make a form with a list of choices. These choices should be picked up from the Google sheet.
So the first question is how to chose only unique values from some range of my spreadsheet?
The second is how to pass this list so that they will be the items in the list?
The code I've tried is:
function getMembranesList() {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/......");
var itemList = ss.getSheetByName('Answers').getRange("Q1:Q").getValues();
var form = FormApp.getActiveForm();
var item = form.addListItem()
item.setTitle('test question');
item.createChoice(itemList);
}
Looking at the methods available to populate the ListItem, you have to choose one and set your data up so it matches the expected input. For my example, I chose the setChoiceValues method, which looks for an array. So I have to manipulate the items into an array.
One thing the getRange.getValues() method does NOT get you is how many non-blank items are returned in the list. I used this quick way to get a count of those items, so I have a maximum bound for my loops. Then, I formed the itemArray and added only the non-blank items to it.
After that, it's just a matter of creating the ListItem and adding the values:
function getMembranesList() {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/...");
var itemList = ss.getSheetByName('Answers').getRange("Q1:Q").getValues();
var itemCount = itemList.filter(String).length;
var itemArray = [];
for (var i = 0; i < itemCount; i++) {
itemArray[i] = itemList[i];
}
var form = FormApp.getActiveForm();
var item = form.addListItem();
item.setTitle('test question');
item.setChoiceValues(itemArray);
}
Here is my fiddle : DEMO
Under the "Rules" Tab, on click of "+" a group of form-fields are cloned i.e, Join operator, Attributes, Operator & Threshold.
The attribute drop down is populated using a json (called expressionDetails) created using the relationship between contracts and thresholds variables.
Based on the choice of attributes, the thresholds field will be populated.
I could achieve this for the non-cloned Attribute and Threshold. However, due to class/ id duplication I am not able to pick up the cloned attribute's value as all the clones attributes hold the same class and their values are getting concatenated (in var z1).
//Appending option to "cloned" thresold field based on choice of attribute
$('.attributeExpr').on('change', function(e) {
$('.thresholdExpr').empty();
var z1 = $(".attributeExpr option:selected").text();
console.log(z1);
var a1 = expressionDetails[z1];
console.log(a1);
for (var i1 = 0; i1 < a1.length; i1++) {
var b1 = a1[i1].name;
// alert(b1);
var opt1 = $("<option>").text(b1);
// console.log(opt1);
$('.thresholdExpr').append(opt1);
}
});
Is there a different approach for this? Also, it should work for every cloned group thereafter as I will be using all of these values to create the "Expression" field.
Any help would be much appreciated. Thank you.
Replace the line 3 in above code with this. it will only return selected value.
var z1 = $("option:selected",$(this)).text();
Have you tried something like:
var z1 = $(this).find('option:selected').text();
Instead
var z1 = $(".attributeExpr option:selected").text();
Try this, I have tested it in your fiddle DEMO and it is working.
$('.attributeExpr').on('change', function(e) {
var index = $(this).index('.attributeExpr');
$('.thresholdExpr:eq( '+index+' )').empty();
var z1 = $(this).find("option:selected").text();
console.log(z1);
var a1 = expressionDetails[z1];
console.log(a1);
for (var i1 = 0; i1 < a1.length; i1++) {
var b1 = a1[i1].name;
// alert(b1);
var opt1 = $("<option>").text(b1);
// console.log(opt1);
$('.thresholdExpr:eq( '+index+' )').append(opt1);
}
});
I have added index so it can target the current element.
First thing you should do to make it work properly specially such complex implementation is to make the expressionsBuilder formgroup option fields to be dynamic, means it is being populated by JavaScript and not hard-coded in your HTML.
Then, you will assign the change event listener for each individual fields you created, this way you can control every form-group's behavior.
example click here
by populating it programatically you have total control of the fields behavior. You can then get each and every value of fields by iterating expressions variable like this:
for (var i = 0; i < expressions.length; i++)
{
var id = expressions[i];
var theAttribute = $("#" + id).find("[name='attribute']").val();
var theOperator = $("#" + id).find("[name='operator']").val();
var theThreshold = $("#" + id).find("[name='threshold']").val();
}
Hope that helps
===
ALSO heads up, it appears you are creating such complex application. I am suggesting you should make use for JavaScript frameworks to ease up maintainability of your code. This approach will become very hard to maintain in the long run
i'm tring to dynamically display eveyrthing that comes back from the server, however to get it displaying i have to explicitly write in the index of the object i'm trying to access, how can i make this dynamic so it goes through them all?
i am Using AngularJS, Express, and Mongoose.
here is the code snippet where the index i want to change on its own located.
app.controller('MainController', ['$scope', 'whipmeet', function($scope, whipmeet) {
whipmeet.getWhipmeets(function(JSON){
$scope.meetinfo = JSON;
$scope.meetparts {
name = JSON.data["0"].name,
location = JSON.data["0"].location,
car = JSON.data["0"].car,
date = JSON.data["0"].date,
time = JSON.data["0"].time,
type = JSON.data["0"].type,
stock = JSON.data["0"].stock
};
what i'm trying to achieve is that the ["0"] index change dynamically to get all the indexes of the objects so i can get those zeroes to go 1 to 2 to 3 and so on untill there are no more
There are few options.
From my understanding, you are trying to iterate through the JSON object that is returned to you.
You can either use:
var meetpartList = [];
JSON.foreach(function(d) {
// do your parsing here
newObject = {};
newObject.name = d.name;
// etc..
meetpartList.append(newObject);
});
or you can use:
for (int i = 0; i < numberOfIndicesInJson; i++) {
// get values using JSON[i + ""].key;
}
to do something similar as above to create a list of meets.
Then you can use that list of meets to render into your view using ng-repeat, which I hope is the solution you're looking for?
I have 3 classes (Survey, SurveyItem, VoteSurvey)
SurveyItem contain pointer to Survey
VoteSurvey contain pointer to Survey and pointer to SurveyItem
i need to include all the surveys that i haven't voted for.
//survey
var surveyQuery = new Parse.Query(Survey);
surveyQuery.equalTo("condo",pointerCondo); //essential column filter
//surveyitem
var surveyItemQuery = new Parse.Query(SurveyItem);
surveyItemQuery.matchesQuery("survey",surveyQuery);
//all survey with filter & surveyitems (return ok)
var voteQuery = new Parse.Query(VoteSurvey);
//...
can anyone help me?
It's not entirely clear what your class structure and fields are, so their might be a better way to do this. But, how about querying for all the surveys you have voted for and then finding all surveys that don't match? For example:
var voteQuery = new Parse.Query('VoteSurvey');
voteQuery.equalTo('user', user);
voteQuery.find().then(function(results) {
var alreadyVotedSurveyIds = [];
for (var i=0; i<results.length; i++) {
alreadyVotedSurveyIds.push(results[i].get('survey').id);
}
var surveyQuery = new Parse.Query('Survey');
surveyQuery.notContainedIn('objectId', alreadyVotedSurveyIds);
return surveyQuery.find();
}).then(function(notVotedSurveys) {
// notVotedSurveys is the array of surveys not voted for
});
Note: keep in mind that Parse query has a default limit of 100.
I'm using Kendo multi select as follow but i can't get selected values
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
for (var itm in items)
{
selectedData.push(itm);
}
but array selectedData return indices of items in multiselect not values .
You can also assign the array, returned from the value() method, directly to the variable, e.g.:
var ms = $("#multiselect").kendoMultiSelect({
value: ["1", "2"]
}).data('kendoMultiSelect');
var selectedItems = ms.value();
console.log(selectedItems); // ["1", "2"]
Use this other one returns indices.
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
for (var i=0;i<items.length;i++)
{
selectedData.push(items[i]);
}
Your original code doesn't look wrong. Are you sure you are getting only indices? Perhaps you should post your MultiSelect code as well. I found this question because I had the same problem and used the other answers for reference, but I found them overcomplicated. So let me answer in another complicated way :)
Here's what I've got. I know it's more code than you need, but I think it's important to see the full picture here. First let me set this up. There's a problem with the Kendo().MultiSelect.Name("SomeName") property if you are using it more than once. "Name" sets not only the html name, but the id as well, and you never want two ids with the same identifier. So in my code, I am appending a unique Id to my MultiSelect.Name property to ensure a unique id. I am putting the MultiSelect in each row of a table of people. I am showing this to make sure you are using the DataValueField property so you are able to get the selected values (not the text you see in the ui). If you are just showing a list of text values with no id behind them, perhaps that is why you are getting the wrong data?
#foreach (var cm in Model.CaseMembers)
{
<tr>
<td>
#(Html.Kendo().MultiSelect()
.Name("IsDelegateFor" + cm.CaseMemberId)
.Placeholder("is a delegate for..")
.DataTextField("FullName")
.DataValueField("CaseMemberId")
.BindTo(Model.Attorneys)
)
</td>
</tr>
}
then, later on, in my jQuery where I attempt to extract out the DataValueField (CaseMemberId), which is the array of selected values of the MultiSelect...
var sRows = [];
$('#cmGrid tr').each(function () {
// 'this' is a tr
$tr = $(this);
// create an object that will hold my array of selected values (and other stuff)
var rec = {};
rec.IsADelegateFor = [];
// loop over all tds in current row
$('td', $tr).each(function (colIndex, col) {
if (colIndex === 3) {
// make sure our MultiSelect exists in this td
if ($(this).find("#IsDelegateFor" + rec.CaseMemberId).length) {
// it exists, so grab the array of selected ids and assign to our record array
rec.IsADelegateFor = $(this).find("#IsDelegateFor" + rec.CaseMemberId).data("kendoMultiSelect").value();
}
}
}
// add this tr to the collection
sRows.push(rec);
}
so this is all a super verbose way of saying that this single line, as the other people mentioned works perfectly to grab the ids. There is no need to iterate over the .value() array and push the contents to another array!
rec.IsADelegateFor = $(this).find("#IsDelegateFor" + rec.CaseMemberId).data("kendoMultiSelect").value();
So in your original code, there is no reason the following should not work,
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData = [];
selectedData = multiselect.value();
console.log(selectedData);
unless
you don't have your MultiSelect set up properly in C# with DataValueField
you have multiple MultiSelects on the page with the exact same id and it's reading from a different one than you think.
You don't even have value fields, just a list of text.
var selected = $("#multi").data("kendoMultiSelect").value();
The solution given by volvox works.
Below is jquery version,
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
$.each(items ,function(i,v){
selectedData.push(v);
});