/// <summary>
 /// Creates a condition that depends on this page-modification value.
 /// </summary>
 public static PageModificationValueCondition ToCondition(this PageModificationValue <bool> pageModificationValue, bool isTrueWhenValueSet = true)
 {
     return(new PageModificationValueCondition(
                statementGetter => pageModificationValue.AddJsModificationStatement(
                    valueExpression => statementGetter(isTrueWhenValueSet ? valueExpression : "!( {0} )".FormatWith(valueExpression))),
                () => pageModificationValue.Value ^ !isTrueWhenValueSet));
 }
 /// <summary>
 /// Creates a setup object for a text control with auto-complete behavior.
 /// </summary>
 /// <param name="autoCompleteResource">The resource containing the auto-complete items. Do not pass null.</param>
 /// <param name="displaySetup"></param>
 /// <param name="widthOverride">The width of the control. This overrides any value that may be specified via CSS. If no width is specified via CSS and you
 /// pass null for this parameter, the width will be based on the maximum number of characters a user can input.</param>
 /// <param name="numberOfRows">The number of lines in the text control. Must be one or more.</param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="disableTrimming">Pass true to disable white-space trimming.</param>
 /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="checksSpellingAndGrammar">Pass true to enable spelling and grammar checking, false to disable it, and null for default behavior.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action. Currently has no
 /// effect for multiline controls.</param>
 /// <param name="triggersActionWhenItemSelected">Pass true to also trigger the action when the user selects an auto-complete item.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static TextControlSetup CreateAutoComplete(
     ResourceInfo autoCompleteResource, DisplaySetup displaySetup = null, ContentBasedLength widthOverride = null, int numberOfRows = 1,
     ElementClassSet classes            = null, bool disableTrimming = false, string placeholder = "", string autoFillTokens = "", bool?checksSpellingAndGrammar = null,
     SpecifiedValue <FormAction> action = null, bool triggersActionWhenItemSelected = false, FormAction valueChangedAction = null,
     PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new TextControlSetup(
                displaySetup,
                numberOfRows == 1 ? "text" : "",
                widthOverride,
                numberOfRows,
                false,
                classes,
                disableTrimming,
                false,
                placeholder,
                autoFillTokens,
                autoCompleteResource,
                checksSpellingAndGrammar,
                action,
                triggersActionWhenItemSelected,
                valueChangedAction,
                pageModificationValue,
                null,
                validationPredicate,
                validationErrorNotifier));
 }
예제 #3
0
        /// <summary>
        /// Creates a block-level radio button that is part of the group.
        /// </summary>
        /// <param name="isSelected"></param>
        /// <param name="validationMethod">The validation method. Do not pass null.</param>
        /// <param name="label"></param>
        /// <param name="action"></param>
        /// <param name="autoPostBack"></param>
        /// <param name="pageModificationValue"></param>
        /// <param name="nestedControlListGetter"></param>
        /// <returns></returns>
        public BlockCheckBox CreateBlockRadioButton(
            bool isSelected, Action <PostBackValue <bool>, Validator> validationMethod, string label = "", FormAction action = null, bool autoPostBack = false,
            PageModificationValue <bool> pageModificationValue = null, Func <IEnumerable <Control> > nestedControlListGetter = null)
        {
            BlockCheckBox checkBox   = null;
            var           validation =
                formValue.CreateValidation(
                    (postBackValue, validator) => validationMethod(new PostBackValue <bool>(postBackValue.Value == checkBox, postBackValue.ChangedOnPostBack), validator));

            checkBox = new BlockCheckBox(
                formValue,
                label,
                new BlockCheckBoxSetup(action: action, triggersActionWhenCheckedOrUnchecked: autoPostBack, nestedControlListGetter: nestedControlListGetter),
                () =>
                checkBoxesAndSelectionStatesAndPageModificationValues.Where(i => i.Item3 != null)
                .Select(i => i.Item3.GetJsModificationStatements(i.Item1 == checkBox ? "true" : "false")),
                validation);
            checkBoxesAndSelectionStatesAndPageModificationValues.Add(
                Tuple.Create <CommonCheckBox, bool, PageModificationValue <bool> >(checkBox, isSelected, pageModificationValue));

            if (pageModificationValue != null)
            {
                formValue.AddPageModificationValue(pageModificationValue, value => value == checkBox);
            }

            return(checkBox);
        }
 /// <summary>
 /// Creates a setup object for an obscured (i.e. password) text control.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="widthOverride">The width of the control. This overrides any value that may be specified via CSS. If no width is specified via CSS and you
 /// pass null for this parameter, the width will be based on the maximum number of characters a user can input.</param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 /// <returns></returns>
 public static TextControlSetup CreateObscured(
     DisplaySetup displaySetup = null, ContentBasedLength widthOverride = null, ElementClassSet classes       = null, string placeholder = "",
     string autoFillTokens     = "", SpecifiedValue <FormAction> action = null, FormAction valueChangedAction = null,
     PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new TextControlSetup(
                displaySetup,
                "password",
                widthOverride,
                null,
                false,
                classes,
                true,
                false,
                placeholder,
                autoFillTokens,
                null,
                null,
                action,
                null,
                valueChangedAction,
                pageModificationValue,
                null,
                validationPredicate,
                validationErrorNotifier));
 }
