internal static void AddCheckBoxAttributes(
            WebControl checkBoxElement, Control checkBox, FormValue <bool> checkBoxFormValue, FormValue <CommonCheckBox> radioButtonFormValue, string radioButtonListItemId,
            FormAction action, bool autoPostBack, IEnumerable <string> onClickJsMethods)
        {
            checkBoxElement.Attributes.Add("type", checkBoxFormValue != null ? "checkbox" : "radio");
            checkBoxElement.Attributes.Add("name", checkBoxFormValue != null ? checkBox.UniqueID : ((FormValue)radioButtonFormValue).GetPostBackValueKey());
            if (radioButtonFormValue != null)
            {
                checkBoxElement.Attributes.Add("value", radioButtonListItemId ?? checkBox.UniqueID);
            }
            if (checkBoxFormValue != null
                                    ? checkBoxFormValue.GetValue(AppRequestState.Instance.EwfPageRequestState.PostBackValues)
                                    : radioButtonFormValue.GetValue(AppRequestState.Instance.EwfPageRequestState.PostBackValues) == checkBox)
            {
                checkBoxElement.Attributes.Add("checked", "checked");
            }

            SubmitButton.EnsureImplicitSubmissionAction(checkBoxElement, action, false);
            var isSelectedRadioButton = radioButtonFormValue != null &&
                                        radioButtonFormValue.GetValue(AppRequestState.Instance.EwfPageRequestState.PostBackValues) == checkBox;
            var postBackScript = autoPostBack && !isSelectedRadioButton?action.GetJsStatements() : "";

            var customScript = StringTools.ConcatenateWithDelimiter("; ", onClickJsMethods.ToArray());

            checkBoxElement.AddJavaScriptEventScript(JsWritingMethods.onclick, StringTools.ConcatenateWithDelimiter("; ", postBackScript, customScript));
        }
        internal void SetUpClickableControl(WebControl clickableControl)
        {
            if (resource == null && action == null && script == "")
            {
                return;
            }

            clickableControl.CssClass = clickableControl.CssClass.ConcatenateWithSpace("ewfClickable");

            if (resource != null && EwfPage.Instance.IsAutoDataUpdater)
            {
                action   = HyperlinkBehavior.GetHyperlinkPostBackAction(resource);
                resource = null;
            }

            Func <string> scriptGetter;

            if (resource != null)
            {
                scriptGetter = () => "location.href = '" + EwfPage.Instance.GetClientUrl(resource.GetUrl()) + "'; return false";
            }
            else if (action != null)
            {
                action.AddToPageIfNecessary();
                scriptGetter = () => action.GetJsStatements() + " return false";
            }
            else
            {
                scriptGetter = () => script;
            }

            // Defer script generation until after all controls have IDs.
            EwfPage.Instance.PreRender += delegate { clickableControl.AddJavaScriptEventScript(JsWritingMethods.onclick, scriptGetter()); };
        }
