Datagrid item editors and dynamic behavior (part 3/3)

we’re ready to wrap up our functionality now. in part 1, we defined our problem (validated error reporting in a datagrid cell, plus dynamic validation characteristics) and made a first attempt at a solution. in part 2, we improved our error handling in the cells. now, in part 3, we’ll expand our validation logic beyond valid numbers to range checking based on other XML data in the row. this will fulfill our task of creating item editors with dynamic behavior. first, we’ll change our WeightEditor to define the ranges and accept a 2nd parameter in its validate() method. this parameter specifies the weight class against which we want to validate. its value will come from the row, and our custom ITEM_EDIT_END handler will be able to access it. here’s our new method signature: public function validate(value:String, weightClass:String) : String in our handler, the old code looked like this: var editor:WeightEditor2 = WeightEditor2 (weigh_in.itemEditorInstance); var userEnteredValue:String = editor.text; var errorMsg:String = editor.validate (userEnteredValue); and the new code is this: var weightClass:String = event.itemRenderer.data.weightClass; var editor:WeightEditor3 = WeightEditor3(weigh_in.itemEditorInstance); var userEnteredValue:String = editor.text; var errorMsg:String = editor.validate(userEnteredValue, weightClass); note that our handler doesn’t do anything with the weightClass value except hand it to the validation method. our itemEditor and handler are fairly coupled to each other, but at least we’ve kept the validation logic in the editor and not spread it across both places. the handler logic is the same: if we fail our (now improved) validation, we’ll prevent the datagrid from moving out of the cell and allow the user to enter another value. here’s the code for the new item editor, WeightEditor3.mxml: <?xml version="1.0" encoding="utf-8"?> <mx:TextInput restrict="1234567890,." xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.formatters.NumberFormatter; import mx.events.ValidationResultEvent; import mx.validators.NumberValidator; protected static const A_LOW:Number = 0; protected static const A_HIGH:Number = 99; protected static const B_LOW:Number = 100; protected static const B_HIGH:Number = 135; protected static const C_LOW:Number = 136; protected static const C_HIGH:Number = 169; protected static const D_LOW:Number = 170; protected static const D_HIGH:Number = 210; /** * This method is invoked when the user enters a value in the weight column * of the weigh_in datagrid. Because we're allowing the user to handle validation, * we'll always return what the user typed in, right or wrong. By sending back a * value which will eventually fail validation, that allows us to keep the value * in the field when the errortip is drawn around it. */ override public function get data() : Object { var value:String = text; // no need to validate here, since we don't act upon it. but if we did // need to validate to make some kind of decision, then we'll end up // validating twice. return value; } /** * This is our validation method. We pass validation if the user has * entered a non-negative decimal. This is a public function so that we can * re-use this validation outside of the editor. * * @param value         The user-entered value * @param weightClass   From the XML, the weight class of this particular wrestler * * @return null if we pass validation, otherwise we return the error string */ public function validate(value:String, weightClass:String) : String { var validator:NumberValidator = new NumberValidator(); validator.allowNegative = false; validator.required = false; var result:ValidationResultEvent = validator.validate(value); if (result.type != ValidationResultEvent.VALID) return result.message; var errorMsg:String = validateWeightClass(value, weightClass); return errorMsg; } /** * This is a validation helper method. It checks to ensure the entered weight * is within range. The weight can be equal on the low end but must be lower than * the high end. * * @param value         The user-entered value * @param weightClass   From the XML, the weight class of this particular wrestler * * @return null if we pass validation, otherwise we return the error string */ protected function validateWeightClass(value:String, weightClass:String) : String { var lowWeight:Number = 0; var highWeight:Number = 1000; switch (weightClass) { case 'A' : lowWeight = A_LOW; highWeight = A_HIGH; break; case 'B' : lowWeight = B_LOW; highWeight = B_HIGH; break; case 'C' : lowWeight = C_LOW; highWeight = C_HIGH; break; case 'D' : lowWeight = D_LOW; highWeight = D_HIGH; break; default: break; } var weight:Number = Number(value); if ((weight >= lowWeight) && (weight < highWeight)) return null; var errorMsg:String = "This wrestler's weight is out of his weight class. His weight must be between " + lowWeight + ' and ' + highWeight + ' pounds.'; return errorMsg; } ]]> </mx:Script> </mx:TextInput> click on the image to run the final app. test the new validation by entering valid numbers which are outside the weight range.

There are no comments.

Leave a Reply