예제 #5
0
 /// <summary>
 /// Creates a setup object for a numeric-text control with auto-complete behavior.
 /// </summary>
 /// <param name="autoCompleteResource">The resource containing the auto-complete items. Do not pass null.</param>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="triggersActionWhenItemSelected">Pass true to also trigger the action when the user selects an auto-complete item.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="numericPageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static NumericTextControlSetup CreateAutoComplete(
     ResourceInfo autoCompleteResource, DisplaySetup displaySetup = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "",
     SpecifiedValue <FormAction> action = null, bool triggersActionWhenItemSelected = false, FormAction valueChangedAction   = null,
     PageModificationValue <string> pageModificationValue = null, PageModificationValue <long?> numericPageModificationValue = null,
     Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new NumericTextControlSetup(
                new TextControlSetup(
                    displaySetup,
                    "text",
                    null,
                    null,
                    false,
                    classes,
                    false,
                    true,
                    placeholder,
                    autoFillTokens,
                    autoCompleteResource,
                    null,
                    action,
                    triggersActionWhenItemSelected,
                    valueChangedAction,
                    pageModificationValue,
                    numericPageModificationValue,
                    validationPredicate,
                    validationErrorNotifier),
                validationErrorNotifier));
 }
예제 #6
0
 private ElementClassSet getSectionClasses(
     bool?expanded, PageModificationValue <string> expandedPmv, ElementClass closedClass, ElementClass expandedClass)
 {
     return(!expanded.HasValue ? expandedClass :
            expandedPmv == null ? expanded.Value ? expandedClass : closedClass :
            expandedPmv.ToCondition(bool.FalseString.ToCollection())
            .ToElementClassSet(closedClass)
            .Add(expandedPmv.ToCondition(bool.TrueString.ToCollection()).ToElementClassSet(expandedClass)));
 }
 /// <summary>
 /// Creates a free-form radio button list.
 /// </summary>
 /// <param name="allowNoSelection">Pass true to cause a selected item ID with the default value (or the empty string when the item ID type is string) to
 /// represent the state in which none of the radio buttons are selected. Note that this is not recommended by the Nielsen Norman Group; see
 /// http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/ for more information.</param>
 /// <param name="selectedItemId"></param>
 /// <param name="disableSingleButtonDetection">Pass true to allow just a single radio button to be displayed for this list. Use with caution, as this
 /// violates the HTML specification.</param>
 /// <param name="itemIdPageModificationValue"></param>
 /// <param name="itemMatchPageModificationSetups"></param>
 public static FreeFormRadioList <ItemIdType> Create <ItemIdType>(
     bool allowNoSelection, ItemIdType selectedItemId, bool disableSingleButtonDetection = false,
     PageModificationValue <ItemIdType> itemIdPageModificationValue = null,
     IEnumerable <ListItemMatchPageModificationSetup <ItemIdType> > itemMatchPageModificationSetups = null)
 {
     return(new FreeFormRadioList <ItemIdType>(
                allowNoSelection,
                disableSingleButtonDetection,
                selectedItemId,
                itemIdPageModificationValue,
                itemMatchPageModificationSetups));
 }
 /// <summary>
 /// Creates a condition that depends on this page-modification value.
 /// </summary>
 public static PageModificationValueCondition ToCondition <T>(
     this PageModificationValue <T> pageModificationValue, IEnumerable <T> values, bool isTrueOnMatch = true)
 {
     values = values.ToImmutableArray();
     return(new PageModificationValueCondition(
                statementGetter => pageModificationValue.AddJsModificationStatement(
                    valueExpression => statementGetter(
                        "[ {0} ].indexOf( {1} ) {2} -1".FormatWith(
                            StringTools.ConcatenateWithDelimiter(", ", values.Select(i => "'" + i.ObjectToString(true) + "'").ToArray()),
                            valueExpression,
                            isTrueOnMatch ? "!=" : "=="))),
                () => values.Contains(pageModificationValue.Value) ^ !isTrueOnMatch));
 }
 internal DurationControlSetup(
     DisplaySetup displaySetup, bool isReadOnly, ElementClassSet classes, SpecifiedValue <FormAction> action, FormAction valueChangedAction,
     PageModificationValue <string> pageModificationValue, Func <bool, bool> validationPredicate, Action validationErrorNotifier)
 {
     DisplaySetup            = displaySetup;
     IsReadOnly              = isReadOnly;
     Classes                 = classes;
     Action                  = action != null ? action.Value : FormState.Current.FormControlDefaultAction;
     ValueChangedAction      = valueChangedAction;
     PageModificationValue   = pageModificationValue;
     ValidationPredicate     = validationPredicate;
     ValidationErrorNotifier = validationErrorNotifier;
 }
