APEX - Why aren't my input validations working? - validation

I'm working on a contact search page and I have a problem. My console has no errors but when I run a search, the results don't generate and all of my input validation errors prompt.
For Example:
Jane Grey
The Search for Jane Grey
Here is my VisualForce page:
<apex:page id="ContactPage" controller="Ctrl_ContactSearch">
<apex:tabPanel id="ContactPanel">
<apex:tab id="ContactTab" label="Contact Search">
<apex:form id="ContactForm">
<!-- Input Fields -->
<apex:pageBlock title="Contact Search Page" id="ContactBlock">
<apex:pageBlockSection id="contact-table" columns="3">
<apex:pageBlockSectionItem id="NameInputBlock">
<apex:outputLabel value="Name" />
<apex:inputText id="NameInputField" value="{!name}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem id="PhoneInputBlock">
<apex:outputLabel value="Phone" />
<apex:inputText id="PhoneInputField" value="{!phone}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem id="EmailInputBlock">
<apex:outputLabel value="Email" />
<apex:inputText id="EmailInputField" value="{!email}" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<!-- Buttons -->
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="Search Contacts" action="{!searchContacts}" />
<apex:commandButton value="Clear Fields" action="{!ClearFields}" />
</apex:pageBlockButtons>
</apex:pageBlock>
<!-- Results Display -->
<apex:pageBlock title="Results" rendered="{!contacts.size!=0}" >
<apex:pageBlockSection >
<apex:pageBlockTable value="{!contacts}" var="c" id="contact-table">
<apex:column >
<apex:facet name="header">Name</apex:facet>
{!c.Name}
</apex:column>
<apex:column >
<apex:facet name="header">Phone Number</apex:facet>
{!c.Phone}
</apex:column>
<apex:column >
<apex:facet name="header">Email</apex:facet>
{!c.Email}
</apex:column>
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:pageBlock>
<!-- Error Display -->
<apex:pageBlock title="Errors" id="ErrorSection" >
<apex:pageMessages id="ErrorsListing">
</apex:pageMessages>
</apex:pageBlock>
</apex:form>
</apex:tab>
</apex:tabPanel>
<script type = "text/javascript">
var name = document.getElementByID("name");
var phone = document.getElementByID("phone");
var email = document.getElementByID("email");
</script>
</apex:page>
Here is my Controller:
public with sharing class Ctrl_ContactSearch
{
public List<Contact> contacts { get; set; }
public String name { get; set; }
public String phone { get; set; }
public String email { get; set; }
public integer MatchingContacts { get; set; }
public boolean ErrorsPresent = false;
public boolean Error_NoResults = false;
public boolean Error_FieldsEmpty = false;
public boolean Error_NameSyntax = false;
public boolean Error_PhoneSyntax = false;
public boolean Error_EmailSyntax = false;
/* Name Input Validation Regex*/
public static Boolean ValidationName (String name)
{
Boolean NameIsValid = false;
String nameRegex = '/^[a-zA-Z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*(__[cC])?$/';
Pattern PatternName = Pattern.compile(nameRegex);
Matcher nameMatcher = PatternName.matcher(name);
if (nameMatcher.matches())
{
NameIsValid = true;
}
return NameIsValid;
}
/* Phone Input Validation Regex*/
public static Boolean ValidationPhone (String phone)
{
Boolean PhoneIsValid = false;
String phoneRegex = '//^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$//';
Pattern PatternPhone = Pattern.compile(phoneRegex);
Matcher phoneMatcher = PatternPhone.matcher(phone);
if (phoneMatcher.matches())
{
PhoneIsValid = true;
}
return PhoneIsValid;
}
/* Email Input Validation Regex*/
public static Boolean ValidationEmail (String email)
{
Boolean EmailIsValid = false;
String emailRegex = '/^\\w+([\\.-]?\\w+)*#\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$//';
Pattern PatternEmail = Pattern.compile(emailRegex);
Matcher emailMatcher = PatternEmail.matcher(email);
if (emailMatcher.matches())
{
EmailIsValid = true;
}
return EmailIsValid;
}
/* Runs when "Clear Fields" button is pressed*/
public void ClearFields()
{
name = '';
phone = '';
email = '';
}
/* Runs when "Search Contacts" button is pressed*/
public PageReference searchContacts()
{
/* Checks if input fields are empty*/
if (name == '' && phone == '' && email == '')
{
Error_FieldsEmpty = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Your fields are blank. Please enter your information in the remaining fields to proceed'));
}
else
{
/* Checks Input Validation Results*/
if (ValidationName(name) == false)
{
Error_NameSyntax = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Inproper name format. Please enter name in following format : Firstname Lastname.'));
}
if (ValidationPhone(phone) == false)
{
Error_PhoneSyntax = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Inproper phone number format. Please enter number in following format : XXX-XXX-XXXX.'));
}
if (ValidationPhone(email) == false)
{
Error_EmailSyntax = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Inproper email format. Please enter email in following format : XXX#emailprovider.com'));
}
/* Runs if all Validation results are 'true'*/
if (ValidationName(name) == true && ValidationPhone(phone) == true && ValidationPhone(email) == true)
{
contacts = [select Name, Phone, Email from Contact where Name = :name or Phone = :phone or email = :email];
MatchingContacts = contacts.size();
/* Checks if/how many matches were found from the search*/
if(MatchingContacts != 0)
{
system.debug('There are currently ' + MatchingContacts + 'results found.' );
}
else
{
Error_NoResults = false;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'No matching Contacts were found.'));
}
}
}
/* Displays "Error" field if any errors are found*/
if (Error_NoResults == true || Error_FieldsEmpty == true || Error_NameSyntax == true || Error_PhoneSyntax == true || Error_EmailSyntax == true)
{
ErrorsPresent = true;
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.WARNING,'There are errors present. Please read and follow instructions accordingly.'));
}
return null;
}
}
What do I have wrong here?
For some reason StackOverflow won't let me make this post without adding extra text. I'm putting this here to increase the wordcount.

