Dynamic AutoComplete - codenameone

When I type a location starting with 'W', the related locations are listed below. But if I erase the already typed location and then type in a different one starting with 'L', then the list shows the previously listed options for the old location first(locations starting with 'W') then the options related to new location are listed.
Because of this the autocomplete list displays the locations starting with 'W' and then the locations starting with 'L',both.
I also tried placing options.removeAll(); as first statement in the filter method.
AutoCompleteTextField ac = new AutoCompleteTextField(options) {
protected boolean filter(String add) {
options.removeAll();
if(add.length() == 0) {
return false;
}
String[] l = searchLocations(add);
if(l == null || l.length == 0) {
return false;
}
for(String s : l) {
options.addItem(s);
}
return true;
}
};
//ac.setMinimumElementsShownInPopup(1);
ac.setMinimumLength(1);
Container c = stateMachine.findContainer(form);
AutoCompleteTextField oldac = (AutoCompleteTextField) stateMachine.findAddress(c);
c.replace(oldac, ac, null);
Is there a way to rectify this?
Thanks!!

Check out this live sample, this issue doesn't occur here so I'm guessing the problem with the preexisting results is related to the way you modified the the model.

Related

This script wont select elements/layers which thier names are between angle-brackets "<>"

Whenever I open a PDF-file in Illustrator for edithing, there are a lot of ungrouped and uncategorized Elemetns in it.
So I tried to select multiple elements with a spicific name with the below Script, but since the name of the elements are between Angle-brackets "<someName>" script wont select them:
function selectPageItemsByName(items, name) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.name === name) {
item.selected = true;
}
}
}
function main() {
var document = app.activeDocument;
var name = '<someFile>';
document.selection = null;
selectPageItemsByName(document.pageItems, name);
}
main();
Femkeblanko from Adobe Community says: Items with angle brackets in their label (unless user-created) are unnamed. They correspond to an empty string, i.e. "".
If I remove the Brackets from the name of the Elemetns, the script works but I have a lot of Elements and it needs time.
So, isn't there a way to salve it?
this is a pretty creative way:
// Select->Objects->Clipping Mask
app.executeMenuCommand("Clipping Masks menu item");
// Edit->Clear
app.executeMenuCommand("clear");
but it isn't really documented very well
some links for future reference:
Where is the perfect reference of adobe illustrator script?
https://ai-scripting.docsforadobe.dev/index.html
https://ten-artai.com/illustrator-ccver-22-menu-commands-list/
https://github.com/ten-A/AiMenuObject

is it possible to obtain the results of a custom validation?

