Meteor Add Users to Form Select - javascript

I am a little surprised I am not finding anything out there on this. My question is really 2 parts:
Is it possible to generate a form select field (preferably with Autoform) with all of the options being registered users emails or names? If so could anyone please provide an example?
Is it possible (again autoform is preferred) to have conditional form field rules. EX: I have a client with multiple locations. One select would be for the client, and depending on what is selected here would populate another select that generates all of this clients locations. Again ANY examples would be appreciated!
Thanks so much!

Really not answering but rather just giving a better visual of the code I added. I am getting an input box but not a select box. There is nothing inside the input. Here is what I added:
inspector: {
type: String,
autoform: {
type: "selectize",
options: function() {
return Meteor.users.find({}, fields: {
emails: 1,
profile: 1
}).map(function(c) {
var optionsArray = [];
for (var i = 0; i < c.length; i++) {
optionsArray[i] = {};
optionsArray[i].label = c[name][i];
optionsArray[i].value = c[name][i];
}
return optionsArray;
})[0];
},
defaultValue: function() {
return "Choose a User";
},
}
},
Just curious what I got wrong.

Autoform is awesome work done by aldeed. So much of functionality inside it, it would take some time to read and understand the documentation. I will try to help with an example.
Is it possible to generate a form select field (preferably with Autoform) with all of the options being registered users emails or names? If so could anyone please provide an example?
var myAutoForm = new SimpleSchema({
"formSelectField": {
type: String,
autoform: {
type: "selectize",
options: function() {
return collectionName.find({ criteria to get the registered user names }).map(function(c) {
var optionsArray = [];
for (var i = 0; i < c.length; i++) {
optionsArray[i] = {}; // creates a new object
optionsArray[i].label = c[name][i];
optionsArray[i].value = c[name][i];
}
return optionsArray;
})[0];
},
defaultValue: function() {
return the default value to be picked on the select dropdown
},
}
},
});
Is it possible (again autoform is preferred) to have conditional form field rules. EX: I have a client with multiple locations. One select would be for the client, and depending on what is selected here would populate another select that generates all of this clients locations. Again ANY examples would be appreciated!
For this, I will put only the options part of the autoform
options: function() {
if(AutoForm.getFieldValue('fieldName', 'formId')==='something')
})
return someValue;
},

Related

angularjs filters with an OR operation

I have data array like this :
$scope.data = [{
name: 'joseph',
statarray: [{
status: 'Online',
status: 'Offline',
}],
active: 'yes'
},
{
name: 'arnold',
statarray: [{
status: 'Offline'
}],
active: 'no'
},
{
name: 'john',
statarray: [{
status: 'Online'
}],
active: 'yes'
}
];
$scope.findObjectByKey = function(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
return null;
};
$scope.Online = function(array){
var obj = $scope.findObjectByKey(array, 'status', 'Online');
return obj;
}
$scope.Offline = function(array){
var obj = $scope.findObjectByKey(array, 'status', 'Offline');
return obj;
}
The functions $scope.Online and $scope.Offline sorts the data according to the status Online and Offline.
Here's my view :
I have these two checkboxes as filters :
<input ng-true-value='Online' ng-false-value='' type="checkbox" ng-model="online" type="checkbox">Online
<input ng-true-value='Offline' ng-false-value='' type="checkbox" ng-model="offline" type="checkbox">Offline
<div ng-repeat="user in data|filter:online|filter:offline">
<p>{{user.name}}</p>
</div>
Currently when I click the checkbox corresponding to Online it displays the user joseph and john whose status is Online and when I click the checkbox corresponding to Offline it displays the users joseph and arnold whose status are Offline. This much is working perfectly. But when I click both the filter buttons it only displays joseph as joseph has both Online and Offline status. So an AND operation is being applied here. But I want an OR operation here. So when I click both the filter buttons I should get the output as joseph,arnold and john in the view. Any clue on how can I do it?
First, your statarray seems wrong, considering you declared one object with two properties with the same name, first we should move it to something like an array only containing the status strings ex. ['Online', 'Offline'].
You are executing the filter function only using the latest filter selected.
You need to think in a different approach to aggregate your selected filters,
something like create an filter obj.
filter = {
online: true,
offline: false
}
and iterate over then to display your data
$scope.filterArray = function(array, key, value) {
var filtered = [];
for (var i = 0; i < array.length; i++) {
var shouldInclude = false;
shouldInclude |= ($scope.filter.online && array[i].statarray.indexOf('Online') >= 0);
shouldInclude |= ($scope.filter.offline && array[i].statarray.indexOf('Offline') >= 0);
if (shouldInclude) {
filtered.push(array[i]);
}
}
return filtered;
};
This is just one possible approach, if you are able to use ES6 functions this become even simpler.
# pravin navle-
Are you sure its working same as you described below code? Because when I tried to replicated same functionality it works only for Offline and not for Online as well as Both Checked.