1st, some constructive criticism:
The DRY principle says you should combine your validation methods into 1.
2nd, it looks like your regexs weren't good. Depending on the exact requirements of the validation, you can try these below... Taken willy nilly from other replies to other questions on forums much like this one... (I am by no means a Regex expert)
Try something like this:
private string nameRegEx = '^[a-zA-Z][a-zA-Z0-9 ]+$';
private string emailRegEx = '^[a-zA-Z0-9._|\\\\%#~`=?&/$^*!}{+-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$';
private string phoneRegEx = '^(\\d{3}\\-\\d{3}-\\d{4})?$';
public static Boolean Validate (String str, String validation)
{
Boolean IsValid = false;
Pattern Pattern = Pattern.compile(validation);
Matcher Matcher = Pattern.matcher(str);
if (Matcher.matches())
{
IsValid = true;
}
return IsValid;
}
Also, this function returns a Boolean. When checking its return value, you don't need the equality operators. Just use if (Validate(name, nameRegex)) { ... } or if (!Validate(email, emailRegex)) { ... }

Related

how to show a alert if table is empty?

I want to show a alert if table is empty, problem is that i have to click twice before he is hitting
the else statement to show my alert.
I use a overlay to show the devices.
I tried OnafterrenderAsync, OnInitializedAsync, OnParameterSetAsync
If the api call gets devices than there is no problem, the table is loading but if there is no data in the table he doesn't go to the else statement to show my mudalert
<PageTitle>#AccountResource.DevicesLinkLabel</PageTitle>
#if (isLoading)
{
}
else
{
#if (!isShowing)
{
<MudTable T="DeviceModel" ServerData="#(new Func<TableState, Task<TableData<DeviceModel>>>(LoadData))" Hover="true" Breakpoint="Breakpoint.Sm" Dense="true" #ref="table">
<HeaderContent>
<MudTh>#AccountResource.DevicesLinkLabel</MudTh>
<MudTh>#SharedResource.Type</MudTh>
<MudTh>#SharedResource.Version</MudTh>
<MudTh>#SharedResource.VersionAppNumber</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="DeviceName">#context.DisplayName</MudTd>
<MudTd DataLabel="DeviceType">#context.Type</MudTd>
<MudTd DataLabel="DeviceVersion">#context.Version</MudTd>
<MudTd DataLabel="DeviceVersionAppNumber">#context.VersionAppNumber</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager />
</PagerContent>
</MudTable>
}
else
{
<MudAlert Severity="MudBlazor.Severity.Warning">#SharedResource.NothingToShow</MudAlert>
}
}
#code {
[Parameter]
public long UserId { get; set; }
[Parameter]
public long OrganisationId { get; set; }
[Parameter]
public EventCallback<ModelBase> ShowResponseInToast { get; set; }
private MudTable<DeviceModel>? table;
private bool isLoading = true;
private bool isShowing;
protected override async Task OnParametersSetAsync()
{
try
{
if (table != null)
{
//table.CurrentPage = 0;s
await table.ReloadServerData();
}
}
finally
{
isLoading = false;
}
}
private async Task<TableData<DeviceModel>> LoadData(TableState state)
{
var request = new GetDeviceRequest
{
OrganisationId = OrganisationId,
UserId = UserId,
Page = state.Page,
PageSize = state.PageSize,
};
var response = await DeviceManagerClient.GetDeviceResponseAsync(request);
if (table?.Items?.Any() == true)
{
isShowing = false;
return new TableData<DeviceModel>
{
Items = response.Results,
TotalItems = response.TotalCount
};
}
else
{
isShowing = true;
return new TableData<DeviceModel>
{
Items = response.Results,
};
}
}
}