Example #3
0
 string ButtonBehavior.GetJsInitStatements(string id)
 {
     return("$( '#{0}' ).click( function() {{ {1} }} );".FormatWith(id, Action.GetJsStatements()));
 }
        internal HyperlinkBehavior(ResourceInfo destination, string target, Func <string, string> actionStatementGetter)
        {
            this.destination = destination;
            Classes          = destination?.AlternativeMode is NewContentResourceMode ? ActionComponentCssElementCreator.NewContentClass : ElementClassSet.Empty;

            Url             = new Lazy <string>(() => destination != null ? destination.GetUrl(true, false, true) : "");
            AttributeGetter = forNonHyperlinkElement =>
                              (destination != null && !forNonHyperlinkElement ? Tuple.Create("href", Url.Value).ToCollection() : Enumerable.Empty <Tuple <string, string> >())
                              .Concat(
                destination != null && target.Any() && !forNonHyperlinkElement
                                                ? Tuple.Create("target", target).ToCollection()
                                                : Enumerable.Empty <Tuple <string, string> >())
                              .Materialize();

            var isPostBackHyperlink = destination != null && !(destination.AlternativeMode is DisabledResourceMode) && !target.Any() &&
                                      EwfPage.Instance.IsAutoDataUpdater;
            FormAction postBackAction = null;

            string getActionInitStatements(string id, bool omitPreventDefaultStatement, string actionStatements) =>
            "$( '#{0}' ).click( function( e ) {{ {1} }} );".FormatWith(
                id,
                (omitPreventDefaultStatement ? "" : "e.preventDefault();").ConcatenateWithSpace(actionStatements));

            if (destination?.AlternativeMode is DisabledResourceMode disabledResourceMode)
            {
                IncludesIdAttribute = forNonHyperlinkElement => true;
                EtherealChildren    = new ToolTip(
                    (disabledResourceMode.Message.Any() ? disabledResourceMode.Message : Translation.ThePageYouRequestedIsDisabled).ToComponents(),
                    out var toolTipInitStatementGetter).ToCollection();
                JsInitStatementGetter = (id, forNonHyperlinkElement) =>
                                        (forNonHyperlinkElement ? "" : getActionInitStatements(id, false, "") + " ") + toolTipInitStatementGetter(id);
            }
            else
            {
                IncludesIdAttribute = forNonHyperlinkElement =>
                                      isPostBackHyperlink || (destination != null && (actionStatementGetter != null || forNonHyperlinkElement));
                EtherealChildren      = null;
                JsInitStatementGetter = (id, forNonHyperlinkElement) => {
                    var actionStatements = isPostBackHyperlink ? postBackAction.GetJsStatements() :
                                           destination != null && actionStatementGetter != null?actionStatementGetter(Url.Value) :
                                               destination != null && forNonHyperlinkElement ? !target.Any()
                                                                                                                       ? "window.location.href = '{0}';".FormatWith(Url.Value)
                                                                                                                       :
                                               target == "_parent"
                                                                                                                               ?
                                               "window.parent.location.href = '{0}';".FormatWith(Url.Value)
                                                                                                                               : "window.open( '{0}', '{1}' );".FormatWith(Url.Value, target) : "";

                    return(actionStatements.Any() ? getActionInitStatements(id, forNonHyperlinkElement, actionStatements) : "");
                };
            }

            IsFocusable = destination != null;

            if (isPostBackHyperlink)
            {
                PostBackAdder = () => {
                    postBackAction = GetHyperlinkPostBackAction(destination);
                    postBackAction.AddToPageIfNecessary();
                }
            }
            ;
            else
            {
                PostBackAdder = () => {}
            };
        }
 /// <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;
 }
