Google App Maker table query _notContains doesn't work - google-app-maker

App Maker > Page > Table > Events > onAttach
works:
var datasource = widget.datasource;
datasource.query.filters.readByUsers._contains = 'Susanne';
datasource.load();
doesn't work:
var datasource = widget.datasource;
datasource.query.filters.readByUsers._notContains = 'Susanne';
datasource.load();
Any filter with _equals works too.
Can anyone say why?
Or maybe the even better question is:
How do you set filtered table views in app maker?
Again:
How do you exactly set filters for your tables?

According to the official documentation:
Filters startsWith, notStartsWith, contains, notContains are only supported for strings.
Therefore, if your field is a string field, it should definitely work. However, the only reason I can think this will not work, is if you are applying a filter on top of another filter without clearing the previous filter first. I.e., If you run the following code:
var datasource = widget.datasource;
datasource.query.filters.readByUsers._contains = 'Susanne';
datasource.load();
It will only return results where the field readyByUsers contains the string Sussane. If after that you run the code:
var datasource = widget.datasource;
datasource.query.filters.readByUsers._notContains = 'Susanne';
datasource.load();
It will return zero results because all the records loaded contain the string Susanne. Hence it might give you that effect that it is not working when indeed is.
To make sure that your filters work properly, you first need to clear the previous filter before applying a new one, unless you explicitly want to apply a second filter on top of the first one. For that, you need to run the clearFilters method. So your code should look like this:
var datasource = widget.datasource;
datasource.query.clearFilters();
datasource.query.filters.readByUsers._contains = 'Susanne';
datasource.load();
Or like this:
var datasource = widget.datasource;
datasource.query.clearFilters();
datasource.query.filters.readByUsers._notContains = 'Susanne';
datasource.load();

the correct answer was:
because the field was "null"
so you need to add the filter "_notEquals = null;" to get results

Related

Trying To Filter Only Rows That Meet Two Criteria

I promise I have read through the Query information page, but obviously I am missing/misunderstanding something.
I have a Table that has the statuses for multiple departments (the fields are Strings). When a user loads that table I want App Maker to hide jobs that have been finished.
The way we categorize a job as finishes is when:
The Inventory Status = Complete and when the The Delivery Status = Delivered.
Both these conditions need to be met.
Example:
Inventory (Complete) + Delivery (Delivered) = hide
Inventory (In Progress) + Delivery (Delivered) = don't hide
Inventory (Complete) + Delivery (Scheduled) = don't hide
I tried the following, however it hides all the example listed above, not just the first one.
var datasource = app.datasources.SystemOrders;
var inventory = ['Complete'];
var delivery = ['Delivered'];
datasource.query.filters.InventoryStatus._notIn = inventory;
datasource.query.filters.DeliveryStatus._notIn = delivery;
datasource.load();
I have also tried this:
var datasource = app.datasources.SystemOrders;
datasource.query.filters.InventoryStatus._notIn = 'Complete';
datasource.query.filters.DeliveryStatus._notIn = 'Delivered';
datasource.load();
But I get this error:
Type mismatch: Cannot set type String for property _notIn. Type List is expected. at SystemOrders.ToolBar.Button2.onClick:2:46
Any help would be greatly appreciated.
Filters are using AND operator. Please consider switching the Datasource Query Builder and applying the following query:
"InventoryStatus != :CompleteStatus OR DeliveryStatus != :DeliveredStatus"
Set CompleteStatus variable to Complete
Set DeliveredStatus variable to Delivered
Explanation:
Filter you want to apply is "NOT(InventoryStatus = Complete AND DeliveryStatus = Delivered)" which is equivalent to "InventoryStatus != Complete OR DeliveryStatus != Delivered".
Vasyl answer my question perfectly, but I wanted to add a few details in case anyone needs to do the same thing and aren't familiar with using the Datasource Query Builder.
All I did was click the Database I was using and then clicked the Datasources section at the top.
I clicked Add Datasource, named it a new name and pasted Vasyl's code into the Query Builder Expression box.
Two new boxes appear below it allowing me to enter the desired statuses that I wanted to filter out.
Lastly I went back to my Table and changed its datasource to my newly created datasource.
Since you are changing your datasource, if you have any extra code on there it may need to be updated to point to the new datasource.
Example:
I had some buttons that would filter entries for the various departments.
So this:
widget.datasource.query.clearFilters();
var datasource = app.datasources.SystemOrders;
var statuses = ['Complete'];
datasource.query.filters.WarehouseStatus._notIn = statuses;
datasource.load();
had to change to this:
widget.datasource.query.clearFilters();
var datasource = app.datasources.SystemOrders_HideComplete;
var statuses = ['Complete'];
datasource.query.filters.WarehouseStatus._notIn = statuses;
datasource.load();
You can use multiple run and then concatenate their results something like following
/**
* Retrieves records for ActionItems datasource.
* #param {RecordQuery} query - query object of the datasource;
* #return {Array<ActionItems>} user's rating as an array.
*/
function getActionItemsForUser_(query) {
var userRoles = app.getActiveUserRoles();
query.filters.Owner._contains = Session.getActiveUser().getEmail();
var ownerRecords = query.run();
query.clearFilters();
query.filters.AddedBy._contains = Session.getActiveUser().getEmail();
var addedByRecords = query.run();
return addedByRecords.concat(ownerRecords);
}

How Can I Duplicate A Item/Record?