Does the IClientValidator support input file?

Edit
I found that the problem is that View Components are unable to have an #section (see ViewComponent and #Section #2910 ) so adding custom client-side validation using the unobtrusive library seems imposible (or very complex). Moreover, the inability of including the required javascript into a View Component makes me regret of following this approach to modularize my app in the first place...
I am learning to make custom validation attributes with client-side support. I was able to implement a custom validator for a string property and it works pretty well, but when I tried to make one for input file it doesn't work (i.e. when I select a file in my computer, the application doesn't display the validation messages. The server-side validation works. Here is some code that shows my implementation.
The class of the model
public class UploadPanelModel
{
public int? ID { get; set; }
public string Title { get; set; }
public string Description { get; set; } //Raw HTML with the panel description
[FileType(type: "application/pdf")]
[FileSize(maxSize: 5000000)]
public IFormFile File { get; set; }
public byte[] FileBytes { get; set; }
public ModalModel Modal { get; set; } //Only used if the Upload panel uses a modal.
The validator
public class FileSizeAttribute : ValidationAttribute, IClientModelValidator
{
private long _MaxSize { get; set; }
public FileSizeAttribute (long maxSize)
{
_MaxSize = maxSize;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
UploadPanelModel panel = (UploadPanelModel)validationContext.ObjectInstance;
return (panel.File==null || panel.File.Length <= _MaxSize) ? ValidationResult.Success : new ValidationResult(GetFileSizeErrorMessage(_MaxSize));
}
private string GetFileSizeErrorMessage(long maxSize)
{
double megabytes = maxSize / 1000000.0;
return $"El archivo debe pesar menos de {megabytes}MB";
}
public void AddValidation(ClientModelValidationContext context)
{
if(context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-filesize", GetFileSizeErrorMessage(_MaxSize));
var maxSize = _MaxSize.ToString();
MergeAttribute(context.Attributes, "data-val-filesize-maxsize", maxSize);
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
The javascript in the Razor View
#section Scripts{
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$.validator.addMethod('filesize',
function (value, element, params) {
var size = $((params[0]).val()).size(),
maxSize = params[1];
if (size < maxSize) {
return false;
}
else {
return false;
}
}
);
$.validator.unobtrusive.adapters.add('filesize',
['maxSize'],
function (options) {
var element = $(options.form).find('input#File')[0];
options.rules['filesize'] = [element, options.params['maxSize']];
options.messages['filesize'] = options.message;
}
);
</script>
I always return false in the javascript method to force the application to show the validation error regardless the chosen file, but it still doesn't work.
Your addMethod() function will be throwing an error because params[0] is not a jQuery object and has no .val() (you also have the $ in the wrong place). You would need to use
var size = params[0].files[0].size;
However I suggest you write you scripts as
$.validator.unobtrusive.adapters.add('filesize', ['maxsize'], function (options) {
options.rules['filesize'] = { maxsize: options.params.maxsize };
if (options.message) {
options.messages['filesize'] = options.message;
}
});
$.validator.addMethod("filesize", function (value, element, param) {
if (value === "") {
return true;
}
var maxsize = parseInt(param.maxsize);
if (element.files != undefined && element.files[0] != undefined && element.files[0].size != undefined) {
var filesize = parseInt(element.files[0].size);
return filesize <= maxsize ;
}
return true; // in case browser does not support HTML5 file API
});

How to validate one field related to another's value in ASP .NET MVC 3

I had two fields some thing like phone number and mobile number. Some thing like..
[Required]
public string Phone { get; set; }
[Required]
public string Mobile{ get; set; }
But user can enter data in either one of it. One is mandatory. How to handle them i.e how to disable the required field validator for one field when user enter data in another field and viceversa. In which event i have to handle it in javascript and what are the scripts i need to add for this. Can anyone please help to find the solution...
One possibility is to write a custom validation attribute:
public class RequiredIfOtherFieldIsNullAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _otherProperty;
public RequiredIfOtherFieldIsNullAttribute(string otherProperty)
{
_otherProperty = otherProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(_otherProperty);
if (property == null)
{
return new ValidationResult(string.Format(
CultureInfo.CurrentCulture,
"Unknown property {0}",
new[] { _otherProperty }
));
}
var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue == null || otherPropertyValue as string == string.Empty)
{
if (value == null || value as string == string.Empty)
{
return new ValidationResult(string.Format(
CultureInfo.CurrentCulture,
FormatErrorMessage(validationContext.DisplayName),
new[] { _otherProperty }
));
}
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredif",
};
rule.ValidationParameters.Add("other", _otherProperty);
yield return rule;
}
}
which you would apply to one of the properties of your view model:
public class MyViewModel
{
[RequiredIfOtherFieldIsNull("Mobile")]
public string Phone { get; set; }
public string Mobile { get; set; }
}
then you could have a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
and finally a view in which you will register an adapter to wire the client side validation for this custom rule:
#model MyViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
jQuery.validator.unobtrusive.adapters.add(
'requiredif', ['other'], function (options) {
var getModelPrefix = function (fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf('.') + 1);
}
var appendModelPrefix = function (value, prefix) {
if (value.indexOf('*.') === 0) {
value = value.replace('*.', prefix);
}
return value;
}
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(':input[name="' + fullOtherName + '"]')[0];
options.rules['requiredif'] = element;
if (options.message) {
options.messages['requiredif'] = options.message;
}
}
);
jQuery.validator.addMethod('requiredif', function (value, element, params) {
var otherValue = $(params).val();
if (otherValue != null && otherValue != '') {
return true;
}
return value != null && value != '';
}, '');
</script>
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.Phone)
#Html.EditorFor(x => x.Phone)
#Html.ValidationMessageFor(x => x.Phone)
</div>
<div>
#Html.LabelFor(x => x.Mobile)
#Html.EditorFor(x => x.Mobile)
#Html.ValidationMessageFor(x => x.Mobile)
</div>
<button type="submit">OK</button>
}
Pretty sick stuff for something so extremely easy as validation rule that we encounter in our everyday lives. I don't know what the designers of ASP.NET MVC have been thinking when they decided to pick a declarative approach for validation instead of imperative.
Anyway, that's why I use FluentValidation.NET instead of data annotations to perform validations on my models. Implementing such simple validation scenarios is implemented in a way that it should be - simple.
I know this question is not so hot, because it was asked relatively long time ago, nevertheless I'm going to share with a slightly different idea of solving such an issue. I decided to implement mechanism which provides conditional attributes to calculate validation results based on other properties values and relations between them, which are defined in logical expressions.
Your problem can be defined and automatically solved by the usage of following annotations:
[RequiredIf("Mobile == null",
ErrorMessage = "At least email or phone should be provided.")]
public string Phone{ get; set; }
[RequiredIf("Phone == null",
ErrorMessage = "At least email or phone should be provided.")]
public string Mobile { get; set; }
If you feel it would be useful for your purposes, more information about ExpressiveAnnotations library can be found here. Client side validation is also supported out of the box.
Since nobody else suggested it, I'm going to tell you a different way to do this that we use.
If you create a notmapped field of a custom data type (in my example, a pair of gps points), you can put the validator on that and you don't even need to use reflection to get all the values.
[NotMapped]
[DCGps]
public GPS EntryPoint
{
get
{
return new GPS(EntryPointLat, EntryPointLon);
}
}
and the class, a standard getter/setter
public class GPS
{
public decimal? lat { get; set; }
public decimal? lon { get; set; }
public GPS(decimal? lat, decimal? lon)
{
this.lat = lat;
this.lon = lon;
}
}
and now the validator:
public class DCGps : DCValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (!(value is GPS)) {
return new ValidationResult("DCGps: This annotation only works with fields with the data type GPS.");
}
//value stored in the field.
//these come through as zero or emptry string. Normalize to ""
string lonValue = ((GPS)value).lonstring == "0" ? "" : ((GPS)value).lonstring;
string latValue = ((GPS)value).latstring == "0" ? "" : ((GPS)value).latstring;
//place validation code here. You have access to both values.
//If you have a ton of values to validate, you can do them all at once this way.
}
}