Json cascading dropdown

I'm trying to set up a cascading dropdown using JSON data. I have it working somewhat but need some assistance getting the 2nd tier to work as intended. Currently it seems to be grabbing the number in the array.
Ideally for my 2nd tier I want to show the text in the dropdown as the option text, and I'd like to use the id field in the json as the value of the option.
var data = {
"Crime":[
{"id":"1","text":"Number of police"},
{ "id":"2","text":"Number of crimes"}
],
"Health":[
{"id":"3","text":"Number of doctors"},
{"id":"4","text":"Number of hospital visits"},
{"id":"5","text":"Number of nurses"}
],
}
I have a jsfiddle showing what I have so far.
Happy to use whatever combination of javascript/jquery works best.
The way you have used for..in seems to be incorrect. The question variable will not contain the entire value if the pointed collection (data[this.value], in this case) is not a simple array. Rather, it would contain the index of the first row, the second row and so on. I request you to read this for a more in-depth understanding :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
This line here
questionSel.options[questionSel.options.length] = new Option(question, question);
Must read this way
questionSel.options[questionSel.options.length] = new Option(
data[this.value][question].text,
data[this.value][question].id);
Here's an updated fiddle after this change has been made:
http://jsfiddle.net/tc1f3kup/2/
please try this
var data = {
"Crime":[
{"id":"1","text":"Number of police"},
{ "id":"2","text":"Number of crimes"}
],
"Health":[
{"id":"3","text":"Number of doctors"},
{"id":"4","text":"Number of hospital visits"},
{"id":"5","text":"Number of nurses"}
],
}
window.onload = function () {
var themeSel = document.getElementById("theme"),
questionSel = document.getElementById("questions");
for (var theme in data) {
themeSel.options[themeSel.options.length] = new Option(theme, theme);
}
themeSel.onchange = function () {
questionSel.length = 1; // remove all options bar first
if (this.selectedIndex < 1) return; // done
for(var i=0;i<data[this.value].length;i++)
{
questionSel.options[questionSel.options.length] = new Option(data[this.value][i].text, data[this.value][i].id);
}
}
}
working fiddle
http://jsfiddle.net/tc1f3kup/3/

How to set a dojo combobox store

I'm working on a web application and am attempting to set combo boxes based off of a query built into an ArcGIS map service. I set the first combo box based off of a query and when I select a value from that I want to query an ArcGIS map service to fill the second.
For testing purposes I default the first combo box value to an option and the query works to fill the second combo box. However when I change the first combo box I get an error with setting the store for the second combo box.
Please forgive the ugliness of the code. I'm making it "work" right now and will clean it up when I learn a bit more.
function startCat(results) {
var items=[];
var features = results.features;
features.forEach(function(feature) {
cat = feature.attributes.CATEGORY;
items.push({name:cat});
});
var data = {
label: 'name',
items: items
};
var store = new ItemFileReadStore({data:data});
// create combobox
var comboBox = new ComboBox({
id: "catSelect",
name: "Category",
value: "LCC",
store: store,
onChange: changeCat,
}, "catSelect").startup();
// SUBCategory combo box fill with query
var subcatqueryTask = new QueryTask("http://sroarcgis.ducks.org/ducksunlimited/rest/services/WSITable/MapServer/4");
var subcatquery = new Query();
subcatquery.returnGeometry = false;
subcatquery.outFields = ["SUBCATEGORY"];
subcatquery.where = "CATEGORY = '" + dom.byId("catSelect").value + "'";
subcatqueryTask.execute(subcatquery, startSubCat);
}
function changeCat(){
// SUBCategory combo box fill with query
var subcatqueryTask = new QueryTask("http://sroarcgis.ducks.org/ducksunlimited/rest/services/WSITable/MapServer/4");
var subcatquery = new Query();
subcatquery.returnGeometry = false;
subcatquery.outFields = ["SUBCATEGORY"];
subcatquery.where = "CATEGORY = '" + dom.byId("catSelect").value + "'";
//domConstruct.destroy("subcatSelect");
subcatqueryTask.execute(subcatquery, startSubCat);
}
function changeSubCat(results) {
var items=[];
var features = results.features;
features.forEach(function(feature) {
cat = feature.attributes.SUBCATEGORY;
items.push({name:cat});
});
var data = {
label: 'name',
items: items
};
var store = new ItemFileReadStore({data:data});
var comboBox = dom.byId("subcatSelect");
comboBox.setStore(store);
}
I am creating the second combo box in the startCat function for testing purposes. I would like to have it elsewhere.
I attempted to create the category combo box declaratively at first but again I couldn't set the store unless I did it when creating the box.
As you will see in the code I tried destroying the second combo box and recreating it but I always received the error that subcatSelect is already registered.
What is the best way to do this? Is there a proper setStore method that I haven't found or is destroying and recreating the combo box a better way to do this? If it is a better way how can I destroy it?
Thanks for any input.
I'm sorry to answer my own question but after two days of playing around with this and writing the question I figured it out just a short while later.
I changed one of the functions to set the store. I had to use dom.registry and setAttribute
function changeSubCat(results) {
var items=[];
var features = results.features;
features.forEach(function(feature) {
cat = feature.attributes.SUBCATEGORY;
items.push({name:cat});
});
var data = {
label: 'name',
items: items
};
var store = new ItemFileReadStore({data:data});
node = registry.byId("subcatSelect");
node.setAttribute("store", store);
}

