How to set a dojo combobox store - javascript

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);
}

Related

Netsuite SSv2 How to Update Filters of a Saved Search

I am trying to figure out how to update the filters of a group saved searches.
I save the filters from a generic saved search:
var searchGen = search.load({
id: 'customsearch_ca_export_detail_search__38'
});
var filter = searchGen.filters;
Then I plug the filters into the searches using a loop:
for (var i = 0; i<selectedMarkets.length; i++){
var selectedSearchId = marketplaces[selectedMarkets[i]].searchId;
var searchObj = search.load({id:selectedSearchId});
var filters = searchObj.filters;
filters = filter;
searchObj.save();
}
All my variables contain the right information. But pushing the data from the generic saved search to the searches I want to update is not working:
filters = filter;
Any help?
Try deconstructing the filters and reconstructing them as such:
for (var i in selectedMarkets){
var selectedSearchId = marketplaces[selectedMarkets[i]].searchId;
var searchObj = SEARCHMODULE.load({id:selectedSearchId});
var oldFilters = searchObj.filters;
var newFilters = [];
for (var k in oldFilters) {
var oldFilter = oldFilters[k];
var filter = {};
filter.name = oldFilter.name;
filter.operator = oldFilter.operator;
filter.values = oldFilter.values;
filter.join = oldFilter.join;
if (typeof(oldFilter.formula) !== 'undefined'){
filter.formula = oldFilter.formula;
}
newFilters.push(SEARCHMODULE.createFilter(filter));
}
searchObj.filters = newFilters;
searchObj.save();
}
Note: You need to adjust the code to work for summary filters.
Super close, try:
searchObj.filters = filter;
searchObj.save();
As written, you're just setting the 'local' variable filters to filter, not the actual search object parameter.
This is a pretty terrible answer and extreme caution is recommended, but might work for your purposes if you really need to do this in SS2. You could recreate the whole search, delete the original, and save the recreated search:
var searchObj = search.load({
id: 'customsearch_test'
});
log.debug('first search', searchObj.filterExpression);
var otherSearch = search.load({
id: 'customsearch_test_2'
});
log.debug('second search', otherSearch.filterExpression);
var newSearch = search.create({
type: otherSearch.searchType,
filters: searchObj.filters, //everything is unchanged but the filters
columns: otherSearch.columns,
title: otherSearch.title || "testy test", //apparently the title doesn't come through in search.load()?!?
id: otherSearch.id,
isPublic: otherSearch.isPublic
});
search.delete({
id: 'customsearch_test_2'
});
var id = newSearch.save();
log.debug('result', id);
var otherSearchAgain = search.load({
id: 'customsearch_test_2'
});
log.debug('second search, after save', otherSearchAgain.filterExpression);
So I spent a couple weeks going back and forth with NetSuite reps, and they have confirmed that there is a bug with search.save() that is preventing this from working.
They have filed a defect for now. Just FYI for anyone else interested.

How to extract filters from BufferedGrid Object in EXTJS

On my UI, I've a grid where I'm applying filters on columns and getting filtered data. In my REST request, my UI is sending filter as a key:value like this:
filter:[{"operator":"gt","value":222,"property":"qty_raw"}]
and, I want to extract the same filter data from the same grid (using ComponentQuery) so that I can send the same filter/filters(more than one column) in another request on a button click handler, I am writing code in EXTJS like this,
var gridObj = Ext.ComponentQuery.query('myGridId')[0];
var filters = gridObj.store.getFilters();
console.log("print filters.....",filters);
filters in Chrome tool looks like the following snapshot, where the data which I need is in items and map, but I can't reach to the data. I don't know if there is any better way to do this? any suggestions?
Update: I tried doing it using store lastOptions property, it still not working (Error: Uncaught TypeError: Cannot read property 'params' of undefined)
var gridObj = Ext.ComponentQuery.query('Grid_xx')[0];
var lastOptions = gridObj.store.lastOptions,
lastParams = Ext.clone(lastOptions.params);
lastParams.limit = limit; //;var limit = gridObj.store.getTotalCount();
lastParams.page = page; // var page = 1
lastParams.start = start; // var start= 1
lastParams.columnsNameArray = JSON.stringify(columnsNameArray);
console.log("columnArray............ =",lastParams.columnsNameArray);
var encodedFilename = Ext.urlEncode(lastParams);
Ext.create('Ext.Component', {
renderTo: Ext.getBody(),
//url: EfwSlamUI.Config.restUrl.GridExport,
cls: 'x-hidden',
params: lastParams,
autoEl: {
tag: 'iframe',
src: Abc.Config.restUrl.GridExport + '?' + encodedFilename}
});
One suggestion:
I think a better approach would be to use the store.reload() function because it will automatically use the last params used by the last stores request.
https://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.data.BufferedStore-method-reload
You can change the filters / sorters on the grid or store.
https://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.data.BufferedStore-property-lastOptions
If you wanna prevent auto-reload of the grid, if a filter is changed, disable autoLoad of the store.

Vaadin Combo-Box: Using value property to pass the index of a selected item