예제 #10
0
 /// <summary>
 /// Creates a setup object for a standard radio button.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the container.</param>
 /// <param name="highlightedWhenSelected"></param>
 /// <param name="action">The action that will occur when the user hits Enter on the radio button. Pass null to use the current default action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="nestedContentGetter">A function that gets the content that will appear beneath the radio button.</param>
 /// <param name="nestedContentAlwaysDisplayed">Pass true to force the nested content to always be displayed instead of only when the button is selected.
 /// </param>
 public static FlowRadioButtonSetup Create(
     DisplaySetup displaySetup = null, ElementClassSet classes = null, bool highlightedWhenSelected = false, SpecifiedValue <FormAction> action = null,
     PageModificationValue <bool> pageModificationValue = null, Func <IReadOnlyCollection <FlowComponent> > nestedContentGetter = null,
     bool nestedContentAlwaysDisplayed = false)
 {
     return(new FlowRadioButtonSetup(
                displaySetup,
                classes,
                RadioButtonSetup.Create(action: action, pageModificationValue: pageModificationValue),
                highlightedWhenSelected,
                nestedContentGetter,
                nestedContentAlwaysDisplayed));
 }
 /// <summary>
 /// Creates a setup object for a standard duration control.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control container.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static DurationControlSetup Create(
     DisplaySetup displaySetup = null, ElementClassSet classes = null, SpecifiedValue <FormAction> action = null, FormAction valueChangedAction = null,
     PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new DurationControlSetup(
                displaySetup,
                false,
                classes,
                action,
                valueChangedAction,
                pageModificationValue,
                validationPredicate,
                validationErrorNotifier));
 }
예제 #12
0
 /// <summary>
 /// Creates a display setup object for display that depends on this page-modification value.
 /// </summary>
 public static DisplaySetup ToDisplaySetup(this PageModificationValue <bool> pageModificationValue, bool componentsDisplayedWhenValueSet = true)
 {
     return
         (new DisplaySetup(
              Tuple.Create <Action <string>, Action <string> >(
                  statements =>
                  pageModificationValue.AddJsModificationStatement(
                      valueExpression =>
                      "if( {0} )".FormatWith(componentsDisplayedWhenValueSet ? valueExpression : "!( {0} )".FormatWith(valueExpression)) + " { " + statements + " }"),
                  statements =>
                  pageModificationValue.AddJsModificationStatement(
                      valueExpression =>
                      "if( {0} )".FormatWith(componentsDisplayedWhenValueSet ? "!( {0} )".FormatWith(valueExpression) : valueExpression) + " { " + statements + " }")),
              () => pageModificationValue.Value ^ !componentsDisplayedWhenValueSet));
 }
예제 #13
0
 /// <summary>
 /// Creates a generic phrasing container (i.e. span element) that depends on this page-modification value.
 /// </summary>
 public static IReadOnlyCollection <PhrasingComponent> ToGenericPhrasingContainer <ModificationValueType>(
     this PageModificationValue <ModificationValueType> pageModificationValue, Func <ModificationValueType, string> textSelector,
     Func <string, string> jsTextExpressionGetter)
 {
     return(new CustomPhrasingComponent(
                new DisplayableElement(
                    context => {
         pageModificationValue.AddJsModificationStatement(
             valueExpression => "$( '#{0}' ).text( {1} );".FormatWith(context.Id, jsTextExpressionGetter(valueExpression)));
         return new DisplayableElementData(
             null,
             () => new DisplayableElementLocalData("span", focusDependentData: new DisplayableElementFocusDependentData(includeIdAttribute: true)),
             children: new TextNode(() => textSelector(pageModificationValue.Value)).ToCollection());
     }).ToCollection()).ToCollection());
 }
        /// <summary>
        /// Creates a hidden field.
        /// </summary>
        /// <param name="value">Do not pass null.</param>
        /// <param name="id"></param>
        /// <param name="pageModificationValue"></param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        /// <param name="jsInitStatementGetter">A function that takes the field’s ID and returns the JavaScript statements that should be executed when the DOM is
        /// loaded. Do not return null.</param>
        public EwfHiddenField(
            string value, HiddenFieldId id = null, PageModificationValue <string> pageModificationValue = null,
            Action <PostBackValue <string>, Validator> validationMethod = null, Func <string, string> jsInitStatementGetter = null)
        {
            pageModificationValue = pageModificationValue ?? new PageModificationValue <string>();

            var elementId = new ElementId();
            var formValue = new FormValue <string>(
                () => value,
                () => elementId.Id,
                v => v,
                rawValue => rawValue != null ? PostBackValueValidationResult <string> .CreateValid(rawValue) : PostBackValueValidationResult <string> .CreateInvalid());

            component = new ElementComponent(
                context => {
                elementId.AddId(context.Id);
                id?.AddId(context.Id);
                return(new ElementData(
                           () => {
                    var attributes = new List <Tuple <string, string> >();
                    attributes.Add(Tuple.Create("type", "hidden"));
                    attributes.Add(Tuple.Create("name", context.Id));
                    attributes.Add(Tuple.Create("value", pageModificationValue.Value));

                    return new ElementLocalData(
                        "input",
                        focusDependentData: new ElementFocusDependentData(
                            attributes: attributes,
                            includeIdAttribute: id != null || pageModificationValue != null || jsInitStatementGetter != null,
                            jsInitStatements: StringTools.ConcatenateWithDelimiter(
                                " ",
                                pageModificationValue != null
                                                                                        ? "$( '#{0}' ).change( function() {{ {1} }} );".FormatWith(
                                    context.Id,
                                    pageModificationValue.GetJsModificationStatements("$( this ).val()"))
                                                                                        : "",
                                jsInitStatementGetter?.Invoke(context.Id) ?? "")));
                }));
            },
                formValue: formValue);

            formValue.AddPageModificationValue(pageModificationValue, v => v);

            if (validationMethod != null)
            {
                validation = formValue.CreateValidation(validationMethod);
            }
        }
 internal DateAndTimeControlSetup(
     DisplaySetup displaySetup, bool isReadOnly, ElementClassSet classes, string autoFillTokens, int?minuteInterval, SpecifiedValue <FormAction> action,
     FormAction valueChangedAction, PageModificationValue <string> pageModificationValue, Func <bool, bool> validationPredicate,
     Action validationErrorNotifier)
 {
     DisplaySetup            = displaySetup;
     IsReadOnly              = isReadOnly;
     Classes                 = classes;
     AutoFillTokens          = autoFillTokens;
     MinuteInterval          = minuteInterval;
     Action                  = action != null ? action.Value : FormState.Current.FormControlDefaultAction;
     ValueChangedAction      = valueChangedAction;
     PageModificationValue   = pageModificationValue;
     ValidationPredicate     = validationPredicate;
     ValidationErrorNotifier = validationErrorNotifier;
 }