Example #6
0
 /// <summary>
 /// Returns the JavaScript statements that should be executed on keypress to ensure that a form control will trigger the specified action when the enter key
 /// is pressed while the control has focus. If you specify the submit-button post-back, this method relies on HTML’s built-in implicit submission behavior,
 /// which will simulate a click on the submit button.
 /// </summary>
 internal static string GetImplicitSubmissionKeyPressStatements(FormAction action, bool forceJsHandling)
 {
     // EWF does not allow form controls to use HTML’s built-in implicit submission on a page with no submit button. There are two reasons for this. First, the
     // behavior of HTML’s implicit submission appears to be somewhat arbitrary when there is no submit button; see
     // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission. Second, we don’t want the implicit submission behavior of
     // form controls to unpredictably change if a submit button is added or removed.
     return(action is PostBackFormAction postBackAction && postBackAction.PostBack == PageBase.Current.SubmitButtonPostBack && !forceJsHandling
                                ? ""
                                : "if( e.which == 13 ) {{ {0} }}".FormatWith("e.preventDefault();".ConcatenateWithSpace(action?.GetJsStatements() ?? "")));
 }
        internal HyperlinkBehavior(ResourceInfo destination, bool disableAuthorizationCheck, string target, Func <string, string> actionStatementGetter)
        {
            hasDestination = destination != null;
            userCanNavigateToDestinationPredicate = () => !hasDestination || disableAuthorizationCheck || destination.UserCanAccessResource;

            var destinationAlternativeMode = hasDestination && !disableAuthorizationCheck ? destination.AlternativeMode : null;

            Classes = destinationAlternativeMode is NewContentResourceMode ? ActionComponentCssElementCreator.NewContentClass : ElementClassSet.Empty;

            Url = new Lazy <string>(() => hasDestination ? destination.GetUrl(!disableAuthorizationCheck, false) : "");
            var isPostBackHyperlink = new Lazy <bool>(
                () => hasDestination && !(destinationAlternativeMode is DisabledResourceMode) && !target.Any() && PageBase.Current.IsAutoDataUpdater.Value);

            AttributeGetter = forNonHyperlinkElement =>
                              (hasDestination && !forNonHyperlinkElement ? new ElementAttribute("href", Url.Value).ToCollection() : Enumerable.Empty <ElementAttribute>()).Concat(
                hasDestination && target.Any() && !forNonHyperlinkElement
                                                ? new ElementAttribute("target", target).ToCollection()
                                                : Enumerable.Empty <ElementAttribute>())
                              .Concat(
                // for https://instant.page/
                !isPostBackHyperlink.Value && destination is ResourceBase && !(destinationAlternativeMode is DisabledResourceMode) && !forNonHyperlinkElement
                                                ? new ElementAttribute("data-instant").ToCollection()
                                                : Enumerable.Empty <ElementAttribute>())
                              .Materialize();

            FormAction postBackAction = null;

            string getActionInitStatements(string id, bool omitPreventDefaultStatement, string actionStatements) =>
            "$( '#{0}' ).click( function( e ) {{ {1} }} );".FormatWith(
                id,
                (omitPreventDefaultStatement ? "" : "e.preventDefault();").ConcatenateWithSpace(actionStatements));

            if (destinationAlternativeMode is DisabledResourceMode disabledResourceMode)
            {
                IncludesIdAttribute = forNonHyperlinkElement => true;
                EtherealChildren    = new ToolTip(
                    (disabledResourceMode.Message.Any() ? disabledResourceMode.Message : Translation.ThePageYouRequestedIsDisabled).ToComponents(),
                    out var toolTipInitStatementGetter).ToCollection();
                JsInitStatementGetter = (id, forNonHyperlinkElement) =>
                                        (forNonHyperlinkElement ? "" : getActionInitStatements(id, false, "") + " ") + toolTipInitStatementGetter(id);
            }
            else
            {
                IncludesIdAttribute = forNonHyperlinkElement =>
                                      isPostBackHyperlink.Value || (hasDestination && (actionStatementGetter != null || forNonHyperlinkElement));
                EtherealChildren      = null;
                JsInitStatementGetter = (id, forNonHyperlinkElement) => {
                    var actionStatements = isPostBackHyperlink.Value ? postBackAction.GetJsStatements() :
                                           hasDestination && actionStatementGetter != null?actionStatementGetter(Url.Value) :
                                               hasDestination && forNonHyperlinkElement ? !target.Any()
                                                                                                                  ? "window.location.href = '{0}';".FormatWith(Url.Value)
                                                                                                                  :
                                               target == "_parent"
                                                                                                                          ?
                                               "window.parent.location.href = '{0}';".FormatWith(Url.Value)
                                                                                                                          : "window.open( '{0}', '{1}' );".FormatWith(Url.Value, target) : "";

                    return(actionStatements.Any() ? getActionInitStatements(id, forNonHyperlinkElement, actionStatements) : "");
                };
            }

            IsFocusable = hasDestination;

            PostBackAdder = () => {
                if (!isPostBackHyperlink.Value)
                {
                    return;
                }
                var postBackId = PostBack.GetCompositeId("hyperlink", destination.GetUrl(), disableAuthorizationCheck.ToString());
                postBackAction = new PostBackFormAction(
                    PageBase.Current.GetPostBack(postBackId) ?? PostBack.CreateFull(
                        id: postBackId,
                        actionGetter: () => new PostBackAction(destination, authorizationCheckDisabledPredicate: effectiveDestination => disableAuthorizationCheck)));
                postBackAction.AddToPageIfNecessary();
            };
        }
