DOJO Filtering select RegExp query - javascript

I would like to achieve something like this:
filteringSelect.query = {id: "12|13"};
or
filteringSelect.query = {id: new RegExp("12|13")};
Is it possible?
I am using ItemFileReadStore as a store for that FilteringSelect.

See Fuzzy Matches on dijit.form.ComboBox / dijit.form.FilteringSelect Subclass if you want to go the extra mile. This is however for filtering user-input.
For filtering away entries before opening/entering anything in the filteringSelect, continue what youre doing allready. A simple string will not accept the OR operator though, use RegExp.
ItemFileReadStore docs on query
var store = new ItemFileReadStore( {
query: {
id: new RegExp("/^(12|13)$/")
}
} );
As a starting point, ALL items are present in the store, the way to make use of the queryengine is through fetch
store.fetch({
query: {
// yes, you can set the query property directly
// in the store and leave out this parameter
id: new RegExp("^(1|12)$")
},
onComplete: function(items) {
dojo.forEach(items, function(item) {
console.log(store.getValue(item, 'name'))
});
}
})
See http://jsfiddle.net/LuUbT/ for example usage

Related

Using Foreach or another function to reduce the amount of code

please help. I have such a code with Checkboxes. I need to shorten it, namely to go through it through Foreach.
If you can shorten it in another way, then please write it..
let FormData = {
DisplayName: $("#DisplayName").is(":checked"),
Department: $("#Department").is(":checked"),
Post: $("#Post").is(":checked"),
Phone: $("#Phone").is(":checked"),
Location: $("#Location").is(":checked"),
Dinner: $("#Dinner").is(":checked")
}
console.log(JSON.stringify(FormData));
I haven't really tried anything yet. But I didn't really find the answer I needed..
You can declare the fields separately in an array and then use the Array.reduce method to make the object you want:
let FormData = ['DisplayName', 'Department', 'Post', 'Phone', 'Location', 'Dinner'].reduce((acc, field) => {
acc[field] = $(`#${field}`).is(':checked');
return acc;
}, {});
If you don't know the names of the checkboxes and you want to perform this operation of collecting their state on all the checkboxes of a form, you can use this code.
var jsonObject = {};
// For each checkbox - Feed Json object
$('input[type=checkbox]').each(function(index){ jsonObject[$(this).attr('id')] = $(this).is(':checked'); });
console.log(JSON.stringify(jsonObject));
The principle is to use a selection of the checkboxes present on the page to then perform a loop on this selection and recover for each of the boxes their ID and their state.

Add [DataObject] to exsisting array with var key