ASP MVC 2 Validation : Passing Javascript code to the client

I am writing a custom validation attribute
It does conditional validation between two fields
When I create my rule, one of the things that I could not solve is how to pass javascript code through ValidationParameters
Usually, I just do
ValidationParameters["Param1"] = "{ required :function(element) { return $("#age").val() < 13;) }"
However, the MicrosoftMvcJQueryValidation.js routines trnasforms this to
Param1 = "{ required :function(element) { return $("#age").val() < 13;) }"
I could use Param1.eval() in Javascript. This will evaluates and executes the code but I just want to evalute the code and execute it later
JSON parser does not parse string contening Javascript code
So I am asking here for any idea
Not sure how you would inject javascript as you describe, but you may want to consider using the custom validation pattern for ASP.NET MVC 2.
Important pieces are the ValidationAttribute, DataAnnotationsModelValidator, registering the validator in Application_Start with DataAnnotationsModelValidatorProvider.RegisterAdapter, and the client side Sys.Mvc.ValidatorRegistry.validators function collection to register your client side validation code.
Here's the example code from my post.
[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
public string Password { get; set; }
[StringLength(128, ErrorMessage = "Must be under 128 characters.")]
[MinStringLength(3, ErrorMessage = "Must be at least 3 characters.")]
public string PasswordAnswer { get; set; }
public class MinStringLengthAttribute : ValidationAttribute
{
public int MinLength { get; set; }
public MinStringLengthAttribute(int minLength)
{
MinLength = minLength;
}
public override bool IsValid(object value)
{
if (null == value) return true; //not a required validator
var len = value.ToString().Length;
if (len < MinLength)
return false;
else
return true;
}
}
public class MinStringLengthValidator : DataAnnotationsModelValidator<MinStringLengthAttribute>
{
int minLength;
string message;
public MinStringLengthValidator(ModelMetadata metadata, ControllerContext context, MinStringLengthAttribute attribute)
: base(metadata, context, attribute)
{
minLength = attribute.MinLength;
message = attribute.ErrorMessage;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
var rule = new ModelClientValidationRule
{
ErrorMessage = message,
ValidationType = "minlen"
};
rule.ValidationParameters.Add("min", minLength);
return new[] { rule };
}
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MinStringLengthAttribute), typeof(MinStringLengthValidator));
}
Sys.Mvc.ValidatorRegistry.validators["minlen"] = function(rule) {
//initialization
var minLen = rule.ValidationParameters["min"];
//return validator function
return function(value, context) {
if (value.length < minLen)
return rule.ErrorMessage;
else
return true; /* success */
};
};