Say I have a custom data validation setup like this for a cell in Excel:
I then set the value of the cell in c# using Gembox Spreadsheet.
At this point, is there a way to verify (from c#) if the validation linked to this cell was successful or not?
What has been tried:
I did manage to find the DataValidation object linked to the cell via:
private DataValidation FindDatataValidationForCell(ExcelCell requiredCell)
{
foreach (DataValidation dv in requiredCell.Worksheet.DataValidations)
{
foreach (CellRange range in dv.CellRanges)
{
foreach (ExcelCell foundCell in range)
{
if (foundCell == requiredCell)
return dv;
}
}
}
return null;
}
But in the case of a custom validation, not sure where to go from here.
A workaround might be to write the formula read from the DataValidation object into a new (temporary) cell, and read the result, like this:
public bool IsValid(ExcelCell cell)
{
DataValidation dv = FindDatataValidationForCell(cell);
if (dv != null)
{
if (dv.Type == DataValidationType.Custom)
{
string str = dv.Formula1 as string;
if (str != null && str.StartsWith("="))
{
// dodgy: use a cell which is known to be unused somewhere on the worksheet.
var dummyCell = cell.Worksheet.Cells[100, 0];
dummyCell.Formula = str;
dummyCell.Calculate();
bool res = dummyCell.BoolValue;
dummyCell.Formula = null; // no longer required. Reset.
return res;
}
}
}
return true;
}
This does seem to work, but hoping there is a better way.
Or failing that, maybe a better way to work out a temporary dummy cell location.
Try using this latest bugfix version:
https://www.gemboxsoftware.com/spreadsheet/nightlybuilds/GBS49v1171.zip
Or this latest NuGet package:
Install-Package GemBox.Spreadsheet -Version 49.0.1171-hotfix
Now there is a DataValidation.Validate(ExcelCell) method that you can use.

Checking array object existence

So, I am trying to check the existence of recently pushed array object.
I am developing the web application using angularJS.
I have an array which is defined as
vm.data.detail
So I have a form that let user to CRUD a module. The module is about product stock take. There is a button that will run addProduct() function in my angular controller.
addProduct function:
function addProduct() {
//to check whether the array is empty.
if (vm.data.detail.length == 0) {
vm.data.detail.push({
product: vm.data.product_id.selected,
current_qty: vm.data.product_id.selected.qty,
new_qty: Number(vm.data.product_id.selected.qty) - Number(1),
difference: Number(vm.data.product_id.selected.qty) - (Number(vm.data.product_id.selected.qty) - Number(1)),
remarks: ''
});
console.log("Product just been added");
}
//if the array is not empty
else {
for (var i = 0; i < vm.data.detail.length; i++) {
//to check whether the selected product is already inside the array
if (vm.data.product_id.selected.name == vm.data.detail[i].product.name) {
console.log("same product selected");
//data
}
//if there is no selected product inside the array, then add it
else {
console.log("different product has just been selected");
vm.data.detail.push({
product: vm.data.product_id.selected,
current_qty: vm.data.product_id.selected.qty,
new_qty: 0,
difference: 0,
remarks: ''
});
}
}
}
}
Above code works well when the array just consists of one product. The problem occurs when I am trying to add another product B into the product. Here is the condition :
Product A is already inside the array.
Product B is selected, and then added into the array. Now the array consists of 2 products.
When I am testing to add a new product B, I don't know why the array is still pushed with a new Product B. So now, the array consists of 3 Products (1 Product A, and 2 Product B).
What I wanted is, when I am trying to add the second product B, the array won't be pushed by new product B.
What am I missing here? Have been dealing with it for hours and can't figure out what I have to add for the "validation".
Please note that, the object the array pushing is already correct. I am just don't know how to put the if else. Looks like the logic inside is still lacking of something, but I couldn't figure out what is missing
Thank you so much for the help given.
You're commiting a simple mistake, you are doing the check of else inside the array, you must move it to outside.
Tips:
You can use Array.prototype.find() method to check if the element exists in array, which is much better than perform a traditional for-loop.
As you may have noticed in documentation, the find method have no compatibility with IE and Opera browsers, so if you need this compatibility, you can use Array.prototype.filter().
Below is the code, with both versions (with find and filter) and also with the necessary modifications:
function addProduct() {
//to check whether the array is empty.
if (!vm.data.detail.length) { // you can simply use (!length) instead of comparing with 0
vm.data.detail.push({
product: vm.data.product_id.selected,
current_qty: vm.data.product_id.selected.qty,
new_qty: Number(vm.data.product_id.selected.qty) - Number(1),
difference: Number(vm.data.product_id.selected.qty) - (Number(vm.data.product_id.selected.qty) - Number(1)),
remarks: ''
});
console.log("Product just been added");
}
//if the array is not empty
else {
// if there's no obj with the same name inside the array, it returns undefined, otherwise it returns the object.
var obj = vm.data.detail.find(function(value) {
return value.product.name == vm.data.product_id.selected.name;
});
/* Using FILTER:
var obj = vm.data.detail.filter(function(value) {
return value.product.name == vm.data.product_id.selected.name;
})[0];
*/
// Now you can test, if the object exists
if (obj) {
console.log("same product selected");
}
//if there is no selected product inside the array, then add it
else {
console.log("different product has just been selected");
vm.data.detail.push({
product: vm.data.product_id.selected,
current_qty: vm.data.product_id.selected.qty,
new_qty: 0,
difference: 0,
remarks: ''
});
}
}
}
I hope it helps!
It's a basic logic error. You're doing
for each element {
if element is different from given {
add given to array
}
}
What you need to do is
var allElementsDifferentFromGiven = true
for each element {
if element is same as given {
allElementsDifferentFromGiven = false
break
}
}
if (allElementsDifferentFromGiven) {
add given to array
}
But JavaScript arrays have methods to do that:
if (array.every(function(element) {
return true if element is different given
})) {
add given to array
}
I think problem is here :
because there product is property on Detail object and product does not have name property , it is not matching criteria and going to else condition and pushing into name list.
//to check whether the selected product is already inside the array
if(vm.data.product_id.selected.name == vm.data.detail[i].product.name){
it should be
//to check whether the selected product is already inside the array
if(vm.data.product_id.selected.name == vm.data.detail[i].product){
console.log("same product selected");
//data
}

Kentico Global Events (ObjectEvents) Causes Loop

I'm using ObjectEvents to give ActivityPoints to current user based on fields user filled.
Now for example if user register and fill FirstName I will give 10 points to user.
The problem is that I'm handling ObjectEvents.Update.After and inside it I'm updating userSettings.This causes a unlimited loop and application stops working.
is there any work around?
this is the code block:
var className = e.Object.TypeInfo.ObjectClassName;
DataClassInfo dci = DataClassInfoProvider.GetDataClass(className);
if (dci != null)
{
var fi = new FormInfo(dci.ClassFormDefinition);
if (fi != null)
{
var stopProccess = true;
var fields = new List<FormFieldInfo>();
foreach (var changedColumn in e.Object.ChangedColumns())
{
var field = fi.GetFormField(changedColumn);
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
if (!string.IsNullOrEmpty(activityPointMacro))
{
fields.Add(field);
stopProccess = false;
}
}
if (!stopProccess)
{
var contextResolver = CMSContext.CurrentResolver.CreateContextChild();
foreach (FormCategoryInfo info in fi.ItemsList.OfType<FormCategoryInfo>())
{
contextResolver.SetNamedSourceData(info.CategoryName, info);
}
EditingFormControl data = new EditingFormControl();
foreach (FormFieldInfo info2 in fi.ItemsList.OfType<FormFieldInfo>())
{
contextResolver.SetNamedSourceData(info2.Name, data);
}
foreach (var field in fields)
{
{
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
var activityPoint =
ValidationHelper.GetInteger(contextResolver.ResolveMacros(activityPointMacro), 0);
CMSContext.CurrentUser.UserSettings.UserActivityPoints += activityPoint;
CMSContext.CurrentUser.UserSettings.Update();
}
}
}
}
}
If you just need to give points for user fields then you could just use ObjectEvents.Update.Before, check fields are not empty and assign points. But i can see from the code, you want to have something more complex bulit over macro expressions. So I have a few suggestions for you.
1) ObjectEvents.Update.Before instead of ObjectEvents.Update.After still may be a good idea. Ideally you set your additional values and all is set during one update.
2) Watch only the class names you need
3) Always prefer Provider.SetInfo methods over info.Update(). In case of user settings it's best to set whole user info, so UserInfoProvider.SetUserInfo. Provider methods may add some additional important logic.
4) The code seems like it'll add the points with every update of a user
5) if you are still running into a loop, you need to flag somehow, that some part of code should not be executed again. The best way is to use RequestStockHelper class - add a bool value with a specificname like "PointsProcessed".