I am trying to discern the index # of the pattern selected in the Combo-box. I need to pass this index value in order for another function to read from a file at the correct location. Essentially, selecting the a pattern in the combobox will let me do a lookup for specifications associated with the selected pattern based on the index. To the best of my knowledge the Vaadin Combobox does not have an index associated with the combobox items, but you are able to pass a different value than the displayed label: https://vaadin.com/docs/-/part/elements/vaadin-combo-box/vaadin-combo-box-basic.html (see: Using Objects as Items). This is solution I am trying to implement, however it gets tricky because I am dynamically populating the combobox items from a JSON file.
The code to dynamically populate the items:
paver = document.querySelector('#paver');
//alert('script executed');
patterns = [];
familyind=y;
$.getJSON('menu.json').done(function(data){
//alert('getJSON request succeeded!');
family = (data.gui[x].family[y].display);
for(ind = 0; ind < data.gui[x].family[y].pattern.length; ind++){
var patternLbl = data.gui[x].family[y].pattern[ind].name;
var patternObj = '{ pattern: { label: "' + patternLbl + '", value: ' + ind + ' } }';
patterns[ind] = patternObj;
}
document.getElementById("cb1").items=patterns;
})
.fail(function(jqXHR, textStatus, errorThrown)
{
alert('getJSON request failed! ' + textStatus);
})
.always(function() { }};
HTML for the ComboBox
<div id="patternSelect">
<template is="dom-bind" id="paver">
<div class="fieldset">
class="patterns" items="[[patterns]]" item-label-path="pattern.label" item-value-path="pattern.value"></vaadin-combo-box>
</div>
</template>
</div>
The output I get when I try to execute this is that the entire constructed string gets assembled into my selection choices. Theoretically, this should not have happened because the item-value-path and item-label-path were specified when declaring the combobox.
Screenshot of Output
It says: { pattern: { label: "A-3 Piece Random", value: 0 } }
WORKING TOWARDS A SOLUTION SECTION:
___________(April 27, 7:00pm)___________
Suggested solution to use,
var patternObj = { pattern: { label: patternLbl, value: ind } };
works fine in displaying labels:
However, I am using a trigger to detect when the value in the combo-box is changed and return the new value. Here is the code for the trigger:
// select template
var paver = document.querySelector('#paver');
// define the ready function callback
paver.ready = function () {
// use the async method to make sure you can access parent/siblings
this.async(function() {
// access sibling or parent elements here
var combobox = document.querySelector('#cb1')
combobox.addEventListener('value-changed', function(event) {
// FOR REFERENCE LOG ERRORS, THIS COMMENT IS ON HTML:215
console.log(event.detail.value);
patval = event.detail.value;
console.log(patval)
// Do stuff with fetched value
});
});
};
I have made the suggested change to using a 'value-changed' trigger. It works very well with two slight issues. First, it returns each of the console log calls twice (not sure why twice). Second, when I select the first combo-box item it returns my values but does not set the label as selected. This is not an issue with the other combo-box items, but the first item needs to be selected twice to have the label set. Please watch this short video for a demonstration: https://youtu.be/yIFc9SiSOUM. This graphical glitch would confuse the user as they would think they did not select a pattern when they know they had. Looking for a solution to make sure the label is set when the first item is selected.
You are setting a currently a String to patternObj while you should be setting an Object.
Try using either var patternObj = JSON.parse('{ pattern: { label: "' + patternLbl + '", value: ' + ind + ' } }'; or even simpler:
var patternObj = { pattern: { label: patternLbl, value: ind } };
Also, I would recommend initializing the patterns = [] inside the done callback to make sure you're not leaving any old items in the patterns when the data changes.

Alfresco: Javascript data list creation

I am attempting to execute some Javascript in my Alfresco workflow to create a custom data list type in my site called "Testing". But before I fill in my custom data list type information, I tried simply creating a contact list data list based on examples I found to make sure it works.
Here is my code:
var site = siteService.getSite("Testing");
var dataLists = site.childByNamePath("dataLists");
if (!dataLists) {
var dataLists = site.createNode("dataLists", "cm:folder");
var dataListProps = new Array(1);
dataListProps["st:componentId"] = "dataLists";
dataLists.addAspect("st:siteContainer", dataListProps);
dataLists.save();
logger.log("Created new datalists folder.");'
}
var contactList = dataLists.childByNamePath("contactlist1");
if (!contactList) {
var contactList = dataLists.createNode("contactlist1","dl:dataList");
// tells Share which type of items to create
contactList.properties["dl:dataListItemType"] = "dl:contact";
contactList.save();
var contactListProps = [];
contactListProps["cm:title"] = "My Contacts";
contactListProps["cm:description"] = "A contact list generated by a javascript.";
contactList.addAspect("cm:titled", contactListProps);
logger.log("Created contact datalist.");
}
var contact = contactList.createNode(null, "dl:contact")
contact.properties["dl:contactFirstName"] = "Florian";
contact.properties["dl:contactLastName"] = "Maul";
contact.properties["dl:contactEmail"] = "info#fme.de";
contact.properties["dl:contactCompany"] = "fme AG";
contact.properties["dl:contactJobTitle"] = "Senior Consultant";
contact.properties["dl:contactPhoneMobile"] = "not available";
contact.properties["dl:contactPhoneOffice"] = "not available";
contact.properties["dl:contactNotes"] = "Alfresco Expert";
contact.save();
logger.log("Created new contact: " + contact.nodeRef);
My guess is it's not selecting the right site, but I'm not sure how else to set the site variable to the "Testing" site. Also, I know this code is in the right place in my .bpmn file, because other Javascript in there executes correctly.
What is wrong with my code?
There are 2 javascript object on which you have confusion.One is site and other is node.Site object does not have method called childByNamePath.
Instead of that use below for getting datalist.
var dataLists = site.getContainer("dataLists");
Your code for retrieving site is correct.The only change is for datalist.

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/

Categories