/// <summary>
        /// Creates an HTML block editor.
        /// </summary>
        /// <param name="htmlBlockId"></param>
        /// <param name="idSetter"></param>
        /// <param name="mod"></param>
        /// <param name="setup">The setup object for the HTML block editor.</param>
        public HtmlBlockEditor(int?htmlBlockId, Action <int> idSetter, out HtmlBlockEditorModification mod, HtmlBlockEditorSetup setup = null)
        {
            setup = setup ?? new HtmlBlockEditorSetup();

            this.mod = mod = new HtmlBlockEditorModification(htmlBlockId, htmlBlockId.HasValue ? HtmlBlockStatics.GetHtml(htmlBlockId.Value) : "", idSetter);

            var wysiwygEditor = new WysiwygHtmlEditor(
                mod.Html,
                true,
                (postBackValue, validator) => {
                this.mod.Html = postBackValue;
                setup.AdditionalValidationMethod?.Invoke(validator);
            },
                setup: setup.WysiwygSetup);

            component =
                new DisplayableElement(
                    context => {
                return(new DisplayableElementData(
                           setup.DisplaySetup,
                           () => new DisplayableElementLocalData("div"),
                           classes: new ElementClass(CssElementCreator.CssClass),
                           children: wysiwygEditor.PageComponent.ToCollection()));
            });

            validation = wysiwygEditor.Validation;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a duration control.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="allowEmpty"></param>
        /// <param name="setup">The setup object for the duration control.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public DurationControl(TimeSpan?value, bool allowEmpty, DurationControlSetup setup = null, Action <TimeSpan?, Validator> validationMethod = null)
        {
            setup = setup ?? DurationControlSetup.Create();

            var textControl = new TextControl(
                value.HasValue ? Math.Floor(value.Value.TotalHours).ToString("0000") + ":" + value.Value.Minutes.ToString("00") : "",
                allowEmpty,
                setup: setup.IsReadOnly
                                               ? TextControlSetup.CreateReadOnly(validationPredicate: setup.ValidationPredicate, validationErrorNotifier: setup.ValidationErrorNotifier)
                                               : TextControlSetup.Create(
                    placeholder: "h:m",
                    action: new SpecifiedValue <FormAction>(setup.Action),
                    valueChangedAction: setup.ValueChangedAction,
                    pageModificationValue: setup.PageModificationValue,
                    validationPredicate: setup.ValidationPredicate,
                    validationErrorNotifier: setup.ValidationErrorNotifier),
                validationMethod: validationMethod == null
                                                          ? (Action <string, Validator>)null
                                                          : (postBackValue, validator) => {
                if (tooLongOrInvalidCharacters(postBackValue))
                {
                    validator.NoteErrorAndAddMessage("Please enter a valid duration.");
                    setup.ValidationErrorNotifier?.Invoke();
                    return;
                }

                var errorHandler   = new ValidationErrorHandler("duration");
                var validatedValue = validator.GetNullableTimeSpan(errorHandler, parseTimeSpan(postBackValue), allowEmpty);
                if (errorHandler.LastResult != ErrorCondition.NoError)
                {
                    setup.ValidationErrorNotifier?.Invoke();
                    return;
                }

                validationMethod(validatedValue, validator);
            });

            Labeler = textControl.Labeler;

            PageComponent = new CustomPhrasingComponent(
                new DisplayableElement(
                    context => new DisplayableElementData(
                        setup.DisplaySetup,
                        () => new DisplayableElementLocalData(
                            "span",
                            focusDependentData: new DisplayableElementFocusDependentData(
                                includeIdAttribute: true,
                                jsInitStatements:
                                "{0}.blur( function() {{ {1} }} ).keypress( function( e ) {{ {2} }} ).focus( function() {{ {3} }} ).mouseup( function( e ) {{ {4} }} );"
                                .FormatWith(
                                    getTextControlExpression(context.Id),
                                    "ApplyTimeSpanFormat( this );",
                                    "if( !NumericalOnly( e, this ) ) e.preventDefault();",
                                    "this.value = this.value.replace( ':', '' ); this.select();",
                                    "e.preventDefault();"))),
                        classes: elementClass.Add(setup.Classes ?? ElementClassSet.Empty),
                        children: textControl.PageComponent.ToCollection())).ToCollection());

            Validation = textControl.Validation;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a checkbox.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="label">The checkbox label. Do not pass null. Pass an empty collection for no label.</param>
        /// <param name="setup">The setup object for the checkbox.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public Checkbox(
            bool value, IReadOnlyCollection <PhrasingComponent> label, CheckboxSetup setup = null, Action <PostBackValue <bool>, Validator> validationMethod = null)
        {
            setup = setup ?? CheckboxSetup.Create();

            var id        = new ElementId();
            var formValue = new FormValue <bool>(
                () => value,
                () => setup.IsReadOnly ? "" : id.Id,
                v => v.ToString(),
                rawValue => rawValue == null ? PostBackValueValidationResult <bool> .CreateValid(false) :
                rawValue == "on" ? PostBackValueValidationResult <bool> .CreateValid(true) : PostBackValueValidationResult <bool> .CreateInvalid());

            PageComponent = getComponent(
                formValue,
                id,
                null,
                setup.DisplaySetup,
                setup.IsReadOnly,
                setup.Classes,
                setup.PageModificationValue,
                label,
                setup.Action,
                setup.ValueChangedAction,
                () => (setup.ValueChangedAction?.GetJsStatements() ?? "").ConcatenateWithSpace(
                    setup.PageModificationValue.GetJsModificationStatements("this.checked")));

            formValue.AddPageModificationValue(setup.PageModificationValue, v => v);

            if (validationMethod != null)
            {
                Validation = formValue.CreateValidation(validationMethod);
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates a form item with these components.
 /// </summary>
 /// <param name="content">Do not pass null.</param>
 /// <param name="setup"></param>
 /// <param name="label">The form-item label.</param>
 /// <param name="validation"></param>
 public static FormItem ToFormItem(
     this IReadOnlyCollection <FlowComponent> content, FormItemSetup setup = null, IReadOnlyCollection <PhrasingComponent> label = null,
     EwfValidation validation = null)
 {
     label = label ?? Enumerable.Empty <PhrasingComponent>().Materialize();
     return(new FormItem(setup, label, content, validation != null ? validation.ToCollection() : Enumerable.Empty <EwfValidation>().Materialize()));
 }
Ejemplo n.º 5
0
 internal FormItem(
     FormItemSetup setup, IReadOnlyCollection <PhrasingComponent> label, IReadOnlyCollection <FlowComponent> content, EwfValidation validation)
 {
     Setup          = setup ?? new FormItemSetup();
     this.label     = label;
     this.content   = content;
     Validation     = validation;
     ErrorSourceSet = validation != null ? new ErrorSourceSet(validations: validation.ToCollection()) : null;
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a file-upload control.
        /// </summary>
        /// <param name="displaySetup"></param>
        /// <param name="validationPredicate"></param>
        /// <param name="validationErrorNotifier"></param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public FileUpload(
            DisplaySetup displaySetup = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null,
            Action <RsFile, Validator> validationMethod = null)
        {
            Labeler = new FormControlLabeler();

            var id        = new ElementId();
            var formValue = new FormValue <HttpPostedFile>(
                () => null,
                () => id.Id,
                v => "",
                rawValue => rawValue == null
                                                    ? PostBackValueValidationResult <HttpPostedFile> .CreateInvalid()
                                                    : PostBackValueValidationResult <HttpPostedFile> .CreateValid(rawValue.ContentLength > 0 ? rawValue : null));

            PageComponent = new CustomPhrasingComponent(
                new DisplayableElement(
                    context => {
                id.AddId(context.Id);
                Labeler.AddControlId(context.Id);

                EwfPage.Instance.Form.Enctype = "multipart/form-data";

                return(new DisplayableElementData(
                           displaySetup,
                           () => {
                    var attributes = new List <Tuple <string, string> >();
                    attributes.Add(Tuple.Create("type", "file"));
                    attributes.Add(Tuple.Create("name", context.Id));

                    return new DisplayableElementLocalData(
                        "input",
                        new FocusabilityCondition(true),
                        isFocused => {
                        if (isFocused)
                        {
                            attributes.Add(Tuple.Create("autofocus", "autofocus"));
                        }
                        return new DisplayableElementFocusDependentData(attributes: attributes);
                    });
                }));
            },
                    formValue: formValue).ToCollection());

            if (validationMethod != null)
            {
                Validation = formValue.CreateValidation(
                    (postBackValue, validator) => {
                    if (validationPredicate != null && !validationPredicate(postBackValue.ChangedOnPostBack))
                    {
                        return;
                    }
                    validationMethod(getRsFile(postBackValue.Value), validator);
                });
            }
        }
        /// <summary>
        /// Creates a radio button.
        /// </summary>
        internal FlowCheckbox(FlowRadioButtonSetup setup, Checkbox checkbox)
        {
            PageComponent = getComponent(
                setup.DisplaySetup,
                setup.Classes,
                setup.RadioButtonSetup.PageModificationValue,
                checkbox,
                setup.HighlightedWhenSelected,
                setup.NestedContentGetter,
                setup.NestedContentAlwaysDisplayed);

            Validation = checkbox.Validation;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates a form item.
        /// </summary>
        protected FormItem(FormItemLabel label, Control control, int?cellSpan, TextAlignment textAlignment, EwfValidation validation)
        {
            if (label == null)
            {
                throw new ApplicationException("The label cannot be a null FormItemLabel reference.");
            }
            this.label = label;

            this.control       = control;
            this.cellSpan      = cellSpan;
            this.textAlignment = textAlignment;
            this.validation    = validation;
        }
        /// <summary>
        /// Creates a check box.
        /// </summary>
        /// <param name="isChecked"></param>
        /// <param name="validationMethod">The validation method. Do not pass null.</param>
        /// <param name="label">Do not pass null.</param>
        /// <param name="setup">The setup object for the check box.</param>
        public BlockCheckBox(bool isChecked, Action <PostBackValue <bool>, Validator> validationMethod, string label = "", BlockCheckBoxSetup setup = null)
        {
            this.setup = setup ?? new BlockCheckBoxSetup();

            checkBoxFormValue = EwfCheckBox.GetFormValue(isChecked, this);

            this.label = label;
            action     = this.setup.Action ?? FormState.Current.DefaultAction;

            validation = checkBoxFormValue.CreateValidation(validationMethod);

            nestedControls = this.setup.NestedControlListGetter != null?this.setup.NestedControlListGetter().ToImmutableArray() : ImmutableArray <Control> .Empty;
        }
        /// <summary>
        /// Creates a radio button.
        /// </summary>
        internal BlockCheckBox(
            FormValue <CommonCheckBox> formValue, string label, BlockCheckBoxSetup setup, Func <IEnumerable <string> > jsClickHandlerStatementListGetter,
            EwfValidation validation, string listItemId = null)
        {
            radioButtonFormValue  = formValue;
            radioButtonListItemId = listItemId;
            this.label            = label;
            this.setup            = setup;
            action = setup.Action ?? FormState.Current.DefaultAction;
            jsClickHandlerStatementLists.Add(jsClickHandlerStatementListGetter);

            this.validation = validation;

            nestedControls = setup.NestedControlListGetter != null?setup.NestedControlListGetter().ToImmutableArray() : ImmutableArray <Control> .Empty;
        }
        /// <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);
            }
        }
        /// <summary>
        /// Creates a checkbox.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="label">The checkbox label. Do not pass null. Pass an empty collection for no label.</param>
        /// <param name="setup">The setup object for the flow checkbox.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using the checkbox for page modification.</param>
        public FlowCheckbox(
            bool value, IReadOnlyCollection <PhrasingComponent> label, FlowCheckboxSetup setup = null,
            Action <PostBackValue <bool>, Validator> validationMethod = null)
        {
            setup = setup ?? FlowCheckboxSetup.Create();

            var checkbox = new Checkbox(value, label, setup: setup.CheckboxSetup, validationMethod: validationMethod);

            PageComponent = getComponent(
                setup.DisplaySetup,
                setup.Classes,
                setup.CheckboxSetup.PageModificationValue,
                checkbox,
                setup.HighlightedWhenChecked,
                setup.NestedContentGetter,
                setup.NestedContentAlwaysDisplayed);

            Validation = checkbox.Validation;
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates a radio button.
 /// </summary>
 internal Checkbox(
     FormValue <ElementId> formValue, ElementId id, RadioButtonSetup setup, IReadOnlyCollection <PhrasingComponent> label, FormAction selectionChangedAction,
     Func <string> jsClickStatementGetter, EwfValidation validation, string listItemId = null)
 {
     PageComponent = getComponent(
         formValue,
         id,
         listItemId,
         setup.DisplaySetup,
         setup.IsReadOnly,
         setup.Classes,
         setup.PageModificationValue,
         label,
         setup.Action,
         selectionChangedAction,
         () => setup.IsReadOnly
                                       ? ""
                                       : (setup.PageModificationValue.Value ? "" : selectionChangedAction?.GetJsStatements() ?? "")
         .ConcatenateWithSpace(jsClickStatementGetter()));
     Validation = validation;
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Creates a form item with this component.
 /// </summary>
 /// <param name="content">Do not pass null.</param>
 /// <param name="setup"></param>
 /// <param name="label">The form-item label.</param>
 /// <param name="validation"></param>
 public static FormItem ToFormItem(
     this FlowComponent content, FormItemSetup setup = null, IReadOnlyCollection <PhrasingComponent> label = null, EwfValidation validation = null) =>
 content.ToCollection().ToFormItem(setup: setup, label: label, validation: validation);
Ejemplo n.º 15
0
 /// <summary>
 /// Adds an extraneous validation to this form item. Useful when you have validation logic that needs to execute in a different set of data modifications
 /// than the form item’s built-in validation. For example, you may have a form item that modifies a piece of component state during an intermediate
 /// post-back. If you later need to update the state item’s durable value during a full post-back, and this involves additional validation, you can create a
 /// separate <see cref="EwfValidation"/> and use this method to keep the errors within the form item.
 /// </summary>
 public FormItem AddExtraneousValidation(EwfValidation validation)
 {
     return(new FormItem(Setup, label, content, validations.Append(validation).Materialize()));
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Creates a modification error placeholder for the specified validation, or for the top modification errors if no validation is passed.
 /// </summary>
 public ModificationErrorPlaceholder(EwfValidation validation, ErrorDisplayStyle displayStyle)
 {
     this.validation   = validation;
     this.displayStyle = displayStyle;
 }
Ejemplo n.º 17
0
 void ValidationListInternal.AddValidation(EwfValidation validation)
 {
     ((ValidationListInternal)dataModification).AddValidation(validation);
 }
        /// <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);
        }
 /// <summary>
 /// Returns the errors from the specified validation.
 /// </summary>
 public IReadOnlyCollection <string> GetErrors(EwfValidation validation)
 {
     return(dictionary[validation]);
 }
 void ValidationList.AddValidation(EwfValidation validation)
 {
     validations.Add(validation);
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Creates a date-and-time control.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="allowEmpty"></param>
        /// <param name="setup">The setup object for the date-and-time control.</param>
        /// <param name="minValue">The earliest acceptable date.</param>
        /// <param name="maxValue">The latest acceptable date.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public DateAndTimeControl(
            LocalDateTime?value, bool allowEmpty, DateAndTimeControlSetup setup = null, LocalDate?minValue = null, LocalDate?maxValue = null,
            Action <LocalDateTime?, Validator> validationMethod = null)
        {
            setup = setup ?? DateAndTimeControlSetup.Create();

            var textControl = new TextControl(
                value.HasValue ? value.Value.ToDateTimeUnspecified().ToMonthDayYearString() + " " + value.Value.ToDateTimeUnspecified().ToHourAndMinuteString() : "",
                allowEmpty,
                setup: setup.IsReadOnly
                                               ? TextControlSetup.CreateReadOnly(validationPredicate: setup.ValidationPredicate, validationErrorNotifier: setup.ValidationErrorNotifier)
                                               : TextControlSetup.Create(
                    autoFillTokens: setup.AutoFillTokens,
                    action: new SpecifiedValue <FormAction>(setup.Action),
                    valueChangedAction: setup.ValueChangedAction,
                    pageModificationValue: setup.PageModificationValue,
                    validationPredicate: setup.ValidationPredicate,
                    validationErrorNotifier: setup.ValidationErrorNotifier),
                validationMethod: validationMethod == null
                                                          ? (Action <string, Validator>)null
                                                          : (postBackValue, validator) => {
                var errorHandler   = new ValidationErrorHandler("date and time");
                var validatedValue = validator.GetNullableDateTime(
                    errorHandler,
                    postBackValue.ToUpper(),
                    TewlContrib.DateTimeTools.MonthDayYearFormats.Select(i => i + " " + TewlContrib.DateTimeTools.HourAndMinuteFormat).ToArray(),
                    allowEmpty,
                    minValue?.ToDateTimeUnspecified() ?? DateTime.MinValue,
                    maxValue?.PlusDays(1).ToDateTimeUnspecified() ?? DateTime.MaxValue);
                if (errorHandler.LastResult != ErrorCondition.NoError)
                {
                    setup.ValidationErrorNotifier?.Invoke();
                    return;
                }

                validationMethod(
                    validatedValue.HasValue ? (LocalDateTime?)LocalDateTime.FromDateTime(validatedValue.Value) : null,
                    validator);
            });

            Labeler = textControl.Labeler;

            PageComponent = new CustomPhrasingComponent(
                new DisplayableElement(
                    context => new DisplayableElementData(
                        setup.DisplaySetup,
                        () => new DisplayableElementLocalData(
                            "span",
                            focusDependentData: new DisplayableElementFocusDependentData(
                                includeIdAttribute: true,
                                jsInitStatements: "{0}.datetimepicker( {{ {1} }} );".FormatWith(
                                    getTextControlExpression(context.Id),
                                    StringTools.ConcatenateWithDelimiter(
                                        ", ",
                                        minValue.HasValue
                                                                                        ? "minDate: {0}".FormatWith("new Date( {0}, {1} - 1, {2} )".FormatWith(minValue.Value.Year, minValue.Value.Month, minValue.Value.Day))
                                                                                        : "",
                                        maxValue.HasValue
                                                                                        ? "maxDate: {0}".FormatWith("new Date( {0}, {1} - 1, {2} )".FormatWith(maxValue.Value.Year, maxValue.Value.Month, maxValue.Value.Day))
                                                                                        : "",
                                        "timeFormat: 'h:mmt'",
                                        "stepMinute: {0}".FormatWith(setup.MinuteInterval.Value))))),
                        classes: elementClass.Add(setup.Classes ?? ElementClassSet.Empty),
                        children: textControl.PageComponent.ToCollection()
                        .Concat(
                            setup.IsReadOnly
                                                                        ? Enumerable.Empty <PhrasingComponent>()
                                                                        : new EwfButton(
                                new CustomButtonStyle(
                                    children: new GenericPhrasingContainer(
                                        new FontAwesomeIcon("fa-calendar-o", "fa-stack-2x").ToCollection()
                                        .Append(new FontAwesomeIcon("fa-clock-o", "fa-stack-1x"))
                                        .Materialize(),
                                        classes: new ElementClass("fa-stack")).ToCollection()),
                                behavior: new CustomButtonBehavior(() => "{0}.datetimepicker( 'show' );".FormatWith(getTextControlExpression(context.Id))),
                                classes: new ElementClass("icon")).ToCollection())
                        .Materialize())).ToCollection());

            Validation = textControl.Validation;
        }
 /// <summary>
 /// Creates a modification error placeholder for the specified validation, or for the top modification errors if no validation is passed.
 /// </summary>
 public ModificationErrorPlaceholder( EwfValidation validation, ErrorDisplayStyle displayStyle )
 {
     this.validation = validation;
     this.displayStyle = displayStyle;
 }
 void ValidationListInternal.AddValidation( EwfValidation validation )
 {
     validations.Add( validation );
 }
Ejemplo n.º 24
0
        /// <summary>
        /// Creates a checkbox list.
        /// </summary>
        /// <param name="setup">The setup object for the checkbox list. Do not pass null.</param>
        /// <param name="value">The selected-item IDs.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public CheckboxList(
            CheckboxListSetup <ItemIdType> setup, IEnumerable <ItemIdType> value, Action <IReadOnlyCollection <ItemIdType>, Validator> validationMethod = null)
        {
            var valueSet = value.ToImmutableHashSet();

            var selectedItemIdsInPostBack  = new List <ItemIdType>();
            var selectionChangedOnPostBack = false;
            var checkboxes = setup.Items.Select(
                i => new FlowCheckbox(
                    valueSet.Contains(i.Id),
                    i.Label.ToComponents(),
                    setup: FlowCheckboxSetup.Create(
                        highlightedWhenChecked: true,
                        action: new SpecifiedValue <FormAction>(setup.Action),
                        valueChangedAction: setup.SelectionChangedAction),
                    validationMethod: (postBackValue, validator) => {
                if (postBackValue.Value)
                {
                    selectedItemIdsInPostBack.Add(i.Id);
                }
                selectionChangedOnPostBack = selectionChangedOnPostBack || postBackValue.ChangedOnPostBack;
            }))
                             .Materialize();

            var contentContainerId = new ElementId();

            PageComponent = new GenericFlowContainer(
                (setup.IncludeSelectAndDeselectAllButtons
                                          ? new GenericFlowContainer(
                     new InlineList(
                         new EwfButton(
                             new StandardButtonStyle(
                                 "Select All",
                                 buttonSize: ButtonSize.ShrinkWrap,
                                 icon: new ActionComponentIcon(new FontAwesomeIcon("fa-check-square-o"))),
                             behavior: new CustomButtonBehavior(
                                 () => "$( '#{0}' ).find( 'input[type=checkbox]:not(:checked)' ).click();".FormatWith(contentContainerId.Id))).ToCollection()
                         .ToComponentListItem()
                         .ToCollection()
                         .Append(
                             new EwfButton(
                                 new StandardButtonStyle(
                                     "Deselect All",
                                     buttonSize: ButtonSize.ShrinkWrap,
                                     icon: new ActionComponentIcon(new FontAwesomeIcon("fa-square-o"))),
                                 behavior: new CustomButtonBehavior(
                                     () => "$( '#{0}' ).find( 'input[type=checkbox]:checked' ).click();".FormatWith(contentContainerId.Id))).ToCollection()
                             .ToComponentListItem())).ToCollection(),
                     classes: CheckboxListCssElementCreator.ActionContainerClass).ToCollection()
                                          : Enumerable.Empty <FlowComponent>()).Append(
                    new DisplayableElement(
                        context => {
                contentContainerId.AddId(context.Id);
                return(new DisplayableElementData(
                           null,
                           () => new DisplayableElementLocalData(
                               "div",
                               focusDependentData: new DisplayableElementFocusDependentData(
                                   attributes: setup.MinColumnWidth != null
                                                                                                    ? Tuple.Create("style", "column-width: {0}".FormatWith(((CssLength)setup.MinColumnWidth).Value)).ToCollection()
                                                                                                    : null,
                                   includeIdAttribute: true)),
                           classes: CheckboxListCssElementCreator.ContentContainerClass,
                           children: new RawList(from i in checkboxes select i.PageComponent.ToCollection().ToComponentListItem()).ToCollection()));
            }))
                .Materialize(),
                displaySetup: setup.DisplaySetup,
                classes: CheckboxListCssElementCreator.ListClass);

            if (validationMethod != null)
            {
                Validation = new EwfValidation(
                    validator => {
                    if (setup.ValidationPredicate != null && !setup.ValidationPredicate(selectionChangedOnPostBack))
                    {
                        return;
                    }
                    validationMethod(selectedItemIdsInPostBack, validator);
                });
            }
        }
Ejemplo n.º 25
0
 private void handleValidationErrors( EwfValidation validation, IEnumerable<string> errorMessages )
 {
     if( !modErrorDisplaysByValidation.ContainsKey( validation ) || !errorMessages.Any() )
         return;
     foreach( var displayKey in modErrorDisplaysByValidation[ validation ] ) {
         var errorsByDisplay = AppRequestState.Instance.EwfPageRequestState.InLineModificationErrorsByDisplay;
         errorsByDisplay[ displayKey ] = errorsByDisplay.ContainsKey( displayKey ) ? errorsByDisplay[ displayKey ].Concat( errorMessages ) : errorMessages;
     }
 }
        /// <summary>
        /// Creates a time control.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="allowEmpty"></param>
        /// <param name="setup">The setup object for the time control.</param>
        /// <param name="minValue">The earliest allowed time.</param>
        /// <param name="maxValue">The latest allowed time. This can be earlier than <paramref name="minValue"/> to create a range spanning midnight.</param>
        /// <param name="minuteInterval">Allows the user to select values only in the given increments. Be aware that other values can still be sent from the
        /// browser via a crafted request.</param>
        /// <param name="validationMethod">The validation method. Pass null if you’re only using this control for page modification.</param>
        public TimeControl(
            LocalTime?value, bool allowEmpty, TimeControlSetup setup = null, LocalTime?minValue = null, LocalTime?maxValue = null, int minuteInterval = 15,
            Action <LocalTime?, Validator> validationMethod          = null)
        {
            setup    = setup ?? TimeControlSetup.Create();
            minValue = minValue ?? LocalTime.Midnight;

            if (minuteInterval < 30)
            {
                var textControl = new TextControl(
                    value.HasValue ? new TimeSpan(value.Value.TickOfDay).ToTimeOfDayHourAndMinuteString() : "",
                    allowEmpty,
                    setup: setup.IsReadOnly
                                                       ? TextControlSetup.CreateReadOnly(validationPredicate: setup.ValidationPredicate, validationErrorNotifier: setup.ValidationErrorNotifier)
                                                       : TextControlSetup.Create(
                        autoFillTokens: setup.AutoFillTokens,
                        action: new SpecifiedValue <FormAction>(setup.Action),
                        valueChangedAction: setup.ValueChangedAction,
                        pageModificationValue: setup.PageModificationValue,
                        validationPredicate: setup.ValidationPredicate,
                        validationErrorNotifier: setup.ValidationErrorNotifier),
                    validationMethod: validationMethod == null
                                                                  ? (Action <string, Validator>)null
                                                                  : (postBackValue, validator) => {
                    var errorHandler   = new ValidationErrorHandler("time");
                    var validatedValue = validator.GetNullableTimeOfDayTimeSpan(
                        errorHandler,
                        postBackValue.ToUpper(),
                        TewlContrib.DateTimeTools.HourAndMinuteFormat.ToCollection().ToArray(),
                        allowEmpty)
                                         .ToNewUnderlyingValue(v => LocalTime.FromTicksSinceMidnight(v.Ticks));
                    if (errorHandler.LastResult != ErrorCondition.NoError)
                    {
                        setup.ValidationErrorNotifier?.Invoke();
                        return;
                    }

                    var wrap = maxValue < minValue.Value;
                    if (!wrap
                                                                                      ? validatedValue < minValue.Value || validatedValue > maxValue
                                                                                      : validatedValue < minValue.Value && validatedValue > maxValue)
                    {
                        validator.NoteErrorAndAddMessage("The time is too early or too late.");
                        setup.ValidationErrorNotifier?.Invoke();
                        return;
                    }

                    validationMethod(validatedValue, validator);
                });

                Labeler = textControl.Labeler;

                PageComponent = new DisplayableElement(
                    context => new DisplayableElementData(
                        setup.DisplaySetup,
                        () => new DisplayableElementLocalData(
                            "div",
                            focusDependentData: new DisplayableElementFocusDependentData(
                                includeIdAttribute: true,
                                jsInitStatements: "{0}.timepicker( {{ {1} }} );".FormatWith(
                                    getTextControlExpression(context.Id),
                                    StringTools.ConcatenateWithDelimiter(
                                        ", ",
                                        "timeFormat: 'h:mmt'",
                                        "stepMinute: {0}".FormatWith(minuteInterval),
                                        "showButtonPanel: false")))),
                        classes: elementClass.Add(setup.Classes ?? ElementClassSet.Empty),
                        children: textControl.PageComponent.ToCollection()
                        .Concat(
                            setup.IsReadOnly
                                                                        ? Enumerable.Empty <PhrasingComponent>()
                                                                        : new EwfButton(
                                new CustomButtonStyle(children: new FontAwesomeIcon("fa-clock-o").ToCollection()),
                                behavior: new CustomButtonBehavior(() => "{0}.timepicker( 'show' );".FormatWith(getTextControlExpression(context.Id))),
                                classes: new ElementClass("icon")).ToCollection())
                        .Materialize()));

                Validation = textControl.Validation;
            }
            else
            {
                var items = from time in getTimes(minValue.Value, maxValue, minuteInterval)
                            let timeSpan = new TimeSpan(time.TickOfDay)
                                           select SelectListItem.Create <LocalTime?>(time, timeSpan.ToTimeOfDayHourAndMinuteString());

                var selectList = SelectList.CreateDropDown(
                    setup.IsReadOnly
                                                ? DropDownSetup.CreateReadOnly(
                        items,
                        placeholderText: "",
                        validationPredicate: setup.ValidationPredicate,
                        validationErrorNotifier: setup.ValidationErrorNotifier)
                                                : DropDownSetup.Create(
                        items,
                        placeholderText: "",
                        autoFillTokens: setup.AutoFillTokens,
                        action: new SpecifiedValue <FormAction>(setup.Action),
                        selectionChangedAction: setup.ValueChangedAction,
                        validationPredicate: setup.ValidationPredicate,
                        validationErrorNotifier: setup.ValidationErrorNotifier),
                    value,
                    placeholderIsValid: allowEmpty,
                    validationMethod: validationMethod);

                Labeler = selectList.Labeler;

                PageComponent = new GenericFlowContainer(
                    selectList.PageComponent.ToCollection(),
                    displaySetup: setup.DisplaySetup,
                    classes: elementClass.Add(setup.Classes ?? ElementClassSet.Empty));

                Validation = selectList.Validation;
            }
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Returns the errors from the specified validation.
 /// </summary>
 public IReadOnlyCollection <string> GetValidationErrors(EwfValidation validation) => errorsByValidation[validation];
 void ValidationListInternal.AddValidation( EwfValidation validation )
 {
     ( (ValidationListInternal)dataModification ).AddValidation( validation );
 }
 public void AddTopValidationMethod( Action<PostBackValueDictionary, Validator> validationMethod )
 {
     var validation = new EwfValidation( validationMethod, this );
     topValidations.Add( validation );
 }
Ejemplo n.º 30
0
 void ValidationListInternal.AddValidation(EwfValidation validation)
 {
     validations.Add(validation);
 }
Ejemplo n.º 31
0
        /// <summary>
        /// If you are using the results of this method to create controls, put them in a naming container so that when the controls differ before and after a
        /// transfer, other parts of the page such as form control IDs do not get affected.
        /// </summary>
        internal IEnumerable<string> AddModificationErrorDisplayAndGetErrors( Control control, string keySuffix, EwfValidation validation )
        {
            var key = control.UniqueID + keySuffix;
            if( modErrorDisplaysByValidation.ContainsKey( validation ) )
                modErrorDisplaysByValidation[ validation ].Add( key );
            else
                modErrorDisplaysByValidation.Add( validation, key.ToSingleElementArray().ToList() );

            // We want to ignore all of the problems that could happen, such as the key not existing in the dictionary. This problem will be shown in a more helpful
            // way when we compare form control hashes after a transfer.
            //
            // Avoid using exceptions here if possible. This method is sometimes called many times during a request, and we've seen exceptions take as long as 50 ms
            // each when debugging.
            IEnumerable<string> value;
            return AppRequestState.Instance.EwfPageRequestState.InLineModificationErrorsByDisplay.TryGetValue( key, out value ) ? value : new string[ 0 ];
        }
Ejemplo n.º 32
0
 void ValidationList.AddValidation(EwfValidation validation)
 {
     ((ValidationList)dataModification).AddValidation(validation);
 }
        public void AddTopValidationMethod(Action <PostBackValueDictionary, Validator> validationMethod)
        {
            var validation = new EwfValidation(validationMethod, this);

            topValidations.Add(validation);
        }