Using Cordova, I am trying to get an Object to add to an array. I have this working on node JS using :
theData = {[varkey]:DataObject};
But I can't get this to work the same way within my javascript that cordova runs.
I need to do the following:
var TownName = 'Auckland', var townData = (JSON Data);
theArray = new Array();
theArray[TownName] = townData;
I need to be able to call it back as:
theArray['Auckland']
Which will return (JSON Data)
But it doesn't want to store the data with the key inside the array.
I have also tried:
theArray.TownName = townData;
theArray = [{TownName:townData}];
theArray = {[TownName]:townData}];
Nothing wants to store the data.
Any suggestions?
::EDIT::
data.theData =
"Auckland"[
{
"username":"pndemoname1",
"number":"373456",
"www":"http://373456.pndemoname1",
"icon":"/imgs/pndemoname1.png"
},
{
"username":"pndemoname2",
"number":"373458",
"www":"http://373458.pndemoname2",
"icon":"/imgs/pndemoname2.png"
}
data.town = "Auckland";
townData = new Array();
alert(JSON.stringify(data.theData))//Alerts theData
townData[data.town] = data.theData
alert(townData[townName]) //Alerts undefined
::EDIT2::
Re-defining the array within the function that deals with all of the data, seems to make it work.
As per my answer, the issue was that I assumed javascript vars are global.
Use objects or an array of objects.
A data structure like this:
{
town1: town1Data,
town2: town2Data,
}
Or more common:
[
{
name: "Town 1",
data: {...}
},
{
name: "Town 2",
data: {...}
},
]
For reference:
http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
I got what you're trying to do, to add property names dynamically to your object is first, by making sure you are using an OBJECT instead of an array, so when you want to store something you will do the following:
var _obj = {}, _something = 'xyz';
_obj[ _something ] = { ... }; // json structure
The problem you're facing is that you want to assign a string value as a key inside your array, which will not work.
However, you can still use the array you defined and do the following:
var _array = new array();
_array.push( { .... } ); // insert json structure
Remember! By using the array you will have to loop through all values every time you want to access your key, just as the best practice to avoid getting into errors.
Good luck.
The issue was that I didn't define the array within the function of where I was trying to add the information to.
I assumed the var was global (Too much PHP)

Turn Observable Array into nested JSON

I'm having a problem getting an array of information stored properly as JSON.
I made a fiddle to illustrate the problem. Enter a set of tags and take a look at the console to see the output.
More explanation:
So I have an input that takes in a comma-separated list of tags, which I then format.
function createTagArray() {
// given an input value of 'tag1, tag2, tag3'
// returns array = ['tag1', 'tag2', 'tag3']
}
I thought what I needed to do next was the following:
loop over the array and create a 'tag' object for each item which also includes an id for the tag and the id of the contact the tag is associated with.
Each object is pushed to tags, an observable array.
function single_tag(id, contactId, tagLabel) {
var self = this;
self.id = id;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
function createTags() {
var array = createTagArray();
for (var i = 0; i < array.length; i++) {
self.tags().push(new single_tag(uuid.generate(), self.contactId, array[i]));
}
}
Then, I converted it into JSON
self.contactInformation = function() {
return ko.toJS({
"id": self.contactId,
"firstname": self.firstname(),
"lastname": self.lastname(),
... other fields ...
"tags": self.tags(),
})
}
But, when I inspect the console output of calling this function, tags is a collection of arrays, not a nice json object.
How do I get it formatted correctly?
I tried this suggestion, and the tag json is structured correctly, but it is stored with escaped quotes, so that seems wrong.
Thanks for all the help!
I would recommend you knockout.mapping plugin for KO, it allow map complicated JSON structure to view model, even without declarations.
From the documentation
Let’s say you have a JavaScript object that looks like this:
var data = {
name: 'Scot',
children: [
{ id : 1, name : 'Alicw' }
]
}
You can map this to a view model without any problems:
var viewModel = ko.mapping.fromJS(data);
Now, let’s say the data is updated to be without any typos:
var data = {
name: 'Scott',
children: [
{ id : 1, name : 'Alice' }
]
}
Two things have happened here: name was changed from Scot to Scott and children[0].name was changed from Alicw to the typo-free Alice. You can update viewModel based on this new data:
ko.mapping.fromJS(data, viewModel);
And name would have changed as expected. However, in the children array, the child (Alicw) would have been completely removed and a new one (Alice) added. This is not completely what you would have expected. Instead, you would have expected that only the name property of the child was updated from Alicw to Alice, not that the entire child was replaced!
...
To solve this, you can specify which key the mapping plugin should use to determine if an object is new or old. You would set it up like this:
var mapping = {
'children': {
key: function(data) {
return ko.utils.unwrapObservable(data.id);
}
}
}
var viewModel = ko.mapping.fromJS(data, mapping);
In the jsfiddle you were using Knockout 3.0 which doesn't have support for textInput. This was added in 3.2. To use version 3.2 you need to use a cdn such as this: http://cdnjs.com/libraries/knockout
There was typeo in your binding. sumbit should be submit.
There was a problem with your constructor for single_tag. id was not used so I removed it:
function single_tag(contactId, tagLabel) {
var self = this;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
Currently also contactId is not set because the observable has not been set to a value.
To convert to JSON you need to use ko.toJSON instead of ko.toJS:
self.contactInformation = function() {
return ko.toJSON({
"firstname": self.firstname(),
"tags": self.tags(),
})
}
Now when the console writes out an array appears:
{
"firstname":"test",
"tags":[
{"tagLabel":"test1"},
{"tagLabel":"test2"},
{"tagLabel":"test3"}
]
}
JsFiddle
So my problem was more basic than I was realizing. I'm using JSON Server to serve up my data, and I was pulling information from two parts of the database (contacts & tags).
When I tried to update my tags, I was trying to apply them to a property that didn't exist on the contact JSON in my database. Posting the tags separately worked though.

Parse Multiple doesNotMatchKeyInQuery

I am having a problem using Parse queries in javascript. I want to try and use multiple doesNotMatchKeyInQuery functions but it only allows the last one to be used. Any ideas how I can make code like this work? Ignore the errors that might exist in other parts of the code. I wrote this as an example
//Query 1
var Class1 = Parse.Object.extend("Class1");
var class1Query = new Parse.Query(Class1);
class1Query.equalTo("id", id1);
//Query 2
var Class2 = Parse.Object.extend("Class2");
var class2Query = new Parse.Query(Class2);
class2Query.equalTo("id", id2);
//Query 3
var Class3 = Parse.Object.extend("Class3");
var class3Query = new Parse.Query(Class3);
class3Query.equalTo("id", id3);
//Bringing it all together
var finalQuery = new Parse.Query("User");
//This is the part below I am talking about
finalQuery.doesNotMatchKeyInQuery("objectId", "id1", class1Query);
finalQuery.doesNotMatchKeyInQuery("objectId", "id2", class2Query);
finalQuery.doesNotMatchKeyInQuery("objectId", "id3", class3Query);
finalQuery.find({
success: function (results) {
response.success(results);
},
error: function (error) {
response.error(error);
}
});
It's not possible to do such a complex query in a single request. However, you can fetch the keys you don't want to match ahead of time, and construct a secondary query from that.
I've written up an example based upon your code above:
// Assuming we're actually dealing with 3 different classes,
// and these can't be combined into a single query
var class1Query = new Parse.Query('Class1');
class1Query.equalTo('id', id1);
var class2Query = new Parse.Query('Class2');
class2Query.equalTo('id', id2);
var class3Query = new Parse.Query('Class3');
class3Query.equalTo('id', id3);
// Fetch the results from all three queries simultaneously
Parse.Promise.when([
class1Query.find(),
class2Query.find(),
class3Query.find()
]).then(function(results) {
// results will contain three arrays of results
// We can now build a query where the objectId is not equal
// to any of the objectIds of the results
var ids = [];
results.forEach(function(set) {
set.forEach(function(obj) {
ids.push(obj.id);
});
});
return new Parse.Query('FinalClass').notContainedIn('objectId', ids).find();
})
I want to caution you that this query will not be efficient for large sets of data. "Does not equal" queries are never fast, because they have to loop over every object in the table. If there is another way to get your data, I highly encourage it.

Multiple keys query in IndexedDB (Similar to OR in sql)

I have store with multiEntry index on tags.
{ tags: [ 'tag1', 'tag2', 'tag3' ] }
And i have query that also list of tags.
[ 'tag2', 'tag1', 'tag4' ]
I need to get all records which contain one of tag in query (Similar to SQL OR statement).
Currently I cannot find any other solution except iterate over tags in query and search by the each tag in the store.
Is there any better solution?
Thank you.
You cannot retrieve all results with one query except with iteration. You can optimize the search result by opening a index from the lowest value to the highest:
IDBKeyRange.bound ('tag1', 'tag4');
Other Indexed-Db feature you can use is to open multiple queries and combine the result when the queries complete. This way would be much faster than the iteration.
IndexedDB has only range query as Deni Mf answered.
OR query is simply union of multiple queries. That may be OK.
If you want efficient query, you have to iterate the cursor and seek the cursor position as necessary. Using my library, it will be
tags = ['tag2', 'tag1', 'tag4'];
tags.sort();
iter = new ydn.db.KeyIterator('store name', 'tags', IDBKeyRange.bound(tags[0], tags[tags.length-1]);
keys = [];
i = 0;
var req = db.open(iter, function(cursor) {
if (tags.indexOf(cursor.indexKey()) >= 0) {
// we got the result
if (keys.indexOf(cursor.key()) == -1) { // remove duplicate
keys.push(cursor.key());
}
} else {
return tags[++i]; // jump to next index position.
}
);
req.done(function() {
db.list('store name', keys).done(function(results) {
console.log(results);
}
});
Notice that the algorithm has no false positive retrieval. Key only query is performed first, so that we don't waste on de-serilization. The results is retrieved only we get all the primary keys after removing deplicates.

Categories

Resources