예제 #16
0
        // Web Forms compatibility. Remove when EnduraCode goal 790 is complete.
        public static void AddDisplayLink(
            this PageModificationValue <bool> pageModificationValue, IEnumerable <WebControl> controls, bool controlsDisplayedWhenValueSet = true)
        {
            controls = controls.ToImmutableArray();

            foreach (var control in controls)
            {
                pageModificationValue.AddJsModificationStatement(
                    valueExpression =>
                    "setElementDisplay( '{0}', {1} );".FormatWith(
                        control.ClientID,
                        controlsDisplayedWhenValueSet ? valueExpression : "!( {0} )".FormatWith(valueExpression)));
            }

            EwfPage.Instance.AddDisplayLink(new DisplayLinkAdapter(controls, () => pageModificationValue.Value ^ !controlsDisplayedWhenValueSet));
        }
예제 #17
0
 /// <summary>
 /// Creates an element-class set that depends on this page-modification value.
 /// </summary>
 public static ElementClassSet ToElementClassSet(
     this PageModificationValue <bool> pageModificationValue, ElementClassSet staticClassSet, bool classesPresentWhenValueSet = true)
 {
     if (staticClassSet.JsModificationStatementAdderAndInclusionPredicatePairsByClassName.Values.Any(i => i != null))
     {
         throw new ApplicationException("At least one class already has dynamic behavior.");
     }
     return
         (new ElementClassSet(
              staticClassSet.JsModificationStatementAdderAndInclusionPredicatePairsByClassName.Keys.ToImmutableDictionary(
                  i => i,
                  i =>
                  Tuple.Create <Action <Func <string, string> >, Func <bool> >(
                      statementGetter =>
                      pageModificationValue.AddJsModificationStatement(
                          valueExpression => statementGetter(classesPresentWhenValueSet ? valueExpression : "!( {0} )".FormatWith(valueExpression))),
                      () => pageModificationValue.Value ^ !classesPresentWhenValueSet))));
 }
예제 #18
0
        // Web Forms compatibility. Remove when EnduraCode goal 790 is complete.
        public static void AddDisplayLink <T>(
            this PageModificationValue <T> pageModificationValue, IEnumerable <T> values, IEnumerable <WebControl> controls, bool controlsDisplayedOnMatch = true)
        {
            values   = values.ToImmutableArray();
            controls = controls.ToImmutableArray();

            foreach (var control in controls)
            {
                pageModificationValue.AddJsModificationStatement(
                    valueExpression =>
                    "setElementDisplay( '{0}', [ {1} ].indexOf( {2} ) {3} -1 );".FormatWith(
                        control.ClientID,
                        StringTools.ConcatenateWithDelimiter(", ", values.Select(i => "'" + i.ObjectToString(true) + "'").ToArray()),
                        valueExpression,
                        controlsDisplayedOnMatch ? "!=" : "=="));
            }

            EwfPage.Instance.AddDisplayLink(new DisplayLinkAdapter(controls, () => values.Contains(pageModificationValue.Value) ^ !controlsDisplayedOnMatch));
        }
예제 #19
0
 /// <summary>
 /// Creates a setup object for a number control with auto-complete behavior.
 /// </summary>
 /// <param name="autoCompleteResource">The resource containing the auto-complete items. Do not pass null.</param>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="triggersActionWhenItemSelected">Pass true to also trigger the action when the user selects an auto-complete item.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static NumberControlSetup CreateAutoComplete(
     ResourceInfo autoCompleteResource, DisplaySetup displaySetup = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "",
     SpecifiedValue <FormAction> action = null, bool triggersActionWhenItemSelected = false, FormAction valueChangedAction   = null,
     PageModificationValue <decimal?> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new NumberControlSetup(
                displaySetup,
                false,
                false,
                TextControlSetup.ElementClass.Add(classes ?? ElementClassSet.Empty),
                placeholder,
                autoFillTokens,
                autoCompleteResource,
                action,
                triggersActionWhenItemSelected,
                valueChangedAction,
                pageModificationValue ?? new PageModificationValue <decimal?>(),
                validationPredicate,
                validationErrorNotifier));
 }
