Ewl » Canonical The canonical version of EWL Read More
Clone URL:  
Pushed to 2 repositories · View In Graph Contained in tip and canonical

Reimplemented radio-group logic that supports read-only radio buttons, to ensure
that a concurrency error occurs when the durable value changes from one

disabled radio button to another, if there are any active radio buttons in the
group.

Changeset baade3275984

Parent 2cd438d71111

by Profile picture of William GrossWilliam Gross

Changes to 2 files · Browse files at baade3275984 Showing diff from parent 2cd438d71111 Diff from another changeset...

 
40
41
42
43
44
 
 
45
46
47
 
51
52
53
54
55
56
57
58
59
60
61
 
 
 
 
 
 
 
62
63
64
 
89
90
91
92
93
 
94
95
96
97
98
 
 
 
 
99
100
101
 
110
111
112
113
 
114
115
116
117
 
118
119
120
 
124
125
126
127
 
128
129
130
 
144
145
146
147
 
148
149
150
 
40
41
42
 
 
43
44
45
46
47
 
51
52
53
 
 
 
 
 
 
 
 
54
55
56
57
58
59
60
61
62
63
 
88
89
90
 
 
91
92
93
94
95
 
96
97
98
99
100
101
102
 
111
112
113
 
114
115
116
117
 
118
119
120
121
 
125
126
127
 
128
129
130
131
 
145
146
147
 
148
149
150
151
@@ -40,8 +40,8 @@
  private readonly FormValue<ElementId> formValue;   private readonly bool? noSelectionIsValid;   - private readonly List<( ItemIdType itemId, ElementId buttonId, PageModificationValue<bool> pmv )> itemIdAndButtonIdAndPmvTriples = - new List<( ItemIdType, ElementId, PageModificationValue<bool> )>(); + private readonly List<( ItemIdType itemId, ElementId buttonId, bool isReadOnly, PageModificationValue<bool> pmv )> + itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples = new List<( ItemIdType, ElementId, bool, PageModificationValue<bool> )>();     private readonly FreeFormRadioListSetup<ItemIdType> listSetup;   private readonly EwfValidation validation; @@ -51,14 +51,13 @@
  setup = setup ?? FreeFormRadioListSetup.Create<ItemIdType>();     formValue = RadioButtonGroup.GetFormValue( - noSelectionIsValid.HasValue, - () => from i in itemIdAndButtonIdAndPmvTriples select i.buttonId, - () => from i in itemIdAndButtonIdAndPmvTriples where EwlStatics.AreEqual( i.itemId, selectedItemId ) select i.buttonId, - v => getStringId( v != null ? itemIdAndButtonIdAndPmvTriples.Single( i => i.buttonId == v ).itemId : getNoSelectionItemId() ), - rawValue => from itemIdAndButtonIdAndPmv in itemIdAndButtonIdAndPmvTriples - let buttonId = itemIdAndButtonIdAndPmv.buttonId - where buttonId.Id.Any() && getStringId( itemIdAndButtonIdAndPmv.itemId ) == rawValue - select buttonId ); + () => from i in itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples select ( i.buttonId, i.isReadOnly, EwlStatics.AreEqual( i.itemId, selectedItemId ) ), + v => getStringId( v != null ? itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples.Single( i => i.buttonId == v ).itemId : getNoSelectionItemId() ), + rawValue => from quadruple in itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples + let buttonId = quadruple.buttonId + where buttonId.Id.Any() && !quadruple.isReadOnly && getStringId( quadruple.itemId ) == rawValue + select buttonId, + noSelectionIsValid.HasValue );     this.noSelectionIsValid = noSelectionIsValid;   listSetup = setup; @@ -89,13 +88,15 @@
  () => RadioButtonGroup.ValidateControls(   noSelectionIsValid.HasValue,   EwlStatics.AreEqual( getNoSelectionItemId(), selectedItemId ), - from i in itemIdAndButtonIdAndPmvTriples where EwlStatics.AreEqual( i.itemId, selectedItemId ) select i.buttonId, - from i in itemIdAndButtonIdAndPmvTriples select i.buttonId, + from i in itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples select ( i.buttonId, i.isReadOnly, EwlStatics.AreEqual( i.itemId, selectedItemId ) ),   setup.DisableSingleButtonDetection ) );   }     private ItemIdType getItemIdFromButtonId( ElementId buttonId ) => - itemIdAndButtonIdAndPmvTriples.Where( i => i.buttonId == buttonId ).Select( i => i.itemId ).FallbackIfEmpty( getNoSelectionItemId() ).Single(); + itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples.Where( i => i.buttonId == buttonId ) + .Select( i => i.itemId ) + .FallbackIfEmpty( getNoSelectionItemId() ) + .Single();     /// <summary>   /// Creates a radio button that is part of the list. @@ -110,11 +111,11 @@
    var id = new ElementId();   formValue.AddPageModificationValue( setup.PageModificationValue, v => v == id ); - itemIdAndButtonIdAndPmvTriples.Add( ( listItemId, id, setup.PageModificationValue ) ); + itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples.Add( ( listItemId, id, setup.IsReadOnly, setup.PageModificationValue ) );     return new Checkbox(   formValue, - setup.IsReadOnly ? new ElementId() : id, + id,   setup,   label,   listSetup.SelectionChangedAction, @@ -124,7 +125,7 @@
  .Concat(   listSetup.ItemMatchPageModificationSetups.Select(   i => i.PageModificationValue.GetJsModificationStatements( i.ItemIds.Contains( listItemId ) ? "true" : "false" ) ) ) - .Concat( itemIdAndButtonIdAndPmvTriples.Select( i => i.pmv.GetJsModificationStatements( i.buttonId == id ? "true" : "false" ) ) ) + .Concat( itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples.Select( i => i.pmv.GetJsModificationStatements( i.buttonId == id ? "true" : "false" ) ) )   .ToArray() ),   null,   listItemId: getStringId( listItemId ) ); @@ -144,7 +145,7 @@
  private void validateListItem( ItemIdType listItemId ) {   if( noSelectionIsValid.HasValue && EwlStatics.AreEqual( listItemId, getNoSelectionItemId() ) )   throw new ApplicationException( "You cannot create a radio button with the ID that represents no selection." ); - if( itemIdAndButtonIdAndPmvTriples.Any( i => getStringId( i.itemId ) == getStringId( listItemId ) ) ) + if( itemIdAndButtonIdAndIsReadOnlyAndPmvQuadruples.Any( i => getStringId( i.itemId ) == getStringId( listItemId ) ) )   throw new ApplicationException( "Item IDs, when converted to strings, must be unique." );   }  
 
