/// <summary> /// Creates a setup object for a read-only text control. /// </summary> /// <param name="displaySetup"></param> /// <param name="widthOverride">The width of the control. This overrides any value that may be specified via CSS. If no width is specified via CSS and you /// pass null for this parameter, the width will be based on the maximum number of characters a user can input.</param> /// <param name="numberOfRows">The number of lines in the text control. Must be one or more.</param> /// <param name="classes">The classes on the control.</param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public static TextControlSetup CreateReadOnly( DisplaySetup displaySetup = null, ContentBasedLength widthOverride = null, int numberOfRows = 1, ElementClassSet classes = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new TextControlSetup( displaySetup, numberOfRows == 1 ? "text" : "", widthOverride, numberOfRows, true, classes, false, false, "", "", null, null, null, null, null, null, null, validationPredicate, validationErrorNotifier)); }
/// <summary> /// Creates a setup object for a numeric-text control with auto-complete behavior. /// </summary> /// <param name="autoCompleteResource">The resource containing the auto-complete items. Do not pass null.</param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the control.</param> /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param> /// <param name="autoFillTokens">A list of auto-fill detail tokens (see /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param> /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param> /// <param name="triggersActionWhenItemSelected">Pass true to also trigger the action when the user selects an auto-complete item.</param> /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param> /// <param name="pageModificationValue"></param> /// <param name="numericPageModificationValue"></param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public static NumericTextControlSetup CreateAutoComplete( ResourceInfo autoCompleteResource, DisplaySetup displaySetup = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "", SpecifiedValue <FormAction> action = null, bool triggersActionWhenItemSelected = false, FormAction valueChangedAction = null, PageModificationValue <string> pageModificationValue = null, PageModificationValue <long?> numericPageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new NumericTextControlSetup( new TextControlSetup( displaySetup, "text", null, null, false, classes, false, true, placeholder, autoFillTokens, autoCompleteResource, null, action, triggersActionWhenItemSelected, valueChangedAction, pageModificationValue, numericPageModificationValue, validationPredicate, validationErrorNotifier), validationErrorNotifier)); }
/// <summary> /// Creates a button. /// </summary> /// <param name="style">The style.</param> /// <param name="displaySetup"></param> /// <param name="behavior">The behavior. Pass null to use the form default action. If you need to add additional JavaScript action statements to any /// behavior besides <see cref="CustomButtonBehavior"/>, we recommend using the jQuery document ready event to add an additional click handler to the /// appropriate button element(s), which you can select using a class if there is no simpler way.</param> /// <param name="classes">The classes on the button.</param> public EwfButton(ButtonStyle style, DisplaySetup displaySetup = null, ButtonBehavior behavior = null, ElementClassSet classes = null) { behavior = behavior ?? new FormActionBehavior(FormState.Current.DefaultAction); var elementChildren = style.GetChildren(); var elementEtherealChildren = behavior.GetEtherealChildren(); children = new DisplayableElement( context => { behavior.AddPostBack(); return(new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData( "button", new FocusabilityCondition(true), isFocused => { var attributes = new List <Tuple <string, string> > { Tuple.Create("type", "button") }; attributes.AddRange(behavior.GetAttributes()); if (isFocused) { attributes.Add(Tuple.Create("autofocus", "autofocus")); } return new DisplayableElementFocusDependentData( attributes: attributes, includeIdAttribute: behavior.IncludesIdAttribute(), jsInitStatements: behavior.GetJsInitStatements(context.Id) + style.GetJsInitStatements(context.Id)); }), classes: style.GetClasses().Add(classes ?? ElementClassSet.Empty), children: elementChildren, etherealChildren: elementEtherealChildren)); }).ToCollection(); }
/// <summary> /// Creates an image setup object. /// </summary> /// <param name="alternativeText">The alternative text for the image; see https://html.spec.whatwg.org/multipage/embedded-content.html#alt. Pass null (which /// omits the alt attribute) or the empty string only when the specification allows.</param> /// <param name="displaySetup"></param> /// <param name="sizesToAvailableWidth">Whether the image sizes itself to fit all available width.</param> /// <param name="classes">The classes on the image.</param> public ImageSetup(string alternativeText, DisplaySetup displaySetup = null, bool sizesToAvailableWidth = false, ElementClassSet classes = null) { ComponentGetter = (srcGetter, srcsetGetter) => { return(new DisplayableElement( context => new DisplayableElementData( displaySetup, () => { var attributes = new List <ElementAttribute>(); attributes.Add(new ElementAttribute("src", srcGetter())); var srcset = srcsetGetter(); if (srcset.Any()) { attributes.Add(new ElementAttribute("srcset", srcset)); } if (alternativeText != null) { attributes.Add(new ElementAttribute("alt", alternativeText)); } return new DisplayableElementLocalData("img", focusDependentData: new DisplayableElementFocusDependentData(attributes: attributes)); }, classes: CssElementCreator.Class.Add(sizesToAvailableWidth ? new ElementClass("ewfAutoSizer") : ElementClassSet.Empty) .Add(classes ?? ElementClassSet.Empty))).ToCollection()); }; }
/// <summary> /// Creates a side-comments (i.e. small) element. /// </summary> /// <param name="content"></param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the element.</param> public SideComments(IEnumerable <PhrasingComponent> content, DisplaySetup displaySetup = null, ElementClassSet classes = null) { children = new DisplayableElement( context => new DisplayableElementData(displaySetup, () => new DisplayableElementLocalData("small"), classes: classes, children: content)).ToCollection (); }
/// <summary> /// Creates a setup object for an obscured (i.e. password) text control. /// </summary> /// <param name="displaySetup"></param> /// <param name="widthOverride">The width of the control. This overrides any value that may be specified via CSS. If no width is specified via CSS and you /// pass null for this parameter, the width will be based on the maximum number of characters a user can input.</param> /// <param name="classes">The classes on the control.</param> /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param> /// <param name="autoFillTokens">A list of auto-fill detail tokens (see /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param> /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param> /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param> /// <param name="pageModificationValue"></param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> /// <returns></returns> public static TextControlSetup CreateObscured( DisplaySetup displaySetup = null, ContentBasedLength widthOverride = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "", SpecifiedValue <FormAction> action = null, FormAction valueChangedAction = null, PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new TextControlSetup( displaySetup, "password", widthOverride, null, false, classes, true, false, placeholder, autoFillTokens, null, null, action, null, valueChangedAction, pageModificationValue, null, validationPredicate, validationErrorNotifier)); }
/// <summary> /// Creates a hyperlink. /// </summary> /// <param name="behavior">The behavior. Pass a <see cref="ResourceInfo"/> to navigate to the resource in the default way, or call /// <see cref="HyperlinkBehaviorExtensionCreators.ToHyperlinkNewTabBehavior(ResourceInfo, bool)"/> or /// <see cref="HyperlinkBehaviorExtensionCreators.ToHyperlinkModalBoxBehavior(ResourceInfo, bool, BrowsingContextSetup)"/>. For a mailto link, call /// <see cref="HyperlinkBehaviorExtensionCreators.ToHyperlinkBehavior(Email.EmailAddress, string, string, string, string)"/>. If you need to add additional /// JavaScript action statements to any behavior, we recommend using the jQuery document ready event to add a click handler to the appropriate a element(s), /// which you can select using a class if there is no simpler way.</param> /// <param name="style">The style.</param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the hyperlink.</param> public EwfHyperlink(HyperlinkBehavior behavior, HyperlinkStyle style, DisplaySetup displaySetup = null, ElementClassSet classes = null) { children = new DisplayableElement( context => { behavior.PostBackAdder(); return(new DisplayableElementData( displaySetup, () => { DisplayableElementFocusDependentData getFocusDependentData(bool isFocused) => new DisplayableElementFocusDependentData( attributes: behavior.AttributeGetter(false), includeIdAttribute: behavior.IncludesIdAttribute(false) || isFocused, jsInitStatements: StringTools.ConcatenateWithDelimiter( " ", behavior.JsInitStatementGetter(context.Id, false), style.GetJsInitStatements(context.Id), isFocused ? "document.getElementById( '{0}' ).focus();".FormatWith(context.Id) : "")); return behavior.IsFocusable ? new DisplayableElementLocalData("a", new FocusabilityCondition(true), getFocusDependentData) : new DisplayableElementLocalData("a", focusDependentData: getFocusDependentData(false)); }, classes: behavior.Classes.Add(style.GetClasses()).Add(classes ?? ElementClassSet.Empty), children: style.GetChildren(behavior.Url.Value), etherealChildren: behavior.EtherealChildren)); }).ToCollection(); }
/// <summary> /// Creates a setup object for a standard text control. /// </summary> /// <param name="displaySetup"></param> /// <param name="widthOverride">The width of the control. This overrides any value that may be specified via CSS. If no width is specified via CSS and you /// pass null for this parameter, the width will be based on the maximum number of characters a user can input.</param> /// <param name="numberOfRows">The number of lines in the text control. Must be one or more.</param> /// <param name="classes">The classes on the control.</param> /// <param name="disableTrimming">Pass true to disable white-space trimming.</param> /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param> /// <param name="autoFillTokens">A list of auto-fill detail tokens (see /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param> /// <param name="checksSpellingAndGrammar">Pass true to enable spelling and grammar checking, false to disable it, and null for default behavior.</param> /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action. Currently has no /// effect for multiline controls.</param> /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param> /// <param name="pageModificationValue"></param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public static TextControlSetup Create( DisplaySetup displaySetup = null, ContentBasedLength widthOverride = null, int numberOfRows = 1, ElementClassSet classes = null, bool disableTrimming = false, string placeholder = "", string autoFillTokens = "", bool?checksSpellingAndGrammar = null, SpecifiedValue <FormAction> action = null, FormAction valueChangedAction = null, PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new TextControlSetup( displaySetup, numberOfRows == 1 ? "text" : "", widthOverride, numberOfRows, false, classes, disableTrimming, false, placeholder, autoFillTokens, null, checksSpellingAndGrammar, action, null, valueChangedAction, pageModificationValue, null, validationPredicate, validationErrorNotifier)); }
/// <summary> /// Creates a submit button. /// </summary> /// <param name="style">The style.</param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the button.</param> /// <param name="postBack">Pass null to use the post-back corresponding to the first of the current data modifications.</param> public SubmitButton(ButtonStyle style, DisplaySetup displaySetup = null, ElementClassSet classes = null, PostBack postBack = null) { var elementChildren = style.GetChildren(); var postBackAction = new PostBackFormAction(postBack ?? FormState.Current.PostBack); children = new DisplayableElement( context => { FormAction action = postBackAction; action.AddToPageIfNecessary(); if (EwfPage.Instance.SubmitButtonPostBack != null) { throw new ApplicationException("A submit button already exists on the page."); } EwfPage.Instance.SubmitButtonPostBack = postBackAction.PostBack; return(new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData( "button", attributes: new[] { Tuple.Create("name", EwfPage.ButtonElementName), Tuple.Create("value", "v") }, jsInitStatements: style.GetJsInitStatements(context.Id)), classes: style.GetClasses().Add(classes ?? ElementClassSet.Empty), children: elementChildren)); }).ToCollection(); }
/// <summary> /// Creates a setup object for a read-only numeric-text control. /// </summary> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the control.</param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public static NumericTextControlSetup CreateReadOnly( DisplaySetup displaySetup = null, ElementClassSet classes = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new NumericTextControlSetup( new TextControlSetup( displaySetup, "text", null, null, true, classes, false, true, "", "", null, null, null, null, null, null, null, validationPredicate, validationErrorNotifier), validationErrorNotifier)); }
/// <summary> /// Creates a setup object for a standard URL control. /// </summary> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the control.</param> /// <param name="placeholder">The hint word or phrase that will appear when the control has an empty value. Do not pass null.</param> /// <param name="autoFillTokens">A list of auto-fill detail tokens (see /// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens), or "off" to instruct the browser to disable auto-fill /// (see https://stackoverflow.com/a/23234498/35349 for an explanation of why this could be ignored). Do not pass null.</param> /// <param name="action">The action that will occur when the user hits Enter on the control. Pass null to use the current default action.</param> /// <param name="valueChangedAction">The action that will occur when the value is changed. Pass null for no action.</param> /// <param name="pageModificationValue"></param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public static UrlControlSetup Create( DisplaySetup displaySetup = null, ElementClassSet classes = null, string placeholder = "", string autoFillTokens = "", SpecifiedValue <FormAction> action = null, FormAction valueChangedAction = null, PageModificationValue <string> pageModificationValue = null, Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { return(new UrlControlSetup( new TextControlSetup( displaySetup, "url", null, null, false, classes, false, false, placeholder, autoFillTokens, null, null, action, null, valueChangedAction, pageModificationValue, null, validationPredicate, validationErrorNotifier))); }
/// <summary> /// Creates a form item setup object. /// </summary> /// <param name="displaySetup"></param> /// <param name="columnSpan">Only applies to <see cref="FormItemList.CreateGrid"/>.</param> /// <param name="updateRegionSets">The intermediate-post-back update-region sets that the form item will be a part of.</param> /// <param name="textAlignment"></param> public FormItemSetup( DisplaySetup displaySetup = null, int?columnSpan = null, IEnumerable <UpdateRegionSet> updateRegionSets = null, TextAlignment textAlignment = TextAlignment.NotSpecified) { DisplaySetup = displaySetup; ColumnSpan = columnSpan; UpdateRegionSets = updateRegionSets; TextAlignment = textAlignment; }
/// <summary> /// Creates a component-list setup object. /// </summary> /// <param name="displaySetup"></param> /// <param name="isOrdered">Pass true if the list items have been intentionally ordered, such that changing the order would change the meaning of the page.</param> /// <param name="classes">The classes on the list.</param> /// <param name="lastItemAutofocusCondition">Pass a value to wrap the last list item in an autofocus region with the specified condition.</param> /// <param name="tailUpdateRegions">The tail update regions.</param> /// <param name="itemInsertionUpdateRegions"></param> /// <param name="etherealContent"></param> public ComponentListSetup( DisplaySetup displaySetup = null, bool isOrdered = false, ElementClassSet classes = null, AutofocusCondition lastItemAutofocusCondition = null, IEnumerable <TailUpdateRegion> tailUpdateRegions = null, IEnumerable <ItemInsertionUpdateRegion> itemInsertionUpdateRegions = null, IReadOnlyCollection <EtherealComponent> etherealContent = null) { componentGetter = (listTypeClasses, items) => { items = items.ToImmutableArray(); var itemComponents = items.Select(i => i.Item2).ToImmutableArray(); var itemComponentsById = items.Where(i => i.Item1.Id.Any()).ToDictionary(i => i.Item1.Id, i => i.Item2); return(new IdentifiedFlowComponent( () => new IdentifiedComponentData <FlowComponentOrNode>( "", new[] { new UpdateRegionLinker( "tail", from region in tailUpdateRegions ?? ImmutableArray <TailUpdateRegion> .Empty let staticItemCount = items.Count() - region.UpdatingItemCount select new PreModificationUpdateRegion(region.Sets, () => itemComponents.Skip(staticItemCount), staticItemCount.ToString), arg => itemComponents.Skip(int.Parse(arg))), new UpdateRegionLinker( "add", from region in itemInsertionUpdateRegions ?? ImmutableArray <ItemInsertionUpdateRegion> .Empty select new PreModificationUpdateRegion( region.Sets, () => ImmutableArray <PageComponent> .Empty, () => StringTools.ConcatenateWithDelimiter(",", region.NewItemIdGetter().ToArray())), arg => arg.Separate(",", false).Where(itemComponentsById.ContainsKey).Select(i => itemComponentsById[i])), new UpdateRegionLinker( "remove", items.Select( (item, index) => new PreModificationUpdateRegion( item.Item1.RemovalUpdateRegionSets, () => itemComponents.ElementAt(index).ToCollection(), () => "")), arg => ImmutableArray <PageComponent> .Empty) }, new ErrorSourceSet(), errorsBySource => new DisplayableElement( context => { return new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData(isOrdered ? "ol" : "ul"), classes: CssElementCreator.AllListsClass.Add(listTypeClasses).Add(classes ?? ElementClassSet.Empty), children: itemComponents.Select( (component, index) => index == itemComponents.Length - 1 && lastItemAutofocusCondition != null ? new FlowAutofocusRegion( lastItemAutofocusCondition, new CustomFlowComponent(component.ToCollection()).ToCollection()) : component) .Materialize(), etherealChildren: etherealContent); }).ToCollection())).ToCollection()); }; }
/// <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 an HTML editor setup object. /// </summary> /// <param name="displaySetup"></param> /// <param name="isReadOnly">Pass true to prevent the contents of the HTML editor from being changed.</param> /// <param name="ckEditorConfiguration">A comma-separated list of CKEditor configuration options ("toolbar: [ [ 'Bold', 'Italic' ] ]", etc.). Use this to /// customize the underlying CKEditor. Do not pass null.</param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> public WysiwygHtmlEditorSetup( DisplaySetup displaySetup = null, bool isReadOnly = false, string ckEditorConfiguration = "", Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null) { DisplaySetup = displaySetup; IsReadOnly = isReadOnly; CkEditorConfiguration = ckEditorConfiguration; ValidationPredicate = validationPredicate; ValidationErrorNotifier = validationErrorNotifier; }
/// <summary> /// Creates a list item containing components that represent this string. The string must not be null. /// </summary> /// <param name="text"></param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the item.</param> /// <param name="visualOrderRank"></param> /// <param name="updateRegionSets">The intermediate-post-back update-region sets that this item will be a part of.</param> /// <param name="etherealContent"></param> public static ComponentListItem ToComponentListItem( this string text, DisplaySetup displaySetup = null, ElementClassSet classes = null, int?visualOrderRank = null, IEnumerable <UpdateRegionSet> updateRegionSets = null, IReadOnlyCollection <EtherealComponent> etherealContent = null) => text.ToComponents() .ToComponentListItem( displaySetup: displaySetup, classes: classes, visualOrderRank: visualOrderRank, updateRegionSets: updateRegionSets, etherealContent: etherealContent);
/// <summary> /// Creates an HTML block container. Do not pass null for HTML. This overload is useful when you've already loaded the HTML. /// </summary> /// <param name="html"></param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the container.</param> public HtmlBlockContainer(string html, DisplaySetup displaySetup = null, ElementClassSet classes = null) { this.html = html; children = new DisplayableElement( context => new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData("div"), classes: elementClass.Add(classes ?? ElementClassSet.Empty), children: new TrustedHtmlString(html).ToComponent().ToCollection())).ToCollection(); }
/// <summary> /// Creates a list item containing these components. /// </summary> /// <param name="children"></param> /// <param name="id">The ID of the item. This is required if you're adding the item on an intermediate post-back or want to remove the item on an /// intermediate post-back. Do not pass null or the empty string.</param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the item.</param> /// <param name="visualOrderRank"></param> /// <param name="updateRegionSets">The intermediate-post-back update-region sets that this item will be a part of.</param> /// <param name="removalUpdateRegionSets">The intermediate-post-back update-region sets that this item's removal will be a part of.</param> /// <param name="etherealChildren"></param> public static ComponentListItem ToComponentListItem( this IEnumerable <FlowComponentOrNode> children, string id, DisplaySetup displaySetup = null, ElementClassSet classes = null, int?visualOrderRank = null, IEnumerable <UpdateRegionSet> updateRegionSets = null, IEnumerable <UpdateRegionSet> removalUpdateRegionSets = null, IEnumerable <EtherealComponentOrElement> etherealChildren = null) { return(new ComponentListItem( (includeContentContainer, itemTypeClasses, width) => { FlowComponentOrNode component = null; component = new IdentifiedFlowComponent( () => new IdentifiedComponentData <FlowComponentOrNode>( id, new UpdateRegionLinker( "", new PreModificationUpdateRegion(updateRegionSets, component.ToCollection, () => "").ToCollection(), arg => component.ToCollection()).ToCollection(), ImmutableArray <EwfValidation> .Empty, errorsByValidation => new DisplayableElement( context => { var attributes = new List <Tuple <string, string> >(); if (visualOrderRank.HasValue || width != null) { attributes.Add( Tuple.Create( "style", StringTools.ConcatenateWithDelimiter( ", ", visualOrderRank.HasValue ? "order: {0}".FormatWith(visualOrderRank.Value) : "", width != null ? "width: {0}".FormatWith(width.Value) : ""))); } return new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData("li", attributes: attributes), classes: CssElementCreator.ItemClass.Add(itemTypeClasses).Add(classes ?? ElementClassSet.Empty), children: includeContentContainer ? new DisplayableElement( innerContext => new DisplayableElementData( null, () => new DisplayableElementLocalData("div"), classes: CssElementCreator.ItemClass, children: children, etherealChildren: etherealChildren)).ToCollection() : children, etherealChildren: includeContentContainer ? null : etherealChildren); }).ToCollection())); return component; }, id, removalUpdateRegionSets)); }
private FlowRadioButtonSetup( DisplaySetup displaySetup, ElementClassSet classes, RadioButtonSetup radioButtonSetup, bool highlightedWhenSelected, Func <IReadOnlyCollection <FlowComponent> > nestedContentGetter, bool nestedContentAlwaysDisplayed) { DisplaySetup = displaySetup; Classes = classes; RadioButtonSetup = radioButtonSetup; HighlightedWhenSelected = highlightedWhenSelected; NestedContentGetter = nestedContentGetter; NestedContentAlwaysDisplayed = nestedContentAlwaysDisplayed; }
private FlowCheckboxSetup( DisplaySetup displaySetup, ElementClassSet classes, CheckboxSetup checkboxSetup, bool highlightedWhenChecked, Func <IReadOnlyCollection <FlowComponent> > nestedContentGetter, bool nestedContentAlwaysDisplayed) { DisplaySetup = displaySetup; Classes = classes; CheckboxSetup = checkboxSetup; HighlightedWhenChecked = highlightedWhenChecked; NestedContentGetter = nestedContentGetter; NestedContentAlwaysDisplayed = nestedContentAlwaysDisplayed; }
/// <summary> /// Creates a section. /// </summary> /// <param name="content">The section's content.</param> /// <param name="displaySetup"></param> /// <param name="style">The section's style.</param> /// <param name="classes">The classes on the section.</param> /// <param name="etherealContent"></param> public Section( IReadOnlyCollection <FlowComponent> content, DisplaySetup displaySetup = null, SectionStyle style = SectionStyle.Normal, ElementClassSet classes = null, IReadOnlyCollection <EtherealComponent> etherealContent = null) : this( "", content, displaySetup : displaySetup, style : style, classes : classes, etherealContent : etherealContent) { }
/// <summary> /// Creates a displayable-element-data object. /// </summary> public DisplayableElementData( DisplaySetup displaySetup, Func <DisplayableElementLocalData> localDataGetter, ElementClassSet classes = null, IEnumerable <FlowComponentOrNode> children = null, IEnumerable <EtherealComponentOrElement> etherealChildren = null) { displaySetup = displaySetup ?? new DisplaySetup(true); BaseDataGetter = context => { displaySetup.AddJsShowStatements("$( '#{0}' ).show( 200 );".FormatWith(context.Id)); displaySetup.AddJsHideStatements("$( '#{0}' ).hide( 200 );".FormatWith(context.Id)); return(new ElementData(() => localDataGetter().BaseDataGetter(displaySetup), classes: classes, children: children, etherealChildren: etherealChildren)); }; }
/// <summary> /// Creates a file collection manager. /// </summary> /// <param name="fileCollectionId"></param> /// <param name="displaySetup"></param> /// <param name="postBackIdBase">Do not pass null.</param> /// <param name="sortByName"></param> /// <param name="thumbnailResourceGetter">A function that takes a file ID and returns the corresponding thumbnail resource. Do not return null.</param> /// <param name="openedFileIds">The file IDs that should not be marked with a UI element drawing the user’s attention to the fact that they haven’t read it. /// All other files not in this collection will be marked. The collection can be null, and will result as nothing being shown as new.</param> /// <param name="unopenedFileOpenedNotifier">A method that executes when an unopened file is opened. Use to update the app’s database with an indication /// that the file has been seen by the user.</param> /// <param name="disableModifications">Pass true if there should be no way to upload or delete files.</param> /// <param name="uploadValidationMethod"></param> /// <param name="fileCreatedOrReplacedNotifier">A method that executes after a file is created or replaced.</param> /// <param name="filesDeletedNotifier">A method that executes after one or more files are deleted.</param> public BlobFileCollectionManager( int fileCollectionId, DisplaySetup displaySetup = null, string postBackIdBase = "", bool sortByName = false, Func <int, ResourceInfo> thumbnailResourceGetter = null, IEnumerable <int> openedFileIds = null, MarkFileAsReadMethod unopenedFileOpenedNotifier = null, bool disableModifications = false, Action <RsFile, Validator> uploadValidationMethod = null, NewFileNotificationMethod fileCreatedOrReplacedNotifier = null, Action filesDeletedNotifier = null) { postBackIdBase = PostBack.GetCompositeId("ewfFileCollection", postBackIdBase); var columnSetups = new List <EwfTableField>(); if (thumbnailResourceGetter != null) { columnSetups.Add(new EwfTableField(size: 10.ToPercentage())); } columnSetups.Add(new EwfTableField(classes: new ElementClass("ewfOverflowedCell"))); columnSetups.Add(new EwfTableField(size: 13.ToPercentage())); columnSetups.Add(new EwfTableField(size: 7.ToPercentage())); var table = EwfTable.Create( postBackIdBase: postBackIdBase, caption: "Files", selectedItemActions: disableModifications ? null : SelectedItemAction.CreateWithFullPostBackBehavior <int>( "Delete Selected Files", ids => { foreach (var i in ids) { BlobStorageStatics.SystemProvider.DeleteFile(i); } filesDeletedNotifier?.Invoke(); EwfPage.AddStatusMessage(StatusMessageType.Info, "Selected files deleted successfully."); }) .ToCollection(), fields: columnSetups); IReadOnlyCollection <BlobFile> files = BlobStorageStatics.SystemProvider.GetFilesLinkedToFileCollection(fileCollectionId); files = (sortByName ? files.OrderByName() : files.OrderByUploadedDateDescending()).Materialize(); foreach (var file in files) { addFileRow(postBackIdBase, thumbnailResourceGetter, openedFileIds, unopenedFileOpenedNotifier, table, file); } children = files.Any() || !disableModifications ? table.Concat( !disableModifications ?getUploadComponents( fileCollectionId, files, displaySetup, postBackIdBase, uploadValidationMethod, fileCreatedOrReplacedNotifier ) : Enumerable.Empty <FlowComponent>()) .Materialize() : Enumerable.Empty <FlowComponent>().Materialize(); }
/// <summary> /// Creates a setup object for a BLOB file manager. /// </summary> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the element.</param> /// <param name="thumbnailResourceGetter">A function that takes a file ID and returns the corresponding thumbnail resource. Do not return null.</param> /// <param name="omitNoExistingFileMessage">Pass true if you do not want to show “No existing file” when there is no file in the database.</param> /// <param name="uploadValidationPredicate"></param> /// <param name="uploadValidationErrorNotifier"></param> /// <param name="uploadValidationMethod"></param> public static BlobFileManagerSetup Create( DisplaySetup displaySetup = null, ElementClassSet classes = null, Func <int, ResourceInfo> thumbnailResourceGetter = null, bool omitNoExistingFileMessage = false, Func <bool, bool> uploadValidationPredicate = null, Action uploadValidationErrorNotifier = null, Action <RsFile, Validator> uploadValidationMethod = null) => new BlobFileManagerSetup( displaySetup, classes, thumbnailResourceGetter, omitNoExistingFileMessage, uploadValidationPredicate, uploadValidationErrorNotifier, uploadValidationMethod);
/// <summary> /// Creates a figure. /// </summary> /// <param name="content"></param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the figure.</param> /// <param name="caption">The caption.</param> public EwfFigure( IReadOnlyCollection <FlowComponent> content, DisplaySetup displaySetup = null, ElementClassSet classes = null, FigureCaption caption = null) { children = new DisplayableElement( context => new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData("figure"), classes: CssElementCreator.Class.Add(classes ?? ElementClassSet.Empty), children: caption != null ? caption.FigureIsTextual ? caption.Components.Concat(content).Materialize() : content.Concat(caption.Components).Materialize() : content)).ToCollection(); }
internal BlobFileManagerSetup( DisplaySetup displaySetup, ElementClassSet classes, Func <int, ResourceInfo> thumbnailResourceGetter, bool omitNoExistingFileMessage, Func <bool, bool> uploadValidationPredicate, Action uploadValidationErrorNotifier, Action <RsFile, Validator> uploadValidationMethod) { DisplaySetup = displaySetup; Classes = classes; ThumbnailResourceGetter = thumbnailResourceGetter; OmitNoExistingFileMessage = omitNoExistingFileMessage; UploadValidationPredicate = uploadValidationPredicate; UploadValidationErrorNotifier = uploadValidationErrorNotifier; UploadValidationMethod = uploadValidationMethod; }
/// <summary> /// Creates a setup object for a read-only radio button. /// </summary> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the container.</param> /// <param name="highlightedWhenSelected"></param> /// <param name="nestedContentGetter">A function that gets the content that will appear beneath the radio button.</param> /// <param name="nestedContentAlwaysDisplayed">Pass true to force the nested content to always be displayed instead of only when the button is selected. /// </param> public static FlowRadioButtonSetup CreateReadOnly( DisplaySetup displaySetup = null, ElementClassSet classes = null, bool highlightedWhenSelected = false, Func <IReadOnlyCollection <FlowComponent> > nestedContentGetter = null, bool nestedContentAlwaysDisplayed = false) { return(new FlowRadioButtonSetup( displaySetup, classes, RadioButtonSetup.CreateReadOnly(), highlightedWhenSelected, nestedContentGetter, nestedContentAlwaysDisplayed)); }
/// <summary> /// Creates a generic phrasing container (i.e. span element). /// </summary> /// <param name="content"></param> /// <param name="displaySetup"></param> /// <param name="classes">The classes on the element.</param> /// <param name="etherealContent"></param> public GenericPhrasingContainer( IReadOnlyCollection <PhrasingComponent> content, DisplaySetup displaySetup = null, ElementClassSet classes = null, IReadOnlyCollection <EtherealComponent> etherealContent = null) { children = new DisplayableElement( context => new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData("span"), classes: classes, children: content, etherealChildren: etherealContent)).ToCollection(); }
/// <summary> /// Creates an HTML block editor setup object. /// </summary> /// <param name="displaySetup"></param> /// <param name="isReadOnly">Pass true to prevent the contents of the HTML block editor from being changed.</param> /// <param name="ckEditorConfiguration">A comma-separated list of CKEditor configuration options ("toolbar: [ [ 'Bold', 'Italic' ] ]", etc.). Use this to /// customize the underlying CKEditor. Do not pass null.</param> /// <param name="validationPredicate"></param> /// <param name="validationErrorNotifier"></param> /// <param name="additionalValidationMethod"></param> public HtmlBlockEditorSetup( DisplaySetup displaySetup = null, bool isReadOnly = false, string ckEditorConfiguration = "", Func <bool, bool> validationPredicate = null, Action validationErrorNotifier = null, Action <Validator> additionalValidationMethod = null) { DisplaySetup = displaySetup; WysiwygSetup = new WysiwygHtmlEditorSetup( isReadOnly: isReadOnly, ckEditorConfiguration: ckEditorConfiguration, validationPredicate: validationPredicate, validationErrorNotifier: validationErrorNotifier); AdditionalValidationMethod = additionalValidationMethod; }
internal static ComponentListItem ToComponentListItem( this IReadOnlyCollection <FlowComponent> content, string id, DisplaySetup displaySetup, ElementClassSet classes, int?visualOrderRank, IEnumerable <UpdateRegionSet> updateRegionSets, IEnumerable <UpdateRegionSet> removalUpdateRegionSets, IReadOnlyCollection <EtherealComponent> etherealContent, Func <ElementContext, string, IReadOnlyCollection <Tuple <string, string> >, DisplayableElementLocalData> localDataGetter) { return(new ComponentListItem( (includeContentContainer, itemTypeClasses, width) => { FlowComponentOrNode component = null; component = new IdentifiedFlowComponent( () => new IdentifiedComponentData <FlowComponentOrNode>( id, new UpdateRegionLinker( "", new PreModificationUpdateRegion(updateRegionSets, component.ToCollection, () => "").ToCollection(), arg => component.ToCollection()).ToCollection(), new ErrorSourceSet(), errorsBySource => new DisplayableElement( context => { var attributes = new List <Tuple <string, string> >(); if (visualOrderRank.HasValue || width != null) { attributes.Add( Tuple.Create( "style", StringTools.ConcatenateWithDelimiter( ", ", visualOrderRank.HasValue ? "order: {0}".FormatWith(visualOrderRank.Value) : "", width != null ? "width: {0}".FormatWith(width.Value) : ""))); } return new DisplayableElementData( displaySetup, () => !includeContentContainer && localDataGetter != null ? localDataGetter(context, "li", attributes) : new DisplayableElementLocalData("li", focusDependentData: new DisplayableElementFocusDependentData(attributes: attributes)), classes: CssElementCreator.ItemClass.Add(itemTypeClasses).Add(classes ?? ElementClassSet.Empty), children: includeContentContainer ? new DisplayableElement( innerContext => new DisplayableElementData( null, () => localDataGetter != null ? localDataGetter(innerContext, "div", null) : new DisplayableElementLocalData("div"), classes: CssElementCreator.ItemClass, children: content, etherealChildren: etherealContent)).ToCollection() : content, etherealChildren: includeContentContainer ? null : etherealContent); }).ToCollection())); return component; }, id, removalUpdateRegionSets)); }