Example #8
0
        void ControlTreeDataLoader.LoadData()
        {
            var isTextarea = rows > 1;

            textBox    = new WebControl(isTextarea ? HtmlTextWriterTag.Textarea : HtmlTextWriterTag.Input);
            PreRender += delegate {
                if (!isTextarea)
                {
                    textBox.Attributes.Add("type", masksCharacters ? "password" : "text");
                }
                textBox.Attributes.Add("name", UniqueID);
                if (isTextarea)
                {
                    textBox.Attributes.Add("rows", rows.ToString());
                }
                if (maxLength.HasValue)
                {
                    textBox.Attributes.Add("maxlength", maxLength.Value.ToString());
                }
                if (readOnly)
                {
                    textBox.Attributes.Add("readonly", "readonly");
                }
                if (disableBrowserAutoComplete || autoCompleteService != null)
                {
                    textBox.Attributes.Add("autocomplete", "off");
                }
                if (suggestSpellCheck.HasValue)
                {
                    textBox.Attributes.Add("spellcheck", suggestSpellCheck.Value.ToString().ToLower());
                }

                var value            = formValue.GetValue(AppRequestState.Instance.EwfPageRequestState.PostBackValues);
                var valueOrWatermark = watermarkText.Any() && !value.Any() ? watermarkText : value;
                if (isTextarea)
                {
                    textBox.Controls.Add(new Literal {
                        Text = HttpUtility.HtmlEncode(GetTextareaValue(valueOrWatermark))
                    });
                }
                else if (!masksCharacters)
                {
                    textBox.Attributes.Add("value", valueOrWatermark);
                }
            };
            Controls.Add(textBox);

            if (watermarkText.Any())
            {
                textBox.AddJavaScriptEventScript(JsWritingMethods.onfocus, "if( value == '" + watermarkText + "' ) value = ''");
                textBox.AddJavaScriptEventScript(JsWritingMethods.onblur, "if( value == '' ) value = '" + watermarkText + "'");
                EwfPage.Instance.ClientScript.RegisterOnSubmitStatement(
                    GetType(),
                    UniqueID + "watermark",
                    "$( '#" + textBox.ClientID + "' ).filter( function() { return this.value == '" + watermarkText + "'; } ).val( '' )");
            }

            if (!isTextarea || autoPostBack || (autoCompleteService != null && autoCompleteOption != AutoCompleteOption.NoPostBack))
            {
                action.AddToPageIfNecessary();
            }
            if (!isTextarea)
            {
                PreRender +=
                    delegate {
                    SubmitButton.EnsureImplicitSubmissionAction(
                        this,
                        action,
                        autoPostBack || (autoCompleteService != null && autoCompleteOption == AutoCompleteOption.PostBackOnTextChangeAndItemSelect));
                }
            }
            ;

            if (autoPostBack || (autoCompleteService != null && autoCompleteOption == AutoCompleteOption.PostBackOnTextChangeAndItemSelect))
            {
                PreRender += delegate {
                    // Use setTimeout to prevent keypress and change from *both* triggering post-backs at the same time when Enter is pressed after a text change.
                    textBox.AddJavaScriptEventScript(JsWritingMethods.onchange, "setTimeout( function() { " + action.GetJsStatements() + " }, 0 )");
                }
            }
            ;

            if (ToolTip != null || ToolTipControl != null)
            {
                new ToolTip(ToolTipControl ?? EnterpriseWebFramework.Controls.ToolTip.GetToolTipTextControl(ToolTip), textBox);
            }
        }

        string ControlWithJsInitLogic.GetJsInitStatements()
        {
            var script = new StringBuilder();

            if (watermarkText.Any())
            {
                var restorationStatement = "$( '#" + textBox.ClientID + "' ).filter( function() { return this.value == ''; } ).val( '" + watermarkText + "' );";

                // The first line is for bfcache browsers; the second is for all others. See http://stackoverflow.com/q/1195440/35349.
                script.Append("$( window ).on( 'pagehide', function() { " + restorationStatement + " } );");
                script.Append(restorationStatement);
            }

            if (autoCompleteService != null)
            {
                const int delay         = 250;         // Default delay is 300 ms.
                const int minCharacters = 3;

                var autocompleteOptions = new List <Tuple <string, string> >();
                autocompleteOptions.Add(Tuple.Create("delay", delay.ToString()));
                autocompleteOptions.Add(Tuple.Create("minLength", minCharacters.ToString()));
                autocompleteOptions.Add(Tuple.Create("source", "'" + autoCompleteService.GetUrl() + "'"));

                if (autoCompleteOption != AutoCompleteOption.NoPostBack)
                {
                    var handler = "function( event, ui ) {{ $( '#{0}' ).val( ui.item.value ); {1} return false; }}".FormatWith(textBox.ClientID, action.GetJsStatements());
                    autocompleteOptions.Add(Tuple.Create("select", handler));
                }

                script.Append(
                    @"$( '#" + textBox.ClientID +
                    "' ).autocomplete( {{ {0} }} );".FormatWith(
                        autocompleteOptions.Select(o => "{0}: {1}".FormatWith(o.Item1, o.Item2)).GetCommaDelimitedStringFromCollection()));
            }

            return(script.ToString());
        }

        FormValue FormValueControl.FormValue {
            get { return(formValue); }
        }