Cascade or relate filters on jqGrid

I am working on my first ASP.NET MVC 3 application and using the jqGrid to display/filter/sort tabular data. In general this has worked very well for me. One nagging issue I'm having (which the users have mentioned as well) is that my filtering dropdowns are independent of one another - what I mean is that they don't react and re-load based on the selections of the others. Let me give you an example. I have a table which shows the following column data:
Category SubCategory RecipeName RecipeAuthor
For the Category column dropdown, I retrieve a list of Dessert categories (e.g., "Cake", "Cookie", "Pie", etc.) and I envision that that dessert category would drive the other columns. I'd want to retrieve only, say, cookie subcategories if the user picked the category 'Cookie' because filtering only makes sense that way - the grid will respond correctly, for instance if I filter to "Cookie" category and choose "Lemon Chess" (a pie subcategory) then it will display nothing (as we don't make a lemon chess cookie (but maybe we should) - but that's a bit of a clunky interface. Better to only retrieve the subcategories related to the filtered category, I think.
If the user doesn't select a category, it seems reasonable display all data and thus the subcategory, recipename and recipeauthor dropdowns would show all of the possible choices.
In my jqGrid code I define my dropdowns like so:
{ name: 'CategoryID', index: 'CategoryID', width: 200,
editable: true, align: 'left', edittype: 'select', stype: 'select',
editoptions: {
dataUrl: '#Url.Action("AvailableDessertCategories", "Dessert")',
buildSelect: createSelectList
},
searchoptions: {
dataUrl: '#Url.Action("AvailableDessertCategories", "Dessert")',
buildSelect: createSelectList,
sopt: ['eq']
}
},
(there is a similar piece of code for each of those columns)
And createSelectList is defined as:
createSelectList = function (data) {
var response, s = '<select>', i, l, ri;
if (typeof (data) === "string") {
//var leng = data.length - 1;
response = jQuery.parseJSON(data);
}
else {
response = jQuery.parseJSON(data.responseText);
s += '<option value="">Select...</option>';
}
if (response && response.length) {
for (i = 0, l = response.length; i < l; i += 1) {
ri = response[i];
s += '<option value="' + ri + '">' + ri + '</option>';
}
}
return s + '</select>';
}
and my action that returns the list to populate a dropdown looks like this:
public JsonResult AvailableDessertCategories()
{
var context = new DessertEntities();
var dbquery = context.DessertCategories.AsQueryable();
List<string> all = dbquery.Select(m => m.CategoryID).Where(m => m != null).Distinct().ToList();
return Json(all, JsonRequestBehavior.AllowGet);
}
In another page, I do something like I want here for two dropdown lists. The view looks like:
#Html.DropDownListFor(model => model.FlavorID, new SelectList(Model.IceCreamFlavors, "ID", "Name"), "-- Select Ice Cream --", new { #id = "icecreamselector" })
#Html.DropDownListFor(model => model.RecipeID, Enumerable.Empty<SelectListItem>(), "-- Select Recipe --", new { #id = "recipeselector" })
and use some jQuery to fill in the recipe dropdown like this:
$('#icecreamselector').change(function () {
var selectedFlavorID = $(this).val();
if (selectedFlavorID != null) {
$.getJSON('#Url.Action("RecipesForFlavor")', { flavorID: selectedFlavorID }, function (recipes) {
var recipeSelect = $('#recipeselector');
recipeSelect.empty();
recipeSelect.append($('<option/>', { value: 0, text: 'No Recipe' }));
$.each(recipes, function (index, recipe) {
recipeSelect.append($('<option/>', {
value: recipe.ID,
text: recipe.Name
}));
});
var theVal = $("#hiddenrecipeid").val();
if (theVal != null && theVal != "") {
$('#recipeselector').val(theVal);
}
});
}
});
And that passes the ice cream flavor ID into that RecipesForFlavor action and filters down the recipes accordingly.
I guess what I cannot seem to make the leap on here is how to do the same thing with the grid's dropdowns. The two pieces I'm unsure about are how to respond to the fact that the user has selected something in the Category dropdown (or that it was set automatically) and then how to get the ID from that selection. I think the retrieval code (the controller action) is the same sort of thing as I have used elsewhere but I guess the other piece to solve is then setting those retrieve values in the SubCategory dropdown (and the other two as well).
I'm assuming others have down this sort of thing. Any guidance would be very helpful.
A Solution:
To solve the cascading filter issue I took a look at Oleg's examples and gleaned quite a bit from them. This may not be the ideal solution, but it seems to work pretty well for me. Essentially, I added a dataEvents section (sorry, I'm really not much of a javascript programmer - I suspect there's some term for this) to the searchoptions which does the following:
searchoptions: {
dataUrl: '#Url.Action("AvailableDessertCategories", "Dessert")',
buildSelect: createSelectList,
sopt: ['eq'],
dataEvents: [
{
type: 'change',
fn: function (e) {
// grab the category and then update recipes based on it
var selectedCategory = $(e.target).val();
if (selectedCategory !== '') {
$.getJSON('#Url.Action("RecipeNamesForCategory", "Dessert")', { category: selectedCategory }, function (recipes) {
var row = $(e.target).closest('tr.ui-search-toolbar');
var recipeSelect = $("#gs_RecipeName", row[0]);
recipeSelect.empty();
recipeSelect.append('<option value="">Select...</option>');
$.each(recipes, function (index, recipe) {
recipeSelect.append($('<option/>', {
value: recipe,
text: recipe
}));
});
});
}
}
}
]
}
This clears the recipe dropdown (#gs_RecipeName) and then uses the JSON data returned from my RecipeNamesForCategory action on my Dessert controller for the
given category. It adds an empty entry "Select..." to allow all the recipes to be shown rather than always filtering to single recipe and then iterates through the recipe names and creates entries for those.
Note:
I suspect, however, that this can be improved upon. For instance, I've got a function createSelectList which is common for the four different grids I have on
the website and likely I can do something like that for this too. It seems a bit clunky to repeat this code for each of the four grids.
Edit:
I ended up removing the if (selectedCategory !== '') check from the code and modified the action which retrieved my recipe names so that it would do the right thing whether it was sent a category or an empty string. Otherwise, if I cleared the category filter (by choosing the "Select..." option), the recipe name selector wouldn't be repopulated with all recipes names.

JQuery autocomplete problem

Im using JQuerys Autocomplete plugin, but it doesn't autocomplete upon entering anything.
Any ideas why it doesnt work? The basic example works, but not mine.
var ppl = {"ppl":[{"name":"peterpeter", "work":"student"},
{"name":"piotr","work":"student"}]};
var options = {
matchContains: true, // So we can search inside string too
minChars: 2, // this sets autocomplete to begin from X characters
dataType: 'json',
parse: function(data) {
var parsed = [];
data = data.ppl;
for (var i = 0; i < data.length; i++) {
parsed[parsed.length] = {
data: data[i], // the entire JSON entry
value: data[i].name, // the default display value
result: data[i].name // to populate the input element
};
}
return parsed;
},
// To format the data returned by the autocompleter for display
formatItem: function(item) {
return item.name;
}
};
$('#inputplace').autocomplete(ppl, options);
Ok. Updated:
<input type="text" id="inputplace" />
So, when entering for example "peter" in the input field. No autocomplete suggestions appear. It should give "peterpeter" but nothing happens.
And one more thing. Using this example works perfectly.
var data = "Core Selectors Attributes Traversing Manipulation CSS Events Effects Ajax Utilities".split(" ");
$("#inputplace").autocomplete(data);
Well, looking at the code in that plugin, the "parse" option looks like it's only called when the data is retrieved by an AJAX call. As an experiment, you might try passing in the data such that you don't need it:
var ppl = [{"name":"peterpeter", "work":"student"},
{"name":"piotr","work":"student"}];

Categories