예제 #20
0
 /// <summary>
 /// Creates a setup object for a standard imprecise-number control.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static ImpreciseNumberControlSetup Create(
     DisplaySetup displaySetup      = null, ElementClassSet classes = null, string autoFillTokens = "", SpecifiedValue <FormAction> action = null,
     FormAction valueChangedAction  = null, PageModificationValue <decimal> pageModificationValue = null, Func <bool, bool> validationPredicate = null,
     Action validationErrorNotifier = null)
 {
     return(new ImpreciseNumberControlSetup(
                new NumberControlSetup(
                    displaySetup,
                    true,
                    false,
                    classes,
                    "",
                    autoFillTokens,
                    null,
                    action,
                    null,
                    valueChangedAction,
                    pageModificationValue ?? new PageModificationValue <decimal>(),
                    validationPredicate,
                    validationErrorNotifier)));
 }
 /// <summary>
 /// Creates a setup object for a standard radio list.
 /// </summary>
 /// <param name="items">The items in the list. There must be at least one.</param>
 /// <param name="displaySetup"></param>
 /// <param name="useHorizontalLayout">Pass true if you want the radio buttons to be laid out horizontally instead of vertically.</param>
 /// <param name="classes">The classes on the list container.</param>
 /// <param name="unlistedSelectedItemLabelGetter">A function that will be called if the selected item ID does not match any list item and is not the default
 /// value of the type. The function takes the selected item ID and returns the label of the unlisted selected item, which will appear before all other
 /// items in the list. The string " (invalid)" will be appended to the label.</param>
 /// <param name="disableSingleButtonDetection">Pass true to allow just a single radio button to be displayed for this list. Use with caution, as this
 /// violates the HTML specification.</param>
 /// <param name="action">The action that will occur when the user hits Enter on a radio button. Pass null to use the current default action.</param>
 /// <param name="selectionChangedAction">The action that will occur when the selection is changed. Pass null for no action.</param>
 /// <param name="itemIdPageModificationValue"></param>
 /// <param name="itemMatchPageModificationSetups"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static RadioListSetup <ItemIdType> Create <ItemIdType>(
     IEnumerable <SelectListItem <ItemIdType> > items, DisplaySetup displaySetup = null, bool useHorizontalLayout = false, ElementClassSet classes            = null,
     Func <ItemIdType, string> unlistedSelectedItemLabelGetter = null, bool disableSingleButtonDetection          = false, SpecifiedValue <FormAction> action = null,
     FormAction selectionChangedAction = null, PageModificationValue <ItemIdType> itemIdPageModificationValue     = null,
     IReadOnlyCollection <ListItemMatchPageModificationSetup <ItemIdType> > itemMatchPageModificationSetups = null, Func <bool, bool> validationPredicate = null,
     Action validationErrorNotifier = null) =>
 new RadioListSetup <ItemIdType>(
     displaySetup,
     useHorizontalLayout,
     false,
     classes,
     unlistedSelectedItemLabelGetter,
     items,
     FreeFormRadioListSetup.Create(
         disableSingleButtonDetection: disableSingleButtonDetection,
         selectionChangedAction: selectionChangedAction,
         itemIdPageModificationValue: itemIdPageModificationValue,
         itemMatchPageModificationSetups: itemMatchPageModificationSetups,
         validationPredicate: validationPredicate,
         validationErrorNotifier: validationErrorNotifier),
     action);
 /// <summary>
 /// Creates a radio button list.
 /// </summary>
 /// <param name="items">The items in the list. There must be at least one.</param>
 /// <param name="selectedItemId">The ID of the selected item. This must either match a list item or be the default value of the type, unless an unlisted
 /// selected item label getter is passed.</param>
 /// <param name="useHorizontalLayout">Pass true if you want the radio buttons to be laid out horizontally instead of vertically.</param>
 /// <param name="unlistedSelectedItemLabelGetter">A function that will be called if the selected item ID does not match any list item and is not the default
 /// value of the type. The function takes the selected item ID and returns the label of the unlisted selected item, which will appear before all other
 /// items in the list. The string " (invalid)" will be appended to the label.</param>
 /// <param name="defaultValueItemLabel">The label of the default-value item, which will appear first, and only if none of the list items have an ID with the
 /// default value. Do not pass null. If you pass the empty string, no default-value item will appear and therefore none of the radio buttons will be
 /// selected if the selected item ID has the default value and none of the list items do.</param>
 /// <param name="disableSingleButtonDetection">Pass true to allow just a single radio button to be displayed for this list. Use with caution, as this
 /// violates the HTML specification.</param>
 /// <param name="action">The action that will occur when the user hits Enter on a radio button.</param>
 /// <param name="autoPostBack">Pass true if you want an action to occur when the selection changes.</param>
 /// <param name="itemIdPageModificationValue"></param>
 /// <param name="itemMatchPageModificationSetups"></param>
 public static SelectList <ItemIdType> CreateRadioList <ItemIdType>(
     IEnumerable <SelectListItem <ItemIdType> > items, ItemIdType selectedItemId, bool useHorizontalLayout = false,
     Func <ItemIdType, string> unlistedSelectedItemLabelGetter = null, string defaultValueItemLabel = "", bool disableSingleButtonDetection = false,
     FormAction action = null, bool autoPostBack = false, PageModificationValue <ItemIdType> itemIdPageModificationValue = null,
     IEnumerable <ListItemMatchPageModificationSetup <ItemIdType> > itemMatchPageModificationSetups = null)
 {
     return(new SelectList <ItemIdType>(
                useHorizontalLayout,
                null,
                unlistedSelectedItemLabelGetter,
                defaultValueItemLabel,
                null,
                null,
                items,
                disableSingleButtonDetection,
                selectedItemId,
                action,
                autoPostBack,
                itemIdPageModificationValue,
                itemMatchPageModificationSetups));
 }
 /// <summary>
 /// Creates a drop-down list.
 /// </summary>
 /// <param name="items">The items in the list. There must be at least one.</param>
 /// <param name="selectedItemId">The ID of the selected item. This must either match a list item or be the default value of the type, unless an unlisted
 /// selected item label getter is passed.</param>
 /// <param name="width">The width of the list. This overrides any value that may be specified via CSS. If no width is specified via CSS and you pass null
 /// for this parameter, the list will be just wide enough to show the selected item and will resize whenever the selected item is changed.</param>
 /// <param name="unlistedSelectedItemLabelGetter">A function that will be called if the selected item ID does not match any list item and is not the default
 /// value of the type. The function takes the selected item ID and returns the label of the unlisted selected item, which will appear before all other
 /// items in the list. The string " (invalid)" will be appended to the label.</param>
 /// <param name="defaultValueItemLabel">The label of the default-value item, which will appear first, and only if none of the list items have an ID with the
 /// default value. Do not pass null. If you pass the empty string, no default-value item will appear.</param>
 /// <param name="placeholderIsValid">Pass true if you would like the list to include a default-value placeholder that is considered a valid selection.
 /// This will only be included if none of the list items have an ID with the default value and the default-value item label is the empty string. If you pass
 /// false, the list will still include a default-value placeholder if the selected item ID has the default value and none of the list items do, but in this
 /// case the placeholder will not be considered a valid selection.</param>
 /// <param name="placeholderText">The default-value placeholder's text. Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the drop-down list.</param>
 /// <param name="autoPostBack">Pass true if you want an action to occur when the selection changes.</param>
 /// <param name="itemIdPageModificationValue"></param>
 /// <param name="itemMatchPageModificationSetups"></param>
 public static SelectList <ItemIdType> CreateDropDown <ItemIdType>(
     IEnumerable <SelectListItem <ItemIdType> > items, ItemIdType selectedItemId, System.Web.UI.WebControls.Unit?width = null,
     Func <ItemIdType, string> unlistedSelectedItemLabelGetter = null, string defaultValueItemLabel = "", bool placeholderIsValid = false,
     string placeholderText = "Please select", FormAction action = null, bool autoPostBack = false,
     PageModificationValue <ItemIdType> itemIdPageModificationValue = null,
     IEnumerable <ListItemMatchPageModificationSetup <ItemIdType> > itemMatchPageModificationSetups = null)
 {
     return(new SelectList <ItemIdType>(
                null,
                width,
                unlistedSelectedItemLabelGetter,
                defaultValueItemLabel,
                placeholderIsValid,
                placeholderText,
                items,
                null,
                selectedItemId,
                action,
                autoPostBack,
                itemIdPageModificationValue,
                itemMatchPageModificationSetups ?? ImmutableArray <ListItemMatchPageModificationSetup <ItemIdType> > .Empty));
 }
        private FlowComponent getComponent(
            DisplaySetup displaySetup, ElementClassSet classes, PageModificationValue <bool> pageModificationValue, Checkbox checkbox, bool highlightedWhenChecked,
            Func <IReadOnlyCollection <FlowComponent> > nestedContentGetter, bool nestedContentAlwaysDisplayed)
        {
            var nestedContent = nestedContentGetter?.Invoke() ?? Enumerable.Empty <FlowComponent>().Materialize();

            return(new GenericFlowContainer(
                       checkbox.PageComponent.ToCollection()
                       .Concat(
                           nestedContent.Any()
                                                        ? new GenericFlowContainer(
                               nestedContent,
                               displaySetup: nestedContentAlwaysDisplayed?null: pageModificationValue.ToCondition().ToDisplaySetup(),
                               classes: nestedContentClass).ToCollection()
                                                        : Enumerable.Empty <FlowComponent>())
                       .Materialize(),
                       displaySetup: displaySetup,
                       classes: (highlightedWhenChecked
                                                   ? pageModificationValue.ToCondition(isTrueWhenValueSet: false)
                                 .ToElementClassSet(unhighlightedClass)
                                 .Add(pageModificationValue.ToCondition().ToElementClassSet(highlightedClass))
                                                   : unhighlightedClass).Add(classes ?? ElementClassSet.Empty)));
        }