Example #9
0
        internal HyperlinkBehavior(ResourceInfo destination, string target)
        {
            this.destination = destination;
            Classes          = destination?.AlternativeMode is NewContentResourceMode ? ActionComponentCssElementCreator.NewContentClass : ElementClassSet.Empty;

            Url = destination != null?destination.GetUrl(true, false, true) : "";

            var isPostBackHyperlink = destination != null && !(destination.AlternativeMode is DisabledResourceMode) && !target.Any() &&
                                      EwfPage.Instance.IsAutoDataUpdater;
            FormAction postBackAction = null;

            AttributeGetter =
                () =>
                (Url.Any() ? Tuple.Create("href", Url).ToCollection() : Enumerable.Empty <Tuple <string, string> >()).Concat(
                    target.Any() ? Tuple.Create("target", target).ToCollection() : Enumerable.Empty <Tuple <string, string> >())
                .Concat(
                    isPostBackHyperlink
                                                        ? Tuple.Create(JsWritingMethods.onclick, postBackAction.GetJsStatements() + " return false").ToCollection()
                                                        : Enumerable.Empty <Tuple <string, string> >())
                .ToImmutableArray();

            var disabledResourceMode = destination?.AlternativeMode as DisabledResourceMode;

            if (disabledResourceMode != null)
            {
                IncludeIdAttribute = true;
                Func <string, string> toolTipInitStatementGetter;
                EtherealChildren =
                    new ToolTip(
                        (disabledResourceMode.Message.Any() ? disabledResourceMode.Message : Translation.ThePageYouRequestedIsDisabled).ToComponents(),
                        out toolTipInitStatementGetter).ToCollection();
                JsInitStatementGetter = id => "$( '#{0}' ).click( function( e ) {{ e.preventDefault(); }} );".FormatWith(id) + toolTipInitStatementGetter(id);
            }
            else
            {
                EtherealChildren      = ImmutableArray <EtherealComponent> .Empty;
                JsInitStatementGetter = id => "";
            }

            if (isPostBackHyperlink)
            {
                PostBackAdder = () => {
                    postBackAction = GetHyperlinkPostBackAction(destination);
                    postBackAction.AddToPageIfNecessary();
                }
            }
            ;
            else
            {
                PostBackAdder = () => { }
            };
        }
Example #10
0
        /// <summary>
        /// Ensures that the specified control will trigger the specified action when the enter key is pressed while the control has focus. If you specify the
        /// submit-button post-back, this method relies on HTML's built-in implicit submission behavior, which will simulate a click on the submit button.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="action">Do not pass null.</param>
        /// <param name="forceJsHandling"></param>
        /// <param name="predicate"></param>
        internal static void EnsureImplicitSubmissionAction(WebControl control, FormAction action, bool forceJsHandling, string predicate = "")
        {
            var postBackAction = action as PostBackFormAction;

            // EWF does not allow form controls to use HTML's built-in implicit submission on a page with no submit button. There are two reasons for this. First, the
            // behavior of HTML's implicit submission appears to be somewhat arbitrary when there is no submit button; see
            // https://html.spec.whatwg.org/multipage/forms.html#implicit-submission. Second, we don't want the implicit submission behavior of form controls to
            // unpredictably change if a submit button is added or removed.
            if (postBackAction == null || postBackAction.PostBack != EwfPage.Instance.SubmitButtonPostBack || forceJsHandling)
            {
                control.AddJavaScriptEventScript(
                    JsWritingMethods.onkeypress,
                    "if( event.which == 13 " + predicate.PrependDelimiter(" && ") + " ) { " + action.GetJsStatements() + " return false; }");
            }
        }
        void ControlTreeDataLoader.LoadData()
        {
            FormState.ExecuteWithDataModificationsAndDefaultAction(
                dataModifications,
                () => {
                if (TagKey == HtmlTextWriterTag.Button)
                {
                    Attributes.Add("name", EwfPage.ButtonElementName);
                    Attributes.Add("value", "v");
                    Attributes.Add("type", usesSubmitBehavior ? "submit" : "button");
                }

                FormAction action = postBackAction;
                action.AddToPageIfNecessary();

                if (ConfirmationWindowContentControl != null)
                {
                    if (usesSubmitBehavior)
                    {
                        throw new ApplicationException("PostBackButton cannot be the submit button and also have a confirmation message.");
                    }
                    confirmationWindow = new ModalWindow(this, ConfirmationWindowContentControl, title: "Confirmation", postBack: postBackAction.PostBack);
                }
                else if (!usesSubmitBehavior)
                {
                    PreRender += delegate { this.AddJavaScriptEventScript(JsWritingMethods.onclick, action.GetJsStatements() + " return false"); }
                }
                ;

                CssClass = CssClass.ConcatenateWithSpace("ewfClickable");
                ActionControlStyle.SetUpControl(this, "");
            });
        }