/// <summary> /// Creates a radio button. /// </summary> internal EwfCheckBox( FormValue<CommonCheckBox> formValue, string label, PostBack postBack, string listItemId = null ) { radioButtonFormValue = formValue; radioButtonListItemId = listItemId; this.label = label; this.postBack = postBack; }
/// <summary> /// Creates a radio button. /// </summary> internal BlockCheckBox( FormValue<CommonCheckBox> formValue, string label, PostBack postBack, string listItemId = null ) { radioButtonFormValue = formValue; radioButtonListItemId = listItemId; this.label = label; this.postBack = postBack; NestedControls = new List<Control>(); }
/// <summary> /// Creates a check box. Do not pass null for label. /// </summary> public BlockCheckBox( bool isChecked, string label = "", bool highlightWhenChecked = false, PostBack postBack = null ) { checkBoxFormValue = EwfCheckBox.GetFormValue( isChecked, this ); this.label = label; this.highlightWhenChecked = highlightWhenChecked; this.postBack = postBack; NestedControls = new List<Control>(); }
/// <summary> /// Creates a check box list. /// </summary> public EwfCheckBoxList( IEnumerable <SelectListItem <ItemIdType> > items, IEnumerable <ItemIdType> selectedItemIds, string caption = "", bool includeSelectAndDeselectAllButtons = false, byte numberOfColumns = 1, PostBack postBack = null) { this.items = items.ToArray(); this.selectedItemIds = selectedItemIds.ToArray(); this.caption = caption; this.includeSelectAndDeselectAllButtons = includeSelectAndDeselectAllButtons; this.numberOfColumns = numberOfColumns; this.postBack = postBack; }
/// <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(); }
private IReadOnlyCollection <FlowComponent> getUploadComponents( int fileCollectionId, IReadOnlyCollection <BlobFile> files, DisplaySetup displaySetup, string postBackIdBase, Action <RsFile, Validator> uploadValidationMethod, NewFileNotificationMethod fileCreatedOrReplacedNotifier) { RsFile file = null; var dm = PostBack.CreateFull( id: PostBack.GetCompositeId(postBackIdBase, "add"), firstModificationMethod: () => { if (file == null) { return; } var existingFile = files.SingleOrDefault(i => i.FileName == file.FileName); int newFileId; if (existingFile != null) { BlobStorageStatics.SystemProvider.UpdateFile( existingFile.FileId, file.FileName, file.Contents, BlobStorageStatics.GetContentTypeForPostedFile(file)); newFileId = existingFile.FileId; } else { newFileId = BlobStorageStatics.SystemProvider.InsertFile( fileCollectionId, file.FileName, file.Contents, BlobStorageStatics.GetContentTypeForPostedFile(file)); } fileCreatedOrReplacedNotifier?.Invoke(newFileId); EwfPage.AddStatusMessage(StatusMessageType.Info, "File uploaded successfully."); }); return(FormState.ExecuteWithDataModificationsAndDefaultAction( dm.ToCollection(), () => new StackList( new FileUpload( validationMethod: (postBackValue, validator) => { file = postBackValue; uploadValidationMethod?.Invoke(postBackValue, validator); }).ToFormItem() .ToListItem() .Append(new EwfButton(new StandardButtonStyle("Upload new file")).ToCollection().ToComponentListItem())).ToFormItem( setup: new FormItemSetup(displaySetup: displaySetup), label: "Select and upload a new file:".ToComponents()) .ToComponentCollection())); }
/// <summary> /// Creates a chart setup object. /// </summary> /// <param name="chartType"></param> /// <param name="aspectRatio">The aspect ratio (width divided by height) of the chart canvas.</param> /// <param name="labels">The labels for the X axis. There must be exactly as many elements as there are in each data set.</param> /// <param name="postBackIdBase">Do not pass null.</param> /// <param name="xAxisTitle">The title of the X axis. Do not pass null.</param> /// <param name="maxXValues">The number of values to display on the x axis. This menas only the last <paramref name="maxXValues"/> values are displayed. /// </param> /// <param name="yAxisTitle">The title of the Y axis. Do not pass null.</param> /// <param name="yAxisLabelFormatOptions">A JavaScript object containing number format options for the labels on the Y axis. It will be passed into /// Intl.NumberFormat as the options parameter. See /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat for more information.</param> /// <param name="omitTable">Pass true to omit the table containing the chart’s underlying data.</param> public ChartSetup( ChartType chartType, double aspectRatio, IEnumerable <string> labels, string postBackIdBase = "", string xAxisTitle = "", int maxXValues = 16, string yAxisTitle = "", JObject yAxisLabelFormatOptions = null, bool omitTable = false) { PostBackIdBase = PostBack.GetCompositeId("ewfChart", postBackIdBase); ChartType = chartType; AspectRatio = aspectRatio; XAxisTitle = xAxisTitle; Labels = labels; MaxXValues = maxXValues; YAxisTitle = yAxisTitle; YAxisLabelFormatOptions = yAxisLabelFormatOptions; OmitTable = omitTable; }
/// <summary> /// Returns a link to download a file with the given file ID. /// If no file is associated with the given file collection ID, returns a literal control with textIfNoFile text. /// The file name is used as the label unless labelOverride is specified. /// SystemBlobFileManagementProvider must be implemented. /// </summary> public static IReadOnlyCollection <PhrasingComponent> GetFileButtonFromFileId(int fileId, string labelOverride = null, string textIfNoFile = "") { var file = BlobStorageStatics.SystemProvider.GetFile(fileId); if (file == null) { return(textIfNoFile.ToComponents()); } return(new EwfButton( new StandardButtonStyle(labelOverride ?? file.FileName, buttonSize: ButtonSize.ShrinkWrap), behavior: new PostBackBehavior( postBack: PostBack.CreateFull( id: PostBack.GetCompositeId("ewfFile", file.FileId.ToString()), actionGetter: () => new PostBackAction( new PageReloadBehavior(secondaryResponse: new SecondaryResponse(new BlobFileResponse(fileId, () => true), false)))))).ToCollection()); }
/// <summary> /// Creates a radio button list. /// </summary> /// <param name="items">The items in the list. There must be at least one.</param> /// <param name="selectedItemId">The ID of the selected item. This must either match a list item or be the default value of the type, unless an unlisted /// selected item label getter is passed.</param> /// <param name="useHorizontalLayout">Pass true if you want the radio buttons to be laid out horizontally instead of vertically.</param> /// <param name="unlistedSelectedItemLabelGetter">A function that will be called if the selected item ID does not match any list item and is not the default /// value of the type. The function takes the selected item ID and returns the label of the unlisted selected item, which will appear before all other /// items in the list. The string " (invalid)" will be appended to the label.</param> /// <param name="defaultValueItemLabel">The label of the default-value item, which will appear first, and only if none of the list items have an ID with the /// default value. Do not pass null. If you pass the empty string, no default-value item will appear and therefore none of the radio buttons will be /// selected if the selected item ID has the default value and none of the list items do.</param> /// <param name="disableSingleButtonDetection">Pass true to allow just a single radio button to be displayed for this list. Use with caution, as this /// violates the HTML specification.</param> /// <param name="postBack">The post-back that will occur when the user hits Enter on a radio button.</param> /// <param name="autoPostBack">Pass true if you want a post-back to occur when the selection changes.</param> public static SelectList <ItemIdType> CreateRadioList <ItemIdType>( IEnumerable <SelectListItem <ItemIdType> > items, ItemIdType selectedItemId, bool useHorizontalLayout = false, Func <ItemIdType, string> unlistedSelectedItemLabelGetter = null, string defaultValueItemLabel = "", bool disableSingleButtonDetection = false, PostBack postBack = null, bool autoPostBack = false) { return(new SelectList <ItemIdType>( useHorizontalLayout, null, unlistedSelectedItemLabelGetter, defaultValueItemLabel, null, null, items, disableSingleButtonDetection, selectedItemId, postBack, autoPostBack)); }
/// <summary> /// Creates a drop-down list. /// </summary> /// <param name="items">The items in the list. There must be at least one.</param> /// <param name="selectedItemId">The ID of the selected item. This must either match a list item or be the default value of the type, unless an unlisted /// selected item label getter is passed.</param> /// <param name="width">The width of the list. This overrides any value that may be specified via CSS. If no width is specified via CSS and you pass null /// for this parameter, the list will be just wide enough to show the selected item and will resize whenever the selected item is changed.</param> /// <param name="unlistedSelectedItemLabelGetter">A function that will be called if the selected item ID does not match any list item and is not the default /// value of the type. The function takes the selected item ID and returns the label of the unlisted selected item, which will appear before all other /// items in the list. The string " (invalid)" will be appended to the label.</param> /// <param name="defaultValueItemLabel">The label of the default-value item, which will appear first, and only if none of the list items have an ID with the /// default value. Do not pass null. If you pass the empty string, no default-value item will appear.</param> /// <param name="placeholderIsValid">Pass true if you would like the list to include a default-value placeholder that is considered a valid selection. /// This will only be included if none of the list items have an ID with the default value and the default-value item label is the empty string. If you pass /// false, the list will still include a default-value placeholder if the selected item ID has the default value and none of the list items do, but in this /// case the placeholder will not be considered a valid selection.</param> /// <param name="placeholderText">The default-value placeholder's text. Do not pass null.</param> /// <param name="postBack">The post-back that will occur when the user hits Enter on the drop-down list.</param> /// <param name="autoPostBack">Pass true if you want a post-back to occur when the selection changes.</param> public static SelectList <ItemIdType> CreateDropDown <ItemIdType>( IEnumerable <SelectListItem <ItemIdType> > items, ItemIdType selectedItemId, System.Web.UI.WebControls.Unit?width = null, Func <ItemIdType, string> unlistedSelectedItemLabelGetter = null, string defaultValueItemLabel = "", bool placeholderIsValid = false, string placeholderText = "Please select", PostBack postBack = null, bool autoPostBack = false) { return(new SelectList <ItemIdType>( null, width, unlistedSelectedItemLabelGetter, defaultValueItemLabel, placeholderIsValid, placeholderText, items, null, selectedItemId, postBack, autoPostBack)); }
private FlowComponent getEntityNavListContainer() { if (entityUiSetup == null) { return(null); } var formItems = entityUiSetup.NavFormControls .Select((control, index) => control.GetFormItem(PostBack.GetCompositeId("entity", "nav", index.ToString()))) .Materialize(); var listItems = getActionListItems(entityUiSetup.NavActions).Concat(formItems.Select(i => i.ToListItem())).Materialize(); if (!listItems.Any()) { return(null); } return(new GenericFlowContainer(new LineList(listItems.Select(i => (LineListItem)i)).ToCollection(), classes: entityNavListContainerClass)); }
private FlowComponent getGlobalNavListContainer() { // This check exists to prevent the display of lookup boxes or other post back controls. With these controls we sometimes don't have a specific // destination page to use for an authorization check, meaning that the system code has no way to prevent their display when there is no intermediate // user. if (ConfigurationStatics.IsIntermediateInstallation && !AppRequestState.Instance.IntermediateUserExists) { return(null); } var formItems = EwfUiStatics.AppProvider.GetGlobalNavFormControls() .Select((control, index) => control.GetFormItem(PostBack.GetCompositeId("global", "nav", index.ToString()))) .Materialize(); var listItems = getActionListItems(EwfUiStatics.AppProvider.GetGlobalNavActions()).Concat(formItems.Select(i => i.ToListItem())).Materialize(); if (!listItems.Any()) { return(null); } return(new GenericFlowContainer(new LineList(listItems.Select(i => (LineListItem)i)).ToCollection(), classes: globalNavListContainerClass)); }
protected override PageContent getContent() { var body = new DataValue <string>(); return(FormState.ExecuteWithDataModificationsAndDefaultAction( PostBack.CreateFull( modificationMethod: () => { var message = new EmailMessage { Subject = "Support request from {0} in {1}".FormatWith( AppTools.User.FriendlyName.Any() ? AppTools.User.FriendlyName : AppTools.User.Email, ConfigurationStatics.SystemDisplayName), BodyHtml = body.Value.GetTextAsEncodedHtml() }; message.ReplyToAddresses.Add(new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName)); message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmailWithDefaultFromAddress(message); AddStatusMessage(StatusMessageType.Info, "Your message has been sent."); }, actionGetter: () => new PostBackAction(new ExternalResource(ReturnUrl))) .ToCollection(), () => new UiPageContent(contentFootActions: new ButtonSetup("Send Message").ToCollection()) .Add(new Paragraph("You may report any problems, make suggestions, or ask for help here.".ToComponents())) .Add( FormItemList.CreateStack( items: new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress() .ToString() .ToComponents() .ToFormItem(label: "From".ToComponents()) .Append( "{0} ({1} for this system)".FormatWith( StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true), "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None)) .ToComponents() .ToFormItem(label: "To".ToComponents())) .Append( body.ToTextControl(false, setup: TextControlSetup.Create(numberOfRows: 10), value: "").ToFormItem(label: "Message".ToComponents())) .Materialize())))); }
private void addFileRow( string postBackIdBase, Func <int, ResourceInfo> thumbnailResourceGetter, IEnumerable <int> openedFileIds, MarkFileAsReadMethod unopenedFileOpenedNotifier, EwfTable table, BlobFile file) { var cells = new List <EwfTableCell>(); var thumbnailControl = BlobManagementStatics.GetThumbnailControl(file, thumbnailResourceGetter); if (thumbnailControl.Any()) { cells.Add(thumbnailControl.ToCell()); } var fileIsUnopened = openedFileIds != null && !openedFileIds.Contains(file.FileId); cells.Add( new EwfButton( new StandardButtonStyle(file.FileName), behavior: new PostBackBehavior( postBack: PostBack.CreateFull( id: PostBack.GetCompositeId(postBackIdBase, file.FileId.ToString()), firstModificationMethod: () => { if (fileIsUnopened) { unopenedFileOpenedNotifier?.Invoke(file.FileId); } }, actionGetter: () => new PostBackAction( new PageReloadBehavior(secondaryResponse: new SecondaryResponse(new BlobFileResponse(file.FileId, () => true), false)))))) .ToCollection() .ToCell()); cells.Add(file.UploadedDate.ToDayMonthYearString(false).ToCell()); cells.Add((fileIsUnopened ? "New!" : "").ToCell(new TableCellSetup(classes: "ewfNewness".ToCollection()))); table.AddItem(EwfTableItem.Create(cells, setup: EwfTableItemSetup.Create(id: new SpecifiedValue <int>(file.FileId)))); }
/// <summary> /// Creates a check box. Do not pass null for label. /// </summary> public EwfCheckBox( bool isChecked, string label = "", PostBack postBack = null ) { checkBoxFormValue = GetFormValue( isChecked, this ); this.label = label; this.postBack = postBack; }
internal static void AddCheckBoxAttributes( WebControl checkBoxElement, Control checkBox, FormValue<bool> checkBoxFormValue, FormValue<CommonCheckBox> radioButtonFormValue, string radioButtonListItemId, PostBack postBack, 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" ); PostBackButton.EnsureImplicitSubmission( checkBoxElement, postBack ); var isSelectedRadioButton = radioButtonFormValue != null && radioButtonFormValue.GetValue( AppRequestState.Instance.EwfPageRequestState.PostBackValues ) == checkBox; var postBackScript = autoPostBack && !isSelectedRadioButton ? PostBackButton.GetPostBackScript( postBack ?? EwfPage.Instance.DataUpdatePostBack, includeReturnFalse: false ) : ""; var customScript = StringTools.ConcatenateWithDelimiter( "; ", onClickJsMethods.ToArray() ); checkBoxElement.AddJavaScriptEventScript( JsWritingMethods.onclick, StringTools.ConcatenateWithDelimiter( "; ", postBackScript, customScript ) ); }
/// <summary> /// Creates an in-line radio button that is part of the group. /// </summary> public EwfCheckBox CreateInlineRadioButton(bool isSelected, string label = "", PostBack postBack = null, bool autoPostBack = false) { var checkBox = new EwfCheckBox(formValue, label, postBack) { AutoPostBack = autoPostBack }; checkBoxesAndSelectionStates.Add(Tuple.Create <CommonCheckBox, bool>(checkBox, isSelected)); return(checkBox); }
/// <summary> /// Creates a check box. Do not pass null for label. /// </summary> public BlockCheckBox(bool isChecked, string label = "", bool highlightWhenChecked = false, PostBack postBack = null) { checkBoxFormValue = EwfCheckBox.GetFormValue(isChecked, this); this.label = label; this.highlightWhenChecked = highlightWhenChecked; this.postBack = postBack; NestedControls = new List <Control>(); }
internal void AddPostBack( PostBack postBack ) { PostBack existingPostBack; if( !postBacksById.TryGetValue( postBack.Id, out existingPostBack ) ) postBacksById.Add( postBack.Id, postBack ); else if( existingPostBack != postBack ) throw new ApplicationException( "A post-back with an ID of \"{0}\" already exists in the page.".FormatWith( existingPostBack.Id ) ); }
/// <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 (PageBase.Current.SubmitButtonPostBack != null) { throw new ApplicationException("A submit button already exists on the page."); } PageBase.Current.SubmitButtonPostBack = postBackAction.PostBack; return(new DisplayableElementData( displaySetup, () => new DisplayableElementLocalData( "button", new FocusabilityCondition(true), isFocused => { var attributes = new List <ElementAttribute> { new ElementAttribute("name", PageBase.ButtonElementName), new ElementAttribute("value", "v") }; if (isFocused) { attributes.Add(new ElementAttribute("autofocus")); } return new DisplayableElementFocusDependentData(attributes: attributes, jsInitStatements: style.GetJsInitStatements(context.Id)); }), classes: style.GetClasses().Add(classes ?? ElementClassSet.Empty), children: elementChildren)); }).ToCollection(); }
/// <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(); }
internal static void AddCheckBoxAttributes(WebControl checkBoxElement, Control checkBox, FormValue <bool> checkBoxFormValue, FormValue <CommonCheckBox> radioButtonFormValue, string radioButtonListItemId, PostBack postBack, 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"); } PostBackButton.EnsureImplicitSubmission(checkBoxElement, postBack); var isSelectedRadioButton = radioButtonFormValue != null && radioButtonFormValue.GetValue(AppRequestState.Instance.EwfPageRequestState.PostBackValues) == checkBox; var postBackScript = autoPostBack && !isSelectedRadioButton ? PostBackButton.GetPostBackScript(postBack ?? EwfPage.Instance.DataUpdatePostBack, includeReturnFalse : false) : ""; var customScript = StringTools.ConcatenateWithDelimiter("; ", onClickJsMethods.ToArray()); checkBoxElement.AddJavaScriptEventScript(JsWritingMethods.onclick, StringTools.ConcatenateWithDelimiter("; ", postBackScript, customScript)); }
/// <summary> /// Creates a check box. Do not pass null for label. /// </summary> public EwfCheckBox(bool isChecked, string label = "", PostBack postBack = null) { checkBoxFormValue = GetFormValue(isChecked, this); this.label = label; this.postBack = postBack; }
public PostBackFormAction(PostBack postBack) { PostBack = postBack; }
public BlobFileManager( int?fileCollectionId, bool requireUploadIfNoFile, Action <int> idSetter, out Action modificationMethod, BlobFileManagerSetup setup = null) { setup = setup ?? BlobFileManagerSetup.Create(); var file = fileCollectionId != null?BlobStorageStatics.GetFirstFileFromCollection(fileCollectionId.Value) : null; var components = new List <FlowComponent>(); if (file != null) { var download = new EwfButton( new StandardButtonStyle(Translation.DownloadExisting + " (" + file.FileName + ")", buttonSize: ButtonSize.ShrinkWrap), behavior: new PostBackBehavior( postBack: PostBack.CreateFull( id: PostBack.GetCompositeId("ewfFile", file.FileId.ToString()), actionGetter: () => { // Refresh the file here in case a new one was uploaded on the same post-back. return(new PostBackAction( new PageReloadBehavior( secondaryResponse: new SecondaryResponse( new BlobFileResponse(BlobStorageStatics.GetFirstFileFromCollection(fileCollectionId.Value).FileId, () => true), false)))); }))); components.Add(download); } else if (!setup.OmitNoExistingFileMessage) { components.Add(new GenericPhrasingContainer(Translation.NoExistingFile.ToComponents())); } RsFile uploadedFile = null; var fileUploadDisplayedPmv = new PageModificationValue <string>(); components.AddRange( new FileUpload( displaySetup: fileUploadDisplayedPmv.ToCondition(bool.TrueString.ToCollection()).ToDisplaySetup(), validationPredicate: setup.UploadValidationPredicate, validationErrorNotifier: setup.UploadValidationErrorNotifier, validationMethod: (postBackValue, validator) => { if (requireUploadIfNoFile && file == null && postBackValue == null) { validator.NoteErrorAndAddMessage(Translation.PleaseUploadAFile); setup.UploadValidationErrorNotifier?.Invoke(); return; } uploadedFile = postBackValue; setup.UploadValidationMethod?.Invoke(postBackValue, validator); }).ToFormItem() .ToComponentCollection()); var fileUploadDisplayedHiddenFieldId = new HiddenFieldId(); if (file != null) { components.Add( new EwfButton( new StandardButtonStyle(Translation.ClickHereToReplaceExistingFile, buttonSize: ButtonSize.ShrinkWrap), displaySetup: fileUploadDisplayedPmv.ToCondition(bool.FalseString.ToCollection()).ToDisplaySetup(), behavior: new ChangeValueBehavior(fileUploadDisplayedHiddenFieldId, bool.TrueString))); } children = new GenericFlowContainer( BlobManagementStatics.GetThumbnailControl(file, setup.ThumbnailResourceGetter) .Append <FlowComponent>(new StackList(from i in components select i.ToCollection().ToComponentListItem())) .Materialize(), displaySetup: setup.DisplaySetup, classes: setup.Classes, etherealContent: new EwfHiddenField((file == null).ToString(), id: fileUploadDisplayedHiddenFieldId, pageModificationValue: fileUploadDisplayedPmv) .PageComponent.ToCollection()).ToCollection(); modificationMethod = () => { if (fileCollectionId == null) { fileCollectionId = BlobStorageStatics.SystemProvider.InsertFileCollection(); } if (uploadedFile != null) { BlobStorageStatics.SystemProvider.DeleteFilesLinkedToFileCollection(fileCollectionId.Value); BlobStorageStatics.SystemProvider.InsertFile( fileCollectionId.Value, uploadedFile.FileName, uploadedFile.Contents, BlobStorageStatics.GetContentTypeForPostedFile(uploadedFile)); } idSetter(fileCollectionId.Value); }; }
internal static FormAction GetHyperlinkPostBackAction(ResourceInfo destination) { var id = PostBack.GetCompositeId("ewfLink", destination.GetUrl()); return(new PostBackFormAction(EwfPage.Instance.GetPostBack(id) ?? PostBack.CreateFull(id: id, actionGetter: () => new PostBackAction(destination)))); }
/// <summary> /// Creates a form item with a change based check box list, which is a check box list that is based on changes to the selections rather than the absolute /// set of selected items. /// </summary> /// <typeparam name="ItemIdType"></typeparam> /// <param name="label"></param> /// <param name="items"></param> /// <param name="modificationMethod">A method that executes the change handlers of the items that were selected or deselected on this post back.</param> /// <param name="caption"></param> /// <param name="includeSelectAndDeselectAllButtons"></param> /// <param name="numberOfColumns"></param> /// <param name="postBack"></param> /// <param name="cellSpan"></param> /// <param name="textAlignment"></param> /// <param name="validationPredicate"></param> /// <param name="validationList"></param> /// <returns></returns> public static FormItem GetFormItem <ItemIdType>( FormItemLabel label, IEnumerable <ChangeBasedListItemWithSelectionState <ItemIdType> > items, out Action modificationMethod, string caption = "", bool includeSelectAndDeselectAllButtons = false, byte numberOfColumns = 1, PostBack postBack = null, int?cellSpan = null, TextAlignment textAlignment = TextAlignment.NotSpecified, Func <bool> validationPredicate = null, ValidationList validationList = null) { var itemArray = items.ToArray(); var selectedItemIds = itemArray.Where(i => i.IsSelected).Select(i => i.Item.Item.Id); var uiSelectedItemIds = itemArray.Where(i => i.IsSelectedInUi).Select(i => i.Item.Item.Id); var checkBoxList = new ChangeBasedCheckBoxList <ItemIdType>( itemArray.Select(i => i.Item), selectedItemIds, caption, includeSelectAndDeselectAllButtons, numberOfColumns, uiSelectedItemIds, postBack); modificationMethod = checkBoxList.ModifyData; return(FormItem.Create( label, checkBoxList, cellSpan: cellSpan, textAlignment: textAlignment, validationGetter: control => new EwfValidation( (pbv, validator) => { if (validationPredicate != null && !validationPredicate()) { return; } control.Validate(pbv); }, validationList ?? EwfPage.Instance.DataUpdate))); }
/// <summary> /// Creates a modal credit-card collector that is implemented with Stripe Checkout. When the window’s submit button is clicked, the credit card is charged /// or otherwise used. /// </summary> /// <param name="jsOpenStatements">The JavaScript statement list that will open this credit-card collector.</param> /// <param name="testPublishableKey">Your test publishable API key. Will be used in non-live installations. Do not pass null.</param> /// <param name="livePublishableKey">Your live publishable API key. Will be used in live installations. Do not pass null.</param> /// <param name="name">See https://stripe.com/docs/legacy-checkout. Do not pass null.</param> /// <param name="description">See https://stripe.com/docs/legacy-checkout. Do not pass null.</param> /// <param name="amountInDollars">See https://stripe.com/docs/legacy-checkout, but note that this parameter is in dollars, not cents</param> /// <param name="testSecretKey">Your test secret API key. Will be used in non-live installations. Do not pass null.</param> /// <param name="liveSecretKey">Your live secret API key. Will be used in live installations. Do not pass null.</param> /// <param name="successHandler">A method that executes if the credit-card submission is successful. The first parameter is the charge ID and the second /// parameter is the amount of the charge, in dollars.</param> /// <param name="prefilledEmailAddressOverride">By default, the email will be prefilled with AppTools.User.Email if AppTools.User is not null. You can /// override this with either a specified email address (if user is paying on behalf of someone else) or the empty string (to force the user to type in the /// email address).</param> public CreditCardCollector( JsStatementList jsOpenStatements, string testPublishableKey, string livePublishableKey, string name, string description, decimal?amountInDollars, string testSecretKey, string liveSecretKey, Func <string, decimal, StatusMessageAndDestination> successHandler, string prefilledEmailAddressOverride = null) { if (!EwfApp.Instance.RequestIsSecure(HttpContext.Current.Request)) { throw new ApplicationException("Credit-card collection can only be done from secure pages."); } if (amountInDollars.HasValue && amountInDollars.Value.DollarValueHasFractionalCents()) { throw new ApplicationException("Amount must not include fractional cents."); } var token = new DataValue <string>(); ResourceInfo successDestination = null; var postBack = PostBack.CreateFull( id: PostBack.GetCompositeId("ewfCreditCardCollection", description), modificationMethod: () => { // We can add support later for customer creation, subscriptions, etc. as needs arise. if (!amountInDollars.HasValue) { throw new ApplicationException("Only simple charges are supported at this time."); } StripeCharge response; try { response = new StripeGateway(ConfigurationStatics.IsLiveInstallation ? liveSecretKey : testSecretKey).Post( new ChargeStripeCustomer { Amount = (int)(amountInDollars.Value * 100), Currency = "usd", Description = description.Any() ? description : null, Card = token.Value }); } catch (StripeException e) { if (e.Type == "card_error") { throw new DataModificationException(e.Message); } throw new ApplicationException("A credit-card charge failed.", e); } try { var messageAndDestination = successHandler(response.Id, amountInDollars.Value); if (messageAndDestination.Message.Any()) { PageBase.AddStatusMessage(StatusMessageType.Info, messageAndDestination.Message); } successDestination = messageAndDestination.Destination; } catch (Exception e) { throw new ApplicationException("An exception occurred after a credit card was charged.", e); } }, actionGetter: () => new PostBackAction(successDestination)); var hiddenFieldId = new HiddenFieldId(); var hiddenFields = new List <EtherealComponent>(); FormState.ExecuteWithDataModificationsAndDefaultAction( postBack.ToCollection(), () => hiddenFields.Add( new EwfHiddenField("", validationMethod: (postBackValue, validator) => token.Value = postBackValue.Value, id: hiddenFieldId).PageComponent)); FormAction action = new PostBackFormAction(postBack); childGetter = () => { stripeCheckoutIncludeSetter(); action.AddToPageIfNecessary(); jsOpenStatements.AddStatementGetter( () => { var jsTokenHandler = "function( token, args ) { " + hiddenFieldId.GetJsValueModificationStatements("token.id") + " " + action.GetJsStatements() + " }"; return("StripeCheckout.open( { key: '" + (ConfigurationStatics.IsLiveInstallation ? livePublishableKey : testPublishableKey) + "', token: " + jsTokenHandler + ", name: '" + name + "', description: '" + description + "', " + (amountInDollars.HasValue ? "amount: " + amountInDollars.Value * 100 + ", " : "") + "email: '" + (prefilledEmailAddressOverride ?? (AppTools.User == null ? "" : AppTools.User.Email)) + "' } );"); }); return(hiddenFields); }; }
/// <summary> /// Creates a confirmation dialog. /// </summary> /// <param name="id"></param> /// <param name="content"></param> /// <param name="postBack">Pass null to use the post-back corresponding to the first of the current data modifications.</param> public ConfirmationDialog(ConfirmationDialogId id, IReadOnlyCollection <FlowComponent> content, PostBack postBack = null) { children = new ModalBox( id.ModalBoxId, false, content.Append( new Paragraph( new EwfButton( new StandardButtonStyle("Cancel"), behavior: new CustomButtonBehavior(() => "document.getElementById( '{0}' ).close();".FormatWith(id.ModalBoxId.ElementId.Id))) .ToCollection() .Concat(" ".ToComponents()) .Append(new EwfButton(new StandardButtonStyle("Continue"), behavior: new PostBackBehavior(postBack: postBack))) .Materialize())) .Materialize()).ToCollection(); }
/// <summary> /// Creates an in-line radio button that is part of the group. /// </summary> public EwfCheckBox CreateInlineRadioButton( bool isSelected, string label = "", PostBack postBack = null, bool autoPostBack = false ) { var checkBox = new EwfCheckBox( formValue, label, postBack ) { AutoPostBack = autoPostBack }; checkBoxesAndSelectionStates.Add( Tuple.Create<CommonCheckBox, bool>( checkBox, isSelected ) ); return checkBox; }
public static ElementActivationBehavior CreatePostBackScript(PostBack postBack = null) { return(new ElementActivationBehavior(action: new PostBackFormAction(postBack ?? FormState.Current.PostBack))); }
/// <summary> /// Call this from Application_Start in your Global.asax.cs file. Besides this call, there should be no other code in the method. /// </summary> /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param> /// <param name="appInitializer">The application initializer, which performs web-site specific initialization and cleanup. If you have one of these you /// should name the class AppInitializer.</param> public static void InitStatics(SystemInitializer globalInitializer, SystemInitializer appInitializer = null) { // This is a hack to support data-access state in WCF services. var wcfDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState()); // Initialize system. var initTimeDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState()); try { GlobalInitializationOps.InitStatics( globalInitializer, Path.GetFileName(Path.GetDirectoryName(HttpRuntime.AppDomainAppPath)), false, mainDataAccessStateGetter: () => { return(EwfApp.Instance != null ? EwfApp.Instance.RequestState != null ? EwfApp.Instance.RequestState.DataAccessState : initTimeDataAccessState.Value : System.ServiceModel.OperationContext.Current != null ? wcfDataAccessState.Value : null); }); } catch { // Suppress all exceptions since there is no way to report them. return; } ewlInitialized = true; // Initialize web application. if (!GlobalInitializationOps.SecondaryInitFailed) { EwfApp.ExecuteWithBasicExceptionHandling( () => { EwfConfigurationStatics.Init(); GlobalConfiguration.Configure(WebApiStatics.ConfigureWebApi); var miniProfilerOptions = new MiniProfilerOptions(); miniProfilerOptions.IgnoredPaths.Clear(); MiniProfiler.Configure(miniProfilerOptions); var globalType = BuildManager.GetGlobalAsaxType().BaseType; var providerGetter = new SystemProviderGetter( globalType.Assembly, globalType.Namespace + ".Providers", providerName => @"{0} provider not found in application. To implement, create a class named {0} in ""Your Web Site\Providers"" that derives from App{0}Provider." .FormatWith(providerName)); if (ExternalFunctionalityStatics.SamlFunctionalityEnabled) { ExternalFunctionalityStatics.ExternalSamlProvider.InitAppStatics( providerGetter, () => AuthenticationStatics.SamlIdentityProviders.Select( identityProvider => { using (var client = new HttpClient()) { client.Timeout = new TimeSpan(0, 0, 10); var metadata = Task.Run( async() => { using (var response = await client.GetAsync(identityProvider.MetadataUrl, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); var document = new XmlDocument(); using (var stream = await response.Content.ReadAsStreamAsync()) using (var reader = XmlReader.Create(stream)) document.Load(reader); return(document.DocumentElement); } }) .Result; return(metadata, identityProvider.EntityId); } }) .Materialize()); } UrlHandlingStatics.Init( (baseUrlString, appRelativeUrl) => AppRequestState.ExecuteWithUrlHandlerStateDisabled(() => UrlHandlingStatics.ResolveUrl(baseUrlString, appRelativeUrl)?.Last())); CssPreprocessingStatics.Init(globalInitializer.GetType().Assembly, globalType.Assembly); ResourceBase.Init( (requestTransferred, resource) => { if (requestTransferred) { var urlHandlers = new List <BasicUrlHandler>(); UrlHandler urlHandler = resource; do { urlHandlers.Add(urlHandler); }while((urlHandler = urlHandler.GetParent()) != null); AppRequestState.Instance.SetUrlHandlers(urlHandlers); AppRequestState.Instance.SetNewUrlParameterValuesEffective(false); AppRequestState.Instance.SetResource(resource); } else { AppRequestState.Instance.SetResource(resource); } }, () => AppRequestState.Instance.Resource); PageBase.Init( (() => BasePageStatics.AppProvider.GetPageViewDataModificationMethod(), () => BasePageStatics.AppProvider.JavaScriptDocumentReadyFunctionCall), BasicPageContent.GetContent); HyperlinkBehaviorExtensionCreators.Init(ModalBox.GetBrowsingModalBoxOpenStatements); FileUpload.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).FormUsesMultipartEncoding = true); ModalBox.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).BrowsingModalBoxId); CreditCardCollector.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).IncludesStripeCheckout = true); BasePageStatics.Init(providerGetter.GetProvider <AppStandardPageLogicProvider>("StandardPageLogic")); BasicPageContent.Init( contentObjects => { var contentUsesUi = contentObjects.Any(i => i is UiPageContent); var cssInfos = new List <ResourceInfo>(); cssInfos.Add( new ExternalResource( "//fonts.googleapis.com/css2?family=Libre+Franklin:wght@500;600;700&family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400&display=fallback")); cssInfos.Add(new ExternalResource("//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")); cssInfos.Add(new StaticFiles.Versioned.Third_party.Jquery_ui.Jquery_ui_1114custom_v2.Jquery_uiminCss()); cssInfos.Add(new StaticFiles.Third_party.Select_cssCss()); cssInfos.Add(new StaticFiles.Versioned.Third_party.Chosen.Chosen_v187.ChosenminCss()); cssInfos.Add(new StaticFiles.Third_party.Time_picker.StylesCss()); cssInfos.Add(new ExternalResource("//cdn.jsdelivr.net/qtip2/2.2.1/jquery.qtip.min.css")); cssInfos.Add(new ExternalResource("//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.css")); cssInfos.Add(new StaticFiles.Styles.BasicCss()); if (contentUsesUi) { cssInfos.AddRange( new ResourceInfo[] { new StaticFiles.Styles.Ui.ColorsCss(), new StaticFiles.Styles.Ui.FontsCss(), new StaticFiles.Styles.Ui.LayoutCss(), new StaticFiles.Styles.Ui.TransitionsCss() }); } foreach (var resource in BasePageStatics.AppProvider.GetStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } if (contentUsesUi) { foreach (var resource in EwfUiStatics.AppProvider.GetStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } } else { foreach (var resource in BasePageStatics.AppProvider.GetCustomUiStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } } return(cssInfos); }, (markup, includeStripeCheckout) => { string getElement(ResourceInfo resource) => "<script src=\"{0}\" defer></script>".FormatWith(resource.GetUrl()); var infos = new List <ResourceInfo>(); infos.Add(new ExternalResource("//code.jquery.com/jquery-1.12.3.min.js")); infos.Add(new StaticFiles.Versioned.Third_party.Jquery_ui.Jquery_ui_1114custom_v2.Jquery_uiminJs()); infos.Add(new StaticFiles.Versioned.Third_party.Chosen.Chosen_v187.ChosenjqueryminJs()); infos.Add(new StaticFiles.Third_party.Time_picker.CodeJs()); infos.Add(new ExternalResource("//cdn.jsdelivr.net/qtip2/2.2.1/jquery.qtip.min.js")); infos.Add(new ExternalResource("//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js")); infos.Add(new StaticFiles.Third_party.Spin_js.SpinminJs()); infos.Add(new ExternalResource("//cdn.ckeditor.com/4.5.8/full/ckeditor.js")); infos.Add(new ExternalResource("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js")); infos.Add(new ExternalResource("https://instant.page/5.1.0")); if (includeStripeCheckout) { infos.Add(new ExternalResource("https://checkout.stripe.com/checkout.js")); } infos.Add(new StaticFiles.CodeJs()); foreach (var i in infos.Select(getElement)) { markup.Append(i); } markup.Append(MiniProfiler.Current.RenderIncludes().ToHtmlString()); foreach (var resource in BasePageStatics.AppProvider.GetJavaScriptFiles()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); markup.Append(getElement(resource)); } }, () => { var icons = new List <(ResourceInfo, string, string)>(); var faviconPng48X48 = BasePageStatics.AppProvider.FaviconPng48X48; if (faviconPng48X48 != null) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(faviconPng48X48); icons.Add((faviconPng48X48, "icon", "48x48")); } var favicon = BasePageStatics.AppProvider.Favicon; if (favicon != null) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(favicon); icons.Add((favicon, "icon", "")); } return(icons); }, hideWarnings => { var url = AppRequestState.Instance.Url; if (AppRequestState.Instance.UserAccessible && AppRequestState.Instance.ImpersonatorExists) { url = new UserManagement.Pages.Impersonate( url, optionalParameterSetter: (specifier, parameters) => specifier.User = AppTools.User != null ? AppTools.User.Email : UserManagement.Pages.Impersonate.AnonymousUser).GetUrl(); } return(new NonLiveLogIn( url, optionalParameterSetter: (specifier, parameters) => { specifier.Password = ConfigurationStatics.SystemGeneralProvider.IntermediateLogInPassword; specifier.HideWarnings = hideWarnings; }).GetUrl()); }, () => { if (!AppRequestState.Instance.UserAccessible || !AppRequestState.Instance.ImpersonatorExists || (ConfigurationStatics.IsIntermediateInstallation && !AppRequestState.Instance.IntermediateUserExists)) { return(null); } return("User impersonation is in effect.", new HyperlinkSetup(new UserManagement.Pages.Impersonate(AppRequestState.Instance.Url), "Change user").Append <ActionComponentSetup>( new ButtonSetup( "End impersonation", behavior: new PostBackBehavior( postBack: PostBack.CreateFull( id: "ewfEndImpersonation", modificationMethod: UserImpersonationStatics.EndImpersonation, actionGetter: () => new PostBackAction( new ExternalResource( EwfConfigurationStatics.AppConfiguration.DefaultBaseUrl.GetUrlString( EwfConfigurationStatics.AppSupportsSecureConnections))))))) .Materialize()); }); EwfUiStatics.Init(providerGetter.GetProvider <AppEwfUiProvider>("EwfUi")); AuthenticationStatics.Init( providerGetter.GetProvider <AppAuthenticationProvider>("Authentication"), (user, code) => new UserManagement.Pages.LogIn( "", optionalParameterSetter: (specifier, parameters) => { specifier.User = user; specifier.Code = code; }).GetUrl(), destinationUrl => new UserManagement.Pages.ChangePassword(destinationUrl).GetUrl(disableAuthorizationCheck: true)); Admin.EntitySetup.Init(() => RequestDispatchingStatics.AppProvider.GetFrameworkUrlParent()); RequestDispatchingStatics.Init(providerGetter.GetProvider <AppRequestDispatchingProvider>("RequestDispatching")); EwfInitializationOps.appInitializer = appInitializer; appInitializer?.InitStatics(); executeWithAutomaticDatabaseConnections(AuthenticationStatics.InitAppSpecificLogicDependencies); if (AuthenticationStatics.SamlIdentityProviders.Any() || ExternalFunctionalityStatics.SamlFunctionalityEnabled) { executeWithAutomaticDatabaseConnections(ExternalFunctionalityStatics.ExternalSamlProvider.InitAppSpecificLogicDependencies); } initTimeDataAccessState = null; EwfApp.FrameworkInitialized = true; },
/// <summary> /// Creates a post-back behavior. /// </summary> /// <param name="postBack">Pass null to use the post-back corresponding to the first of the current data modifications.</param> public PostBackBehavior(PostBack postBack = null) { PostBackAction = new PostBackFormAction(postBack ?? FormState.Current.PostBack); }
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(); }; }
/// <summary> /// Returns a JavaScript function call getter that opens a Stripe Checkout modal window. If the window's submit button is clicked, the credit card is /// charged or otherwise used. Do not execute the getter before all controls have IDs. /// </summary> /// <param name="etherealControlParent">The control to which any necessary ethereal controls will be added.</param> /// <param name="testPublishableKey">Your test publishable API key. Will be used in non-live installations. Do not pass null.</param> /// <param name="livePublishableKey">Your live publishable API key. Will be used in live installations. Do not pass null.</param> /// <param name="name">See https://stripe.com/docs/checkout. Do not pass null.</param> /// <param name="description">See https://stripe.com/docs/checkout. Do not pass null.</param> /// <param name="amountInDollars">See https://stripe.com/docs/checkout, but note that this parameter is in dollars, not cents</param> /// <param name="testSecretKey">Your test secret API key. Will be used in non-live installations. Do not pass null.</param> /// <param name="liveSecretKey">Your live secret API key. Will be used in live installations. Do not pass null.</param> /// <param name="successHandler">A method that executes if the credit-card submission is successful. The first parameter is the charge ID and the second /// parameter is the amount of the charge, in dollars.</param> /// <param name="prefilledEmailAddressOverride">By default, the email will be prefilled with AppTools.User.Email if AppTools.User is not null. You can /// override this with either a specified email address (if user is paying on behalf of someone else) or the empty string (to force the user to type in the /// email address).</param> public static Func <string> GetCreditCardCollectionJsFunctionCall( Control etherealControlParent, string testPublishableKey, string livePublishableKey, string name, string description, decimal?amountInDollars, string testSecretKey, string liveSecretKey, Func <string, decimal, StatusMessageAndDestination> successHandler, string prefilledEmailAddressOverride = null) { if (!EwfApp.Instance.RequestIsSecure(HttpContext.Current.Request)) { throw new ApplicationException("Credit-card collection can only be done from secure pages."); } EwfPage.Instance.ClientScript.RegisterClientScriptInclude( typeof(PaymentProcessingStatics), "Stripe Checkout", "https://checkout.stripe.com/v2/checkout.js"); if (amountInDollars.HasValue && amountInDollars.Value.DollarValueHasFractionalCents()) { throw new ApplicationException("Amount must not include fractional cents."); } ResourceInfo successDestination = null; var postBack = PostBack.CreateFull( id: PostBack.GetCompositeId("ewfCreditCardCollection", description), actionGetter: () => new PostBackAction(successDestination)); var token = new DataValue <string>(); Func <PostBackValueDictionary, string> tokenHiddenFieldValueGetter; // unused Func <string> tokenHiddenFieldClientIdGetter; EwfHiddenField.Create( etherealControlParent, "", postBackValue => token.Value = postBackValue, postBack, out tokenHiddenFieldValueGetter, out tokenHiddenFieldClientIdGetter); postBack.AddModificationMethod( () => { // We can add support later for customer creation, subscriptions, etc. as needs arise. if (!amountInDollars.HasValue) { throw new ApplicationException("Only simple charges are supported at this time."); } var apiKey = ConfigurationStatics.IsLiveInstallation ? liveSecretKey : testSecretKey; dynamic response = new StripeClient(apiKey).CreateCharge( amountInDollars.Value, "usd", new CreditCardToken(token.Value), description: description.Any() ? description : null); if (response.IsError) { if (response.error.type == "card_error") { throw new DataModificationException(response.error.message); } throw new ApplicationException("Stripe error: " + response); } try { var messageAndDestination = successHandler((string)response.id, amountInDollars.Value); if (messageAndDestination.Message.Any()) { EwfPage.AddStatusMessage(StatusMessageType.Info, messageAndDestination.Message); } successDestination = messageAndDestination.Destination; } catch (Exception e) { throw new ApplicationException("An exception occurred after a credit card was charged.", e); } }); EwfPage.Instance.AddPostBack(postBack); return(() => { var jsTokenHandler = "function( res ) { $( '#" + tokenHiddenFieldClientIdGetter() + "' ).val( res.id ); " + PostBackButton.GetPostBackScript(postBack, includeReturnFalse: false) + "; }"; return "StripeCheckout.open( { key: '" + (ConfigurationStatics.IsLiveInstallation ? livePublishableKey : testPublishableKey) + "', name: '" + name + "', description: '" + description + "', " + (amountInDollars.HasValue ? "amount: " + amountInDollars.Value * 100 + ", " : "") + "token: " + jsTokenHandler + ", email: '" + (prefilledEmailAddressOverride ?? (AppTools.User == null ? "" : AppTools.User.Email)) + "' } )"; }); }
/// <summary> /// Creates a confirmation behavior. If you have form controls that should open the same dialog via implicit submission, use /// <see cref="ConfirmationFormAction"/> instead. /// </summary> /// <param name="dialogContent"></param> /// <param name="postBack">Pass null to use the post-back corresponding to the first of the current data modifications.</param> public ConfirmationButtonBehavior(IReadOnlyCollection <FlowComponent> dialogContent, PostBack postBack = null) { var id = new ConfirmationDialogId(); dialog = new ConfirmationDialog(id, dialogContent, postBack: postBack); confirmationAction = new ConfirmationFormAction(id); }