Help With Multiple Text Field Valdiation

Discussion in 'iOS Programming' started by keeweepoo, Jan 12, 2010.

  1. keeweepoo macrumors newbie

    Joined:
    Dec 26, 2007
    #1
    I have five fields I need to validate, as different fields require a different range of numbers to have input by the user. The idea is when the user clicks to the next field it checks the previous field, however this isn't how it's working :( Is there a better way in my code to do this? I'd also like it when the user hits wrong info and disregards the error messages, it doesn't allow them to go to the next field.

    Below is my code:

    Code:
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {	
    	//NSLog(@"BundlePath: %@", [[NSBundle mainBundle] bundlePath]);
    	
    	//declare the vars
    	NSString *userNameOne = txtUserName.text;
    	float numOne = [userNameOne intValue];			//age in years
    	NSString *userNameTwo = txtUserName2.text;
    	float numTwo = [userNameTwo intValue];			//iop
    	NSString *userNameThree = txtUserName3.text;
    	float numThree = [userNameThree intValue];		//cct
    	NSString *userNameFour = txtUserName4.text;	
    	float numFour = [userNameFour intValue];		//psd
    	NSString *userNameFive = txtUserName5.text;
    	float numFive = [userNameFive intValue];
    
    	
    	if(numOne < 40 || numOne > 100)
    	{
    			
    		//play sound and vibrate for alert
    		NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"];
    		NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile];
    		SystemSoundID  bonkSoundID;
    		AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID);
    		AudioServicesPlaySystemSound(bonkSoundID);
    		AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);	//vibrate
    		
    		//show alert
    		UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"Age Error"
    							  message:@"Your age must be at least 40 years old and less than 100 years old"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    		[alert show];
    		[alert release];
    	}
    	
    	else if (numTwo < 20 || numTwo > 32)
    	{
    		UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"IOP Error"
    							  message:@"Your IOP must be between 20 and 32"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    		[alert show];
    		[alert release];
    	}
    	
    	else if (numThree < 475 || numThree > 650)
    	{
    		UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"CCT Error"
    							  message:@"Your CCT must be between 475 and 650"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    		[alert show];
    		[alert release];
    	}
    	
    	else if (numFour < .50 || numFour > 3.00)
    	{
    		UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"PSD Error"
    							  message:@"Your PSD must be between .50 and 3.00"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    		[alert show];
    		[alert release];
    	}
    	
    	else if (numFive < 0.80)
    	{
    		UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"C/D Error"
    							  message:@"Your C/D must be between 0 and .80"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    		[alert show];
    		[alert release];
    	}
    }
    And you can see a video of how it works (rather buggy)
    http://screencast.com/t/NWNjZTU2M

    Any advice would be greatly appreciated!
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    First, start with giving us more details on how it's "not working". Second, textFieldDidEndEditing: is passed the textField. I would use that in your logic. For example:
    Code:
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {	
        if (textField == txtUserName) {
            NSString *userNameOne = txtUserName.text;
            float numOne = [userNameOne intValue];			//age in years
            if(numOne < 40 || numOne > 100)
            {
    	    ...
    
     
  3. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #3
    I concur. I watched the video and based on the logic you provided, it will ALWAYS check the first field. Since you used a if ... else if ... endif construct, you're ALWAYS checking the first field. If it's OK, then it will check the second field, and so on.

    So, if in your video you had entered a valid number for the first field and an invalid for the second, it would trap on the second field for each of the subsequent fields.

    Checking the object passed in leaves me with an icky feeling, as I would have a validator object that would validate the fields as in an appropriate fashion. Going super-anal on the OO front, I would make the actual text field a subclass/implementation of a class that provided a validation method, and perhaps bounds for numeric validation, etc. However, using the if (textField == thisTextField) else if (textField == thatTextField) is OK if you must.

    Good luck moving forward.

    Ron
     
  4. keeweepoo thread starter macrumors newbie

    Joined:
    Dec 26, 2007
    #4
    Ah right, great idea.

    So I've implemented your code suggestions and it works perfectly. Any way to modify this code so that if the user types in the wrong amount it won't go/allow option to the next field?

    Code:
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {	
    	
    	if (textField == txtUserName)
    	{
    		NSString *userNameOne = txtUserName.text;
    		double numOne = [userNameOne intValue];	
    
    			if(numOne < 40 || numOne > 100)
    			{
    			
    				//play sound and vibrate for alert
    				NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"];
    				NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile];
    				SystemSoundID  bonkSoundID;
    				AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID);
    				AudioServicesPlaySystemSound(bonkSoundID);
    				AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);	//vibrate
    		
    				//show alert
    				UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"Age Error"
    							  message:@"Your age must be at least 40 years old and less than 100 years old"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    				[alert show];
    				[alert release];
    			}
    		}
    	
    	else if (textField == txtUserName2)
    	{
    		NSString *userNameThree = txtUserName2.text;
    		float numTwo = [userNameThree intValue];	
    			
    		if (numTwo < 20 || numTwo > 32)
    		{
    			UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"IOP Error"
    							  message:@"Your IOP must be between 20 and 32"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    			[alert show];
    			[alert release];
    		}
    	}
    	
    	else if (textField == txtUserName3)
    	{
    		NSString *userNameThree = txtUserName3.text;
    		float numThree = [userNameThree intValue];
    		
    		if (numThree < 475 || numThree > 650)
    		{
    		
    			UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"CCT Error"
    							  message:@"Your CCT must be between 475 and 650"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    			[alert show];
    			[alert release];
    		}
    	}
    	
    	else if (textField == txtUserName4)
    	{
    		NSString *userNameFour = txtUserName4.text;	
    		float numFour = [userNameFour intValue];
    		
    		if (numFour < .50 || numFour > 3.00)
    		{
    		
    			UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"PSD Error"
    							  message:@"Your PSD must be between .50 and 3.00"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    			[alert show];
    			[alert release];
    		}
    	}
    	
    	else if (textField == txtUserName5)
    	{
    		NSString *userNameFive = txtUserName5.text;
    		float numFive = [userNameFive intValue];
    
    		if (numFive < 0.80)
    		{
    			
    			UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"C/D Error"
    							  message:@"Your C/D must be between 0 and .80"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    			[alert show];
    			[alert release];
    		}
    	}
    }
     
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    Yes. Basically you'll want the current field to remain as the first responder. Look into becomeFirstResponder.
     
  6. keeweepoo thread starter macrumors newbie

    Joined:
    Dec 26, 2007
    #6
    So would it be something like this,

    Code:
    	if (textField == txtUserName)
    	{
    		NSString *userNameOne = txtUserName.text;
    		double numOne = [userNameOne intValue];	
    
    			if(numOne < 40 || numOne > 100)
    			{
    			
    				//play sound and vibrate for alert
    				NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"];
    				NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile];
    				SystemSoundID  bonkSoundID;
    				AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID);
    				AudioServicesPlaySystemSound(bonkSoundID);
    				AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);	//vibrate
    		
    				//show alert
    				UIAlertView *alert = [[UIAlertView alloc]
    							  initWithTitle:@"Age Error"
    							  message:@"Your age must be at least 40 years old and less than 100 years old"
    							  delegate:nil
    							  cancelButtonTitle:@"OK"
    							  otherButtonTitles:nil];
    				[alert show];
    				[alert release];
    
    //allow text field to be first responder
    [txtUserName becomeFirstResponder];
    			}
    		}
    
     
  7. keeweepoo thread starter macrumors newbie

    Joined:
    Dec 26, 2007
    #7
    I just got back home and tired the code but it didn't work. I was thinking that would make the textField be FirstReponder but no! Any thoughts?
     

Share This Page