(Deleted my old question to simplify it. )
I enter data in a table, I then want to make an exact duplicate of that data in a new item/record/row*.
*not sure the proper term.
Is there any way to accomplish this?
Sorry for the slow response. Here is what you should do:
Add a "copy" button in the row. In the onClick on that button, add this code:
var createDataSource = widget.datasource.modes.create;
var rowDataSource = widget.datasource;
createDataSource.item.foo = rowDataSource.item.foo;
createDataSource.item.bar = rowDataSource.item.bar;
// And so on for each field
createDataSource.createItem();
You could probably make sure of javascript for-in to loop through all the properties of the item in so you don't have to manually specify each record, but I didn't have time to experiment with this.
Edit:
The above code won't show the copied record in the list immediately, because I used row's create data source, instead of the lists create data source. Try this instead:
var rowDataSource = widget.datasource;
// Instead of using the row datasource for create, explicitly use the data source of your list.
var listDatasource = app.datasources.NameOfYourListsDataSource;
var createDataSource = listDatasource.modes.create;
createDataSource.item.foo = rowDataSource.item.foo;
createDataSource.item.bar = rowDataSource.item.bar;
// And so on for each field
createDataSource.createItem();

Query through SPListCollection

I wonder if it's somehow possible to query a SPListCollection object using SPQuery, as with SPListItemCollection. Imagine that you want to find out which lists were created by a given Author or visible for a given user, for example.
No, this is not possible with SPQuery! But i would prefer you using KeywordQuery:
using (SPSite siteCollection = new SPSite("http://server/sitecollection"))
{
KeywordQuery keywordQuery = new KeywordQuery(siteCollection);
keywordQuery.QueryText = "SharePoint";
SearchExecutor searchExecutor = new SearchExecutor();
ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);
var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
var resultTable = resultTables.FirstOrDefault();
DataTable dataTable = resultTable.Table;
}
Within the Keywordquery you could use for example contentclass STSList to retrieve only lists. And in this case when only using contentclass:"STSList" then you would get all lists where the executor has permissions. You can narrow down by adding additional query parameters. SharePoint search is what you are looking for.

Binding database data to a dropdownlist

I have been trying for a long time to fix the bugs I'm encountering with my dropdownlists in my project. I'm getting data this with at the moment and it's working fine:
using (InfoEntities ie = new InfoEntities())
{
var sqlddl = (from query in ie.Table_Customers
from q in ie.Accounting_PriceType
where query.TypeID == 1 && q.ID == 1
orderby query.Customers
select query).Distinct().ToList();
DropDownListCust.DataTextField = "Customers";
DropDownListCust.DataValueField = "ID";
DropDownListCust.DataSource = sqlddl;
DropDownListCust.DataBind();
}
Now when the user saves the data and opens the website again I need the saved value that was chosen on the dropdownlist earlier retreived. This also works fine but the problem is I'm getting duplicates. Anyways I'm doing it like this and I'm pretty sure I'm doing it wrong:
On the page load i load my dropdownlist to get all the items plus the following to get the saved value:
DropDownListCust.SelectedItem.Text = sql.Customers;
This makes my DDL very buggy, some items dissapear and also sometimes dupicated values. Can anyone please help? I'm using LINQ but I can use some other methods as long as it's fixed.
Cheers
I solved my problem like this:
DropDownList1.ClearSelection();
DropDownList1.Items.FindByText(sql.Customer).Selected = true;

SDL Tridion GetListKeywords using Anquilla Framework

I'm writing a GUI extension and using the Anquilla framework to get a list of Keywords within a Category. I'm obtaining an XML document for the list of keywords then working with that document within my extension.
My problem is that the returned XML doesn't contain the Keyword's 'Description' value. I have the Title and Key etc.
My original code looks like this:
var category = $models.getItem("CATEGORYTCMID:);
var list = category.getListKeywords();
list.getXml();
A typical node returned is this:
<tcm:Item ID="tcm:4-1749-1024"
Type="1024" Title="rate_one" Lock="0" IsRoot="true"
Modified="2012-12-17T23:01:59" FromPub="010 Schema"
Key="rate_one_value" IsAbstract="false"
CategoryTitle="TagSelector"
CategoryID="tcm:4-469-512" Icon="T1024L0P0"
Allow="268560384" Deny="96" IsNew="false"
Managed="1024"/></tcm:ListKeywords>
So I've tried using a Filter to give me additional column information:
var filter = new Tridion.ContentManager.ListFilter();
filter.columns = Tridion.Constants.ColumnFilter.EXTENDED;
var list = category.getListKeywords(filter);
Unfortunately this only gives the additional XML attributes:
IsShared="true" IsLocalized="false"
I'd really like the description value to be part of this XML without having to create a Keyword object from the XML. Is such a thing possible?
cough any ideas? cough
I'm afraid you'll have to load the Keyword itself to get the Description.
It's not used in any lists, so it's not returned in the XML.
You could always create a List Extender to add this information to the list, but try to be smart about it since this extender will execute everytime a GetList is called.
Won't save you from having to open every keyword in the list, but you'll be doing it server-side (with Core Service/NetTcp for instance) which will probably be easier and faster than opening each keyword with Anguilla.
In this instance I only need the one keyword, so I simply get it from the CMS. Getting an object in Anguilla is a bit weird, here's the code:
In your main code area:
var selectedKy = $models.getItem("TcmUriOfKeywordHere");
if (selectedKy.isLoaded()) {
p.selectedKy = selectedKy;
this.onselectedKyLoaded();
} else {
$evt.addEventHandler(selectedKy, "load", this.onselectedKyLoaded);
selectedKy.load();
}
It's worth noting how I store the keyword in the properties of the item, so I can obtain it in the onselectedKyLoaded function
The function called once the item is loaded
ContentBloom.ExampleGuiExtension.prototype.onselectedKyLoaded = function (event) {
var p = this.properties;
var selectedDescription = p.selectedKy.getDescription();
// do what you need to do with the description :)
};
I resolved this, thanks to the answer here: https://stackoverflow.com/a/12805939/1221032 - Cheers Nuno :)

Resources