Пример #1
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;
        }
Пример #2
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 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;
            }
        }