예제 #25
0
 /// <summary>
 /// Creates a display setup object for display that depends on this page-modification value.
 /// </summary>
 public static DisplaySetup ToDisplaySetup <T>(
     this PageModificationValue <T> pageModificationValue, IEnumerable <T> values, bool componentsDisplayedOnMatch = true)
 {
     values = values.ToImmutableArray();
     return
         (new DisplaySetup(
              Tuple.Create <Action <string>, Action <string> >(
                  statements =>
                  pageModificationValue.AddJsModificationStatement(
                      valueExpression =>
                      "if( [ {0} ].indexOf( {1} ) {2} -1 )".FormatWith(
                          StringTools.ConcatenateWithDelimiter(", ", values.Select(i => "'" + i.ObjectToString(true) + "'").ToArray()),
                          valueExpression,
                          componentsDisplayedOnMatch ? "!=" : "==") + " { " + statements + " }"),
                  statements =>
                  pageModificationValue.AddJsModificationStatement(
                      valueExpression =>
                      "if( [ {0} ].indexOf( {1} ) {2} -1 )".FormatWith(
                          StringTools.ConcatenateWithDelimiter(", ", values.Select(i => "'" + i.ObjectToString(true) + "'").ToArray()),
                          valueExpression,
                          componentsDisplayedOnMatch ? "==" : "!=") + " { " + statements + " }")),
              () => values.Contains(pageModificationValue.Value) ^ !componentsDisplayedOnMatch));
 }
 /// <summary>
 /// Creates a setup object for a standard URL control.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static UrlControlSetup Create(
     DisplaySetup displaySetup             = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "",
     SpecifiedValue <FormAction> action    = null, FormAction valueChangedAction  = null, PageModificationValue <string> pageModificationValue = null,
     Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new UrlControlSetup(
                new TextControlSetup(
                    displaySetup,
                    "url",
                    null,
                    null,
                    false,
                    classes,
                    false,
                    false,
                    placeholder,
                    autoFillTokens,
                    null,
                    null,
                    action,
                    null,
                    valueChangedAction,
                    pageModificationValue,
                    null,
                    validationPredicate,
                    validationErrorNotifier)));
 }
 /// <summary>
 /// Creates a setup object for a standard date-and-time control.
 /// </summary>
 /// <param name="displaySetup"></param>
 /// <param name="classes">The classes on the control.</param>
 /// <param name="autoFillTokens">A list of auto-fill detail tokens (see
 /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill
 /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param>
 /// <param name="minuteInterval">Affects the slider but does not prevent other values from passing validation.</param>
 /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param>
 /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param>
 /// <param name="pageModificationValue"></param>
 /// <param name="validationPredicate"></param>
 /// <param name="validationErrorNotifier"></param>
 public static DateAndTimeControlSetup Create(
     DisplaySetup displaySetup             = null, ElementClassSet classes = null, string autoFillTokens = "", int minuteInterval = 15,
     SpecifiedValue <FormAction> action    = null, FormAction valueChangedAction  = null, PageModificationValue <string> pageModificationValue = null,
     Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null)
 {
     return(new DateAndTimeControlSetup(
                displaySetup,
                false,
                classes,
                autoFillTokens,
                minuteInterval,
                action,
                valueChangedAction,
                pageModificationValue,
                validationPredicate,
                validationErrorNotifier));
 }