11
12
13
14
15
 
 
16
17
18
19
 
 
20
21
22
 
27
28
29
30
31
32
 
 
 
 
 
 
 
 
 
33
34
35
36
37
 
38
39
 
40
41
42
43
 
 
44
45
46
 
48
49
50
51
52
 
 
53
54
55
 
63
64
65
66
67
68
 
69
70
71
72
73
 
 
 
 
 
74
75
76
77
78
79
80
81
82
 
 
83
84
85
 
97
98
99
100
 
101
102
103
104
 
105
106
107
108
109
110
 
111
112
113
 
11
12
13
 
 
14
15
16
17
 
 
18
19
20
21
22
 
27
28
29
 
 
 
30
31
32
33
34
35
36
37
38
39
40
41
42
 
43
44
 
45
46
47
 
 
48
49
50
51
52
 
54
55
56
 
 
57
58
59
60
61
 
69
70
71
 
 
 
72
73
 
 
 
 
74
75
76
77
78
79
80
81
82
83
84
 
 
 
85
86
87
88
89
 
101
102
103
 
104
105
106
107
 
108
109
110
111
112
113
 
114
115
116
117
@@ -11,12 +11,12 @@
  /// </summary>   public class RadioButtonGroup {   internal static FormValue<ElementId> GetFormValue( - bool allowsNoSelection, Func<IEnumerable<ElementId>> buttonIdGetter, Func<IEnumerable<ElementId>> selectedButtonIdGetter, - Func<ElementId, string> stringValueSelector, Func<string, IEnumerable<ElementId>> selectedButtonIdInPostBackGetter ) { + Func<IEnumerable<( ElementId id, bool isReadOnly, bool isSelected )>> buttonGetter, Func<ElementId, string> stringValueSelector, + Func<string, IEnumerable<ElementId>> selectedButtonIdInPostBackGetter, bool allowsNoSelection ) {   FormValue<ElementId> formValue = null;   return formValue = new FormValue<ElementId>( - () => selectedButtonIdGetter().FirstOrDefault(), - () => buttonIdGetter().Select( i => i.Id ).FirstOrDefault( i => i.Any() ) ?? "", + () => buttonGetter().Where( i => i.isSelected ).Select( i => i.id ).FirstOrDefault(), + () => buttonGetter().Where( i => i.id.Id.Any() && !i.isReadOnly ).Select( i => i.id ).FirstOrDefault()?.Id ?? "",   stringValueSelector,   rawValue => {   if( rawValue != null ) { @@ -27,20 +27,26 @@
  }     var durableValue = formValue.GetDurableValue(); - return durableValue != null && !durableValue.Id.Any() ? PostBackValueValidationResult<ElementId>.CreateValid( durableValue ) : - allowsNoSelection ? PostBackValueValidationResult<ElementId>.CreateValid( null ) : - PostBackValueValidationResult<ElementId>.CreateInvalid(); + if( durableValue != null ) { + var button = buttonGetter().Single( i => i.id == durableValue ); + if( !button.id.Id.Any() || button.isReadOnly ) + return PostBackValueValidationResult<ElementId>.CreateValid( durableValue ); + } + + return allowsNoSelection + ? PostBackValueValidationResult<ElementId>.CreateValid( null ) + : PostBackValueValidationResult<ElementId>.CreateInvalid();   } );   }     internal static void ValidateControls( - bool allowsNoSelection, bool inNoSelectionState, IEnumerable<ElementId> selectedButtonIds, IEnumerable<ElementId> buttonIds, + bool allowsNoSelection, bool inNoSelectionState, IEnumerable<( ElementId id, bool isReadOnly, bool isSelected )> buttons,   bool disableSingleButtonDetection ) { - if( ( !allowsNoSelection || !inNoSelectionState ) && selectedButtonIds.Count() != 1 ) + if( ( !allowsNoSelection || !inNoSelectionState ) && buttons.Count( i => i.isSelected ) != 1 )   throw new ApplicationException( "If a radio button group is not in the no-selection state, then exactly one radio button must be selected." );   - var activeButtonsIds = buttonIds.Where( i => i.Id.Any() ).Materialize(); - if( activeButtonsIds.Any() && !disableSingleButtonDetection && activeButtonsIds.Count < 2 ) { + var activeButtons = buttons.Where( i => i.id.Id.Any() && !i.isReadOnly ).Materialize(); + if( activeButtons.Any() && !disableSingleButtonDetection && activeButtons.Count < 2 ) {   const string link = "http://developers.whatwg.org/states-of-the-type-attribute.html#radio-button-state-%28type=radio%29";   throw new ApplicationException( "A radio button group must contain more than one element; see " + link + "." );   } @@ -48,8 +54,8 @@
    private readonly FormValue<ElementId> formValue;   - private readonly List<( ElementId id, bool value, PageModificationValue<bool> pmv )> buttonIdAndValueAndPmvTriples = - new List<( ElementId id, bool value, PageModificationValue<bool> pmv )>(); + private readonly List<( ElementId id, bool isReadOnly, bool value, PageModificationValue<bool> pmv )> buttonIdAndIsReadOnlyAndValueAndPmvQuadruples = + new List<( ElementId, bool, bool, PageModificationValue<bool> )>();     private readonly FormAction selectionChangedAction;   @@ -63,23 +69,21 @@
  /// <param name="selectionChangedAction">The action that will occur when the selection is changed. Pass null for no action.</param>   public RadioButtonGroup( bool allowNoSelection, bool disableSingleButtonDetection = false, FormAction selectionChangedAction = null ) {   formValue = GetFormValue( - allowNoSelection, - () => from i in buttonIdAndValueAndPmvTriples select i.id, - () => from i in buttonIdAndValueAndPmvTriples where i.value select i.id, + () => from i in buttonIdAndIsReadOnlyAndValueAndPmvQuadruples select ( i.id, i.isReadOnly, i.value ),   v => v?.Id ?? "", - rawValue => from buttonIdAndValueAndPmv in buttonIdAndValueAndPmvTriples - let id = buttonIdAndValueAndPmv.id - where id.Id.Any() && id.Id == rawValue - select id ); + rawValue => from quadruple in buttonIdAndIsReadOnlyAndValueAndPmvQuadruples + let id = quadruple.id + where id.Id.Any() && !quadruple.isReadOnly && id.Id == rawValue + select id, + allowNoSelection );     this.selectionChangedAction = selectionChangedAction;     EwfPage.Instance.AddControlTreeValidation(   () => ValidateControls(   allowNoSelection, - buttonIdAndValueAndPmvTriples.All( i => !i.value ), - from i in buttonIdAndValueAndPmvTriples where i.value select i.id, - from i in buttonIdAndValueAndPmvTriples select i.id, + buttonIdAndIsReadOnlyAndValueAndPmvQuadruples.All( i => !i.value ), + from i in buttonIdAndIsReadOnlyAndValueAndPmvQuadruples select ( i.id, i.isReadOnly, i.value ),   disableSingleButtonDetection ) );   }   @@ -97,17 +101,17 @@
    var id = new ElementId();   formValue.AddPageModificationValue( setup.PageModificationValue, v => v == id ); - buttonIdAndValueAndPmvTriples.Add( ( id, value, setup.PageModificationValue ) ); + buttonIdAndIsReadOnlyAndValueAndPmvQuadruples.Add( ( id, setup.IsReadOnly, value, setup.PageModificationValue ) );     return new Checkbox(   formValue, - setup.IsReadOnly ? new ElementId() : id, + id,   setup,   label,   selectionChangedAction,   () => StringTools.ConcatenateWithDelimiter(   " ", - buttonIdAndValueAndPmvTriples.Select( i => i.pmv.GetJsModificationStatements( i.id == id ? "true" : "false" ) ).ToArray() ), + buttonIdAndIsReadOnlyAndValueAndPmvQuadruples.Select( i => i.pmv.GetJsModificationStatements( i.id == id ? "true" : "false" ) ).ToArray() ),   validationMethod != null   ? formValue.CreateValidation(   ( postBackValue, validator ) => validationMethod(