ICEfaces multiple selectInputText widgets inside datatable behave erratically

I have multiple selectInputText controls inside a datatable, something like this:
<ice:dataTable id="attributesList" value="#{myForm.myAttributes}" var="entry" cellpadding="0" rows="9999" columnClasses="myColumn,myColumn">
<ice:column>
<!-- auto-complete -->
<ice:panelGroup>
<ice:selectInputText rows="15" width="120" maxlength="255" value="#{entry.attribute.stringValue}" valueChangeListener="#{myFieldAutocomplete.updateList}" immediate="true">
<f:selectItems value="#{myFieldAutocomplete.list}" />
<f:attribute name="fieldName" value="#{entry.name}" />
</ice:selectInputText>
</ice:panelGroup>
</ice:column>
</ice:dataTable>
My backing bean code is this:
public class myFieldAutocomplete {
// default value, empty string
private String currentFieldValue = "";
// list of possible matches.
private List<SelectItem> matchesSIList = new ArrayList<SelectItem>();
public void updateList(ValueChangeEvent event) {
currentFieldValue = "";
// get a new list of matches.
setMatches(event);
if (event.getComponent() instanceof SelectInputText) {
SelectInputText autoComplete = (SelectInputText) event.getComponent();
if (autoComplete.getSelectedItem() != null) {
currentFieldValue = (String) autoComplete.getSelectedItem().getValue();
}
else {
String tempValue = getMatch(autoComplete.getValue().toString());
if(tempValue != null) {
currentFieldValue = tempValue;
}
}
}
}
public String getCurrentFieldValue() {
return currentFieldValue;
}
public List<SelectItem> getList() {
return matchesSIList;
}
private String getMatch(String value) {
String result = null;
if (matchesSIList != null) {
String str;
Iterator<SelectItem> itr = matchesSIList.iterator();
while (itr.hasNext()) {
SelectItem si = (SelectItem) itr.next();
str = (String) si.getValue();
if (str.startsWith(value)) {
result = str;
break;
}
}
}
return result;
}
public void setMatches(ValueChangeEvent event) {
List<String> newMatchesStrList = new ArrayList<String>();
if (event.getComponent() instanceof SelectInputText) {
SelectInputText autoComplete = (SelectInputText) event.getComponent();
myClassDAO myDao = (myClassDAO) Context.getInstance().getBean(myClassDAO.class);
String fieldName = (String) autoComplete.getAttributes().get("fieldName");
newMatchesStrList = myDao.findTemplateFieldValues((String)autoComplete.getValue(), fieldName);
}
// assign new matchList
if (this.matchesSIList != null) {
this.matchesSIList.clear();
}
Iterator<String> itr = newMatchesStrList.iterator();
while(itr.hasNext()) {
String str = (String) itr.next();
matchesSIList.add(new SelectItem(str, str));
}
}
}
The bean is in request scope (although I also tried with session scope). I am using ICEfaces community edition 1.8.2.
The problem is, these auto-complete controls are created dynamically based on certain attributes of each entry in the datatable. So, you can have, for example 2 or more such auto-complete controls in the same panelGroup. When this is the case, when you start typing something the first control, it seems to be triggering the event for all sibling auto-complete controls, and in the end returns the list for the last in order.
In general, I noticed erratic behavior caused by the fact that the event is triggered for all auto-complete controls at once, and values/lists get confused.
What am I doing wrong?
Thanks in advance!

Resources