예제 #28
0
        private PhrasingComponent getComponent(
            FormValue formValue, ElementId id, string radioButtonListItemId, DisplaySetup displaySetup, bool isReadOnly, ElementClassSet classes,
            PageModificationValue <bool> pageModificationValue, IReadOnlyCollection <PhrasingComponent> label, FormAction action, FormAction valueChangedAction,
            Func <string> jsClickStatementGetter)
        {
            return(new CustomPhrasingComponent(
                       new DisplayableElement(
                           labelContext => new DisplayableElementData(
                               displaySetup,
                               () => new DisplayableElementLocalData("label"),
                               classes: elementClass.Add(classes ?? ElementClassSet.Empty),
                               children: new DisplayableElement(
                                   context => {
                if (!isReadOnly)
                {
                    action?.AddToPageIfNecessary();
                    valueChangedAction?.AddToPageIfNecessary();
                }

                return new DisplayableElementData(
                    null,
                    () => {
                    var attributes = new List <ElementAttribute>();
                    var radioButtonFormValue = formValue as FormValue <ElementId>;
                    attributes.Add(new ElementAttribute("type", radioButtonFormValue != null ? "radio" : "checkbox"));
                    if (radioButtonFormValue != null || !isReadOnly)
                    {
                        attributes.Add(
                            new ElementAttribute(
                                "name",
                                radioButtonFormValue != null ? ((FormValue)radioButtonFormValue).GetPostBackValueKey() : context.Id));
                    }
                    if (radioButtonFormValue != null)
                    {
                        attributes.Add(new ElementAttribute("value", radioButtonListItemId ?? context.Id));
                    }
                    if (pageModificationValue.Value)
                    {
                        attributes.Add(new ElementAttribute("checked"));
                    }
                    if (isReadOnly)
                    {
                        attributes.Add(new ElementAttribute("disabled"));
                    }

                    var jsInitStatements = StringTools.ConcatenateWithDelimiter(
                        " ",
                        !isReadOnly
                                                                                                        ? SubmitButton.GetImplicitSubmissionKeyPressStatements(action, false)
                        .Surround("$( '#{0}' ).keypress( function( e ) {{ ".FormatWith(context.Id), " } );")
                                                                                                        : "",
                        jsClickStatementGetter().Surround("$( '#{0}' ).click( function() {{ ".FormatWith(context.Id), " } );"));

                    return new DisplayableElementLocalData(
                        "input",
                        new FocusabilityCondition(!isReadOnly),
                        isFocused => {
                        if (isFocused)
                        {
                            attributes.Add(new ElementAttribute("autofocus"));
                        }
                        return new DisplayableElementFocusDependentData(
                            attributes: attributes,
                            includeIdAttribute: true,
                            jsInitStatements: jsInitStatements);
                    });
                },
                    classes: elementClass,
                    clientSideIdReferences: id.ToCollection());
            },
                                   formValue: formValue).ToCollection()
                               .Concat(label.Any() ? new GenericPhrasingContainer(label, classes: elementClass).ToCollection() : Enumerable.Empty <FlowComponent>())
                               .Materialize())).ToCollection()));
        }
        /// <summary>
        /// Creates a simple HTML editor.
        /// </summary>
        /// <param name="value">Do not pass null.</param>
        /// <param name="allowEmpty"></param>
        /// <param name="validationMethod">The validation method. Do not pass null.</param>
        /// <param name="setup">The setup object for the HTML editor.</param>
        /// <param name="maxLength"></param>
        public WysiwygHtmlEditor(
            string value, bool allowEmpty, Action <string, Validator> validationMethod, WysiwygHtmlEditorSetup setup = null, int?maxLength = null)
        {
            setup = setup ?? new WysiwygHtmlEditorSetup();

            var id = new ElementId();
            FormValue <string> formValue = null;

            formValue = new FormValue <string>(
                () => value,
                () => setup.IsReadOnly ? "" : id.Id,
                v => v,
                rawValue => {
                if (rawValue == null)
                {
                    return(PostBackValueValidationResult <string> .CreateInvalid());
                }

                // This hack prevents the NewLine that CKEditor seems to always add to the end of the textarea from causing
                // ValueChangedOnPostBack to always return true.
                if (rawValue.EndsWith(Environment.NewLine) && rawValue.Remove(rawValue.Length - Environment.NewLine.Length) == formValue.GetDurableValue())
                {
                    rawValue = formValue.GetDurableValue();
                }

                return(PostBackValueValidationResult <string> .CreateValid(rawValue));
            });

            var modificationValue = new PageModificationValue <string>();

            component = new ElementComponent(
                context => {
                id.AddId(context.Id);

                var displaySetup     = setup.DisplaySetup ?? new DisplaySetup(true);
                var jsShowStatements = getJsShowStatements(context.Id, setup.CkEditorConfiguration);
                displaySetup.AddJsShowStatements(jsShowStatements);
                displaySetup.AddJsHideStatements("CKEDITOR.instances.{0}.destroy(); $( '#{0}' ).css( 'display', 'none' );".FormatWith(context.Id));

                return(new ElementData(
                           () => {
                    var attributes = new List <Tuple <string, string> >();
                    if (setup.IsReadOnly)
                    {
                        attributes.Add(Tuple.Create("disabled", "disabled"));
                    }
                    else
                    {
                        attributes.Add(Tuple.Create("name", context.Id));
                    }
                    if (!displaySetup.ComponentsDisplayed)
                    {
                        attributes.Add(Tuple.Create("style", "display: none"));
                    }

                    return new ElementLocalData(
                        "textarea",
                        attributes: attributes,
                        includeIdAttribute: true,
                        jsInitStatements: displaySetup.ComponentsDisplayed ? jsShowStatements : "");
                },
                           children: new TextNode(() => EwfTextBox.GetTextareaValue(modificationValue.Value)).ToCollection()));
            },
                formValue: formValue);

            validation = formValue.CreateValidation(
                (postBackValue, validator) => {
                if (setup.ValidationPredicate != null && !setup.ValidationPredicate(postBackValue.ChangedOnPostBack))
                {
                    return;
                }

                var errorHandler   = new ValidationErrorHandler("HTML");
                var validatedValue = maxLength.HasValue
                                                                     ? validator.GetString(errorHandler, postBackValue.Value, allowEmpty, maxLength.Value)
                                                                     : validator.GetString(errorHandler, postBackValue.Value, allowEmpty);
                if (errorHandler.LastResult != ErrorCondition.NoError)
                {
                    setup.ValidationErrorNotifier();
                    return;
                }

                validationMethod(validatedValue, validator);
            });

            formValue.AddPageModificationValue(modificationValue, v => v);
        }
예제 #30
0
        /// <summary>
        /// Creates an in-line radio button that is part of the group.
        /// </summary>
        public EwfCheckBox CreateInlineRadioButton(
            bool isSelected, string label = "", FormAction action = null, bool autoPostBack = false, PageModificationValue <bool> pageModificationValue = null)
        {
            EwfCheckBox checkBox = null;

            checkBox = new EwfCheckBox(
                formValue,
                label,
                action,
                () =>
                checkBoxesAndSelectionStatesAndPageModificationValues.Where(i => i.Item3 != null)
                .Select(i => i.Item3.GetJsModificationStatements(i.Item1 == checkBox ? "true" : "false")))
            {
                AutoPostBack = autoPostBack
            };
            checkBoxesAndSelectionStatesAndPageModificationValues.Add(
                Tuple.Create <CommonCheckBox, bool, PageModificationValue <bool> >(checkBox, isSelected, pageModificationValue));

            if (pageModificationValue != null)
            {
                formValue.AddPageModificationValue(pageModificationValue, value => value == checkBox);
            }

            return(checkBox);
        }