SharedSizeGroup Naming Rules

I have a question about naming SharedSizeGroups in WPF grids mostly out of curiosity. I noticed on MSDN that they list restrictions for the group's string name:
The SharedSizeGroup property value must satisfy the following rules:
Must not be empty.
Must only consist of letters, digits, and underscore characters.
Must not start with a numeric value.
I have some groups that I named numerically ("1", "2", "3", etc.) and have never had a problem with them. Just for kicks I renamed some groups to something like ",-[]" and they still worked too. So these rules are not enforced and seemingly not necessary. Does anybody know the reason for the rules in the documentation? Is it possible for the names to conflict with something that WPF is doing internally?
Edit: Okay, so WPF does enforce it after all, validation just doesn't fire in my non-compiled templates.
Interesting, I took a look at the DefinitionBase class in reflector and the SharedSizeGroup property.
It creates a dependency property with a validation callback defined as the following:
SharedSizeGroupProperty = DependencyProperty.Register("SharedSizeGroup", typeof(string), typeof(DefinitionBase), new FrameworkPropertyMetadata(new PropertyChangedCallback(DefinitionBase.OnSharedSizeGroupPropertyChanged)), new ValidateValueCallback(DefinitionBase.SharedSizeGroupPropertyValueValid));
private static bool SharedSizeGroupPropertyValueValid(object value)
{
if (value == null)
{
return true;
}
string str = (string)value;
if (str != string.Empty)
{
int num = -1;
while (++num < str.Length)
{
bool flag = char.IsDigit(str[num]);
if (((num == 0) && flag) || ((!flag && !char.IsLetter(str[num])) && ('_' != str[num])))
{
break;
}
}
if (num == str.Length)
{
return true;
}
}
return false;
}
I tested this, and it does in fact return false for anything containing non-numeric, non-alpha, non-underscore characters. It also returns false for any group starting with a number. So it seems to follow general variable name rules..
My guess is this would most likely throw some sort of exception, but perhaps it is being handled. Have you checked the output window?
I tried an invalid name, and I got an XAMLParseException.

Resources