/// <summary> /// Returns the client-side validation message for a component with the specified field name. /// </summary> /// <param name="containerFieldPrefix">The prefix used to build the final field name (for nested fields). May be null.</param> /// <param name="fieldName">The HTML field name.</param> /// <param name="htmlHelper">An instance of a YHtmlHelper.</param> /// <returns>Returns the client-side validation message for the component with the specified field name.</returns> public static string ValidationMessage(this YHtmlHelper htmlHelper, string containerFieldPrefix, string fieldName) { if (!string.IsNullOrEmpty(containerFieldPrefix)) { fieldName = containerFieldPrefix + "." + fieldName; } return(htmlHelper.BuildValidationMessage(fieldName)); }
/// <summary> /// Render a StringTT display component given a HtmlHelper instance. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance.</param> /// <param name="text">The text displayed.</param> /// <param name="tooltip">The tooltip.</param> /// <returns></returns> public static string ForStringTTDisplay(this YHtmlHelper htmlHelper, string text, string tooltip) { YTagBuilder tag = new YTagBuilder("span"); if (!string.IsNullOrWhiteSpace(tooltip)) { tag.Attributes.Add(Basics.CssTooltipSpan, tooltip); } if (!string.IsNullOrWhiteSpace(text)) { tag.SetInnerText(text); } return(tag.ToString(YTagRenderMode.Normal)); }
internal static async Task <string> RenderRecordsHTMLAsync(YHtmlHelper htmlHelper, TreeDefinition treeModel, List <object> records) { HtmlBuilder hb = new HtmlBuilder(); if (records.Count > 0) { TreeSetup setup = GetTreeSetup(treeModel); hb.Append("<ul class='t_sub'>"); foreach (TreeEntry record in records) { hb.Append(await RenderRecordHTMLAsync(htmlHelper, treeModel, setup, record)); } hb.Append("</ul>"); } return(hb.ToString()); }
internal async Task <string> RenderHTML(YHtmlHelper htmlHelper, TreeDefinition treeModel, List <TreeEntry> data, TreeSetup setup) { HtmlBuilder hb = new HtmlBuilder(); string styleCss = ""; if (data != null && data.Count > 0) { styleCss = " style='display:none'"; } hb.Append($@" <div class='tg_emptytr'{styleCss}> <div class='tg_emptydiv'> {HE(treeModel.NoRecordsText)} </div> </div>"); if (data != null && data.Count > 0) { hb.Append($@" <ul class='tg_root t_sub'>"); foreach (TreeEntry record in data) { hb.Append(await RenderRecordHTMLAsync(htmlHelper, treeModel, setup, record)); } hb.Append($@" </ul>"); } else { // when initially rendering a tree with 0 records, we have to prepare for all templates await YetaWFComponentExtender.AddComponentForType(treeModel.RecordType); } return(hb.ToString()); }
/// <summary> /// Returns the client-side validation message for a component with the specified field name. /// </summary> /// <param name="fieldName">The HTML field name.</param> /// <param name="htmlHelper">An instance of a YHtmlHelper.</param> /// <returns>Returns the client-side validation message for the component with the specified field name.</returns> public static string BuildValidationMessage(this YHtmlHelper htmlHelper, string fieldName) { var modelState = htmlHelper.ModelState[fieldName]; string error = null; bool hasError = false; if (modelState == null) { // no errors } else { IEnumerable <string> errors = (from e in modelState.Errors select e.ErrorMessage); hasError = errors.Any(); if (hasError) { error = errors.First(); } } YTagBuilder tagBuilder = new YTagBuilder("span"); tagBuilder.MergeAttribute("data-v-for", fieldName); tagBuilder.AddCssClass(hasError ? "v-error" : "v-valid"); if (hasError) { // we're building the same client side in validation.ts, make sure to keep in sync // <img src="${$YetaWF.htmlAttrEscape(YConfigs.Forms.CssWarningIconUrl)}" name=${name} class="${YConfigs.Forms.CssWarningIcon}" ${YConfigs.Basics.CssTooltip}="${$YetaWF.htmlAttrEscape(val.M)}"/> YTagBuilder tagImg = new YTagBuilder("img"); tagImg.Attributes.Add("src", Forms.CssWarningIconUrl); tagImg.Attributes.Add("name", fieldName); tagImg.AddCssClass(Forms.CssWarningIcon); tagImg.Attributes.Add(Basics.CssTooltip, error); tagBuilder.InnerHtml = tagImg.ToString(); } return(tagBuilder.ToString(YTagRenderMode.Normal)); }
internal static async Task <string> RenderMenuAsync(YHtmlHelper htmlHelper, List <ModuleAction> subMenu, Guid?subGuid, string cssClass, ModuleAction.RenderModeEnum renderMode, ModuleAction.RenderEngineEnum renderEngine, int level) { HtmlBuilder hb = new HtmlBuilder(); string menuContents = await RenderLIAsync(htmlHelper, subMenu, subGuid, renderMode, renderEngine, null, level); if (string.IsNullOrWhiteSpace(menuContents)) { return(null); } // <ul> YTagBuilder ulTag = new YTagBuilder("ul"); ulTag.AddCssClass(string.Format("t_lvl{0}", level)); if (renderEngine == ModuleAction.RenderEngineEnum.BootstrapSmartMenu) { ulTag.AddCssClass("dropdown-menu"); } if (subGuid != null) { ulTag.AddCssClass("t_megamenu_content"); ulTag.AddCssClass("mega-menu"); // used by smartmenus } if (!string.IsNullOrWhiteSpace(cssClass)) { ulTag.AddCssClass(cssClass); } hb.Append(ulTag.ToString(YTagRenderMode.StartTag)); // <li>....</li> hb.Append(menuContents); // </ul> hb.Append(ulTag.ToString(YTagRenderMode.EndTag)); return(hb.ToString()); }
/// <summary> /// Renders a view. /// </summary> /// <param name="htmlHelper">The HtmlHelper instance.</param> /// <param name="module">The module being rendered in the view.</param> /// <param name="viewHtml">The current view contents to be wrapped in the view.</param> /// <param name="UsePartialFormCss">Defines whether the partial form CSS should be used.</param> /// <returns>Returns the complete view as HTML.</returns> public Task <string> RenderViewAsync(YHtmlHelper htmlHelper, ModuleDefinition module, string viewHtml, bool UsePartialFormCss) { HtmlBuilder hb = new HtmlBuilder(); YTagBuilder tag = new YTagBuilder("div"); tag.AddCssClass(Manager.AddOnManager.CheckInvokedCssModule(Forms.CssFormPartial)); string divId = null; if (Manager.IsPostRequest) { divId = Manager.UniqueId(); tag.Attributes.Add("id", divId); } else { if (UsePartialFormCss && !Manager.IsInPopup && Manager.ActiveDevice != YetaWFManager.DeviceSelected.Mobile && !string.IsNullOrWhiteSpace(Manager.SkinInfo.PartialFormCss) && module.UsePartialFormCss) { tag.AddCssClass(Manager.SkinInfo.PartialFormCss); } } hb.Append(tag.ToString(YTagRenderMode.StartTag)); hb.Append(htmlHelper.AntiForgeryToken()); hb.Append($@"<input name='{Basics.ModuleGuid}' type='hidden' value='{module.ModuleGuid}' />"); hb.Append(viewHtml); hb.Append(tag.ToString(YTagRenderMode.EndTag)); if (divId != null) { Manager.ScriptManager.AddLast($"$YetaWF.Forms.initPartialForm('{divId}');"); } return(Task.FromResult(hb.ToString())); }
internal static async Task <string> RenderRecordHTMLAsync(YHtmlHelper htmlHelper, TreeDefinition treeModel, TreeSetup setup, TreeEntry record) { HtmlBuilder hb = new HtmlBuilder(); //bool highlight; //ObjectSupport.TryGetPropertyValue<bool>(record, "__highlight", out highlight, false); //bool lowlight; //ObjectSupport.TryGetPropertyValue<bool>(record, "__lowlight", out lowlight, false); //string lightCss = ""; //if (highlight) // lightCss = "tg_highlight"; //else if (lowlight) // lightCss = "tg_lowlight"; // check for SubEntriesProperty bool collapsed = record.Collapsed; bool dynSubs = false; List <TreeEntry> items = record.SubEntries; if (items == null || items.Count == 0) { items = null; if (record.DynamicSubEntries) { dynSubs = record.DynamicSubEntries; } else { collapsed = false; } } string urlNew = record.UrlNew; string urlContent = record.UrlContent; // selected bool selected = record.Selected; string selectedCss = "", selectedLICss = ""; if (selected) { selectedCss = $" {setup.SelectedCss}"; selectedLICss = " class='t_select'"; } string extraCss = ""; if (record.ExtraCss != null) { extraCss = $" {record.ExtraCss}"; } string caret; string icon; if (dynSubs || items != null) { if (collapsed) { caret = "<i class='t_icright'> </i>"; } else { caret = "<i class='t_icdown'> </i>"; } if (string.IsNullOrWhiteSpace(urlNew) && string.IsNullOrWhiteSpace(urlContent)) { icon = "<i class='t_icfolder'> </i>"; } else { icon = "<i class='t_icfile'> </i>"; } } else { caret = "<i class='t_icempty'> </i>"; icon = "<i class='t_icfile'> </i>"; } string dd = ""; if (treeModel.DragDrop) { dd = " draggable='true'"; } // entry string text = await htmlHelper.ForDisplayAsync(record, nameof(TreeEntry.Text)); string beforeText = null; if (record.BeforeText != null) { beforeText = await htmlHelper.ForDisplayAsync(record, nameof(TreeEntry.BeforeText)); } string afterText = null; if (record.AfterText != null) { afterText = await htmlHelper.ForDisplayAsync(record, nameof(TreeEntry.AfterText)); } if (!string.IsNullOrWhiteSpace(text)) { text = text.Trim(new char[] { '\r', '\n' }); // templates can generate a lot of extra \r\n which breaks filtering } if (string.IsNullOrWhiteSpace(text)) { text = " "; } string output; if (!string.IsNullOrWhiteSpace(urlNew)) { output = $"<a class='t_entry{selectedCss}{extraCss} yaction-link' target='_blank' href='{HAE(urlNew)}'{dd}>{text}</a>"; } else if (!string.IsNullOrWhiteSpace(urlContent)) { output = $"<a class='t_entry{selectedCss}{extraCss} yaction-link' data-contenttarget='{treeModel.ContentTargetId}' data-contentpane='{treeModel.ContentTargetPane}' href='{HAE(urlContent)}'{dd}>{text}</a>"; } else { output = $"<a class='t_entry{selectedCss}{extraCss}' data-nohref='true' href='#'{dd}>{text}</a>"; } string recData = ""; if (treeModel.JSONData) { string json = JsonConvert.SerializeObject(record, JsonSettings); recData = $" data-record='{HAE(json)}'"; } hb.Append($@" <li {recData}{selectedLICss}> {caret} {icon}{beforeText}{output}{afterText}"); // sub entries if (items != null) { string collapsedStyle = ""; if (collapsed) { collapsedStyle = " style='display:none'"; } hb.Append($@" <ul{collapsedStyle} class='t_sub'>"); foreach (TreeEntry item in items) { hb.Append(await RenderRecordHTMLAsync(htmlHelper, treeModel, setup, item)); } hb.Append($@" </ul>"); } hb.Append($@" </li>"); return(hb.ToString()); }
/// <summary> /// Renders the beginning <form> tag with the specified attributes. /// </summary> /// <param name="HtmlAttributes">The HTML attributes to add to the <form> tag.</param> /// <param name="SaveReturnUrl">Defines whether the return URL is saved when the form is submitted.</param> /// <param name="ValidateImmediately">Defines whether client-side validation is immediate (true) or delayed until form submission (false).</param> /// <param name="ActionName">Overrides the default action name.</param> /// <param name="ControllerName">Overrides the default controller name.</param> /// <param name="Pure">TODO: Purpose unclear.</param> /// <param name="Method">The method used to submit the form (get/post)</param> /// <returns>Returns the HTML with the generated <form> tag.</returns> protected async Task <string> RenderBeginFormAsync(object HtmlAttributes = null, bool SaveReturnUrl = false, bool ValidateImmediately = false, string ActionName = null, string ControllerName = null, string Method = "post") { await YetaWFCoreRendering.Render.AddFormsAddOnsAsync(); await Manager.AddOnManager.AddAddOnNamedAsync("YetaWF_Core", "Forms");// standard css, validation strings await Manager.AddOnManager.AddAddOnNamedAsync("YetaWF_ComponentsHTML", "Forms"); Manager.ScriptManager.AddLast("$YetaWF.Forms", "$YetaWF.Forms;");// need to evaluate for side effect to initialize forms Manager.NextUniqueIdPrefix(); if (string.IsNullOrWhiteSpace(ActionName)) { ActionName = GetViewName(); } if (!ActionName.EndsWith(YetaWFViewExtender.PartialSuffix)) { ActionName += YetaWFViewExtender.PartialSuffix; } if (string.IsNullOrWhiteSpace(ControllerName)) { ControllerName = ModuleBase.Controller; } IDictionary <string, object> rvd = YHtmlHelper.AnonymousObjectToHtmlAttributes(HtmlAttributes); if (SaveReturnUrl) { rvd.Add(Basics.CssSaveReturnUrl, ""); } string css = null; if (Manager.CurrentSite.FormErrorsImmed) { css = CssManager.CombineCss(css, "yValidateImmediately"); } css = CssManager.CombineCss(css, Forms.CssFormAjax); rvd.Add("class", css); YTagBuilder tagBuilder = new YTagBuilder("form"); tagBuilder.MergeAttributes(rvd, true); if (ModuleBase.FormAutoComplete) { tagBuilder.Attributes.Add("autocomplete", "on"); } else { tagBuilder.Attributes.Add("autocomplete", "new-password"); } string id = null; if (tagBuilder.Attributes.ContainsKey("id")) { id = (string)tagBuilder.Attributes["id"]; } else { id = Manager.UniqueId(); tagBuilder.Attributes.Add("id", id); } string formAction; #if MVC6 System.IServiceProvider services = HtmlHelper.ActionContext.HttpContext.RequestServices; IUrlHelper urlHelper = services.GetRequiredService <IUrlHelperFactory>().GetUrlHelper(HtmlHelper.ActionContext); formAction = urlHelper.Action(action: ActionName, controller: ControllerName, new { area = HtmlHelper.RouteData.Values["area"] }); #else formAction = UrlHelper.GenerateUrl(null /* routeName */, ActionName, ControllerName, null, RouteTable.Routes, HtmlHelper.RequestContext, true /* includeImplicitMvcValues */); #endif tagBuilder.MergeAttribute("action", formAction, true); tagBuilder.MergeAttribute("method", Method, true); // show errors if already present if (!HtmlHelper.ModelState.IsValid) { Manager.ScriptManager.AddLast($@" var f = $YetaWF.getElementById('{id}'); if ($YetaWF.Forms.hasErrors(f)) $YetaWF.Forms.showErrors(f); "); } return(tagBuilder.ToString(YTagRenderMode.StartTag)); }
internal static async Task <string> RenderMenuAsync(MenuList menu, string id = null, string cssClass = null, ModuleAction.RenderEngineEnum RenderEngine = ModuleAction.RenderEngineEnum.KendoMenu, bool Hidden = false, YHtmlHelper HtmlHelper = null) { HtmlBuilder hb = new HtmlBuilder(); int level = 0; if (menu.Count == 0) { return(null); } string menuContents = await RenderLIAsync(HtmlHelper, menu, null, menu.RenderMode, RenderEngine, menu.LICssClass, level); if (string.IsNullOrWhiteSpace(menuContents)) { return(null); } // <ul class= style= > YTagBuilder ulTag = new YTagBuilder("ul"); if (Hidden) { ulTag.Attributes.Add("style", "display:none"); } if (!string.IsNullOrWhiteSpace(cssClass)) { ulTag.AddCssClass(Manager.AddOnManager.CheckInvokedCssModule(cssClass)); } ulTag.AddCssClass(string.Format("t_lvl{0}", level)); if (RenderEngine == ModuleAction.RenderEngineEnum.BootstrapSmartMenu) { ulTag.AddCssClass("nav"); ulTag.AddCssClass("navbar-nav"); } if (!string.IsNullOrWhiteSpace(id)) { ulTag.Attributes.Add("id", id); } hb.Append(ulTag.ToString(YTagRenderMode.StartTag)); // <li>....</li> hb.Append(menuContents); // </ul> hb.Append(ulTag.ToString(YTagRenderMode.EndTag)); return(hb.ToString()); }
/// <summary> /// Renders a complete menu. /// </summary> /// <param name="menu">The menu to render.</param> /// <param name="id">The menu ID to generate.</param> /// <param name="cssClass">The optional CSS classes to use for the menu.</param> /// <param name="HtmlHelper">The HtmlHelper instance.</param> /// <returns>Returns the complete menu as HTML.</returns> public Task <string> RenderMenuListAsync(MenuList menu, string id = null, string cssClass = null, YHtmlHelper HtmlHelper = null) { return(RenderMenuAsync(menu, id, cssClass, RenderEngine: ModuleAction.RenderEngineEnum.BootstrapSmartMenu, HtmlHelper: HtmlHelper)); }
internal static async Task <string> RenderLIAsync(YHtmlHelper htmlHelper, List <ModuleAction> subMenu, Guid?subGuid, ModuleAction.RenderModeEnum renderMode, ModuleAction.RenderEngineEnum renderEngine, string liCss, int level) { HtmlBuilder hb = new HtmlBuilder(); ++level; if (subGuid != null) { // megamenu content // <li> YTagBuilder tag = new YTagBuilder("li"); tag.AddCssClass("t_megamenu_content"); if (!string.IsNullOrWhiteSpace(liCss)) { tag.AddCssClass(liCss); } if (renderEngine == ModuleAction.RenderEngineEnum.BootstrapSmartMenu) { tag.AddCssClass("nav-item"); } hb.Append(tag.ToString(YTagRenderMode.StartTag)); ModuleDefinition subMod = await ModuleDefinition.LoadAsync((Guid)subGuid, AllowNone : true); if (subMod != null) { subMod.ShowTitle = false; // don't show the module title in a submenu (temp. override) if (htmlHelper == null) { throw new InternalError("HtmlHelper required for module rendering"); } hb.Append(await subMod.RenderModuleAsync(htmlHelper)); } hb.Append("</li>\n"); } else { foreach (var menuEntry in subMenu) { if (menuEntry.Enabled && await menuEntry.RendersSomethingAsync()) { bool rendered = false; string subMenuContents = null; Guid?subModGuid = null; if (!Manager.EditMode) { // don't show submodule in edit mode if ((menuEntry.SubModule != null && menuEntry.SubModule != Guid.Empty)) { subModGuid = menuEntry.SubModule; } } if (subModGuid != null || (menuEntry.SubMenu != null && menuEntry.SubMenu.Count > 0)) { subMenuContents = await RenderMenuAsync(htmlHelper, menuEntry.SubMenu, subModGuid, menuEntry.CssClass, renderMode, renderEngine, level); if (!string.IsNullOrWhiteSpace(subMenuContents)) { // <li> YTagBuilder tag = new YTagBuilder("li"); if (renderEngine == ModuleAction.RenderEngineEnum.BootstrapSmartMenu) { tag.AddCssClass("dropdown"); tag.AddCssClass("nav-item"); } if (subModGuid != null) { tag.AddCssClass("t_megamenu_hassub"); } if (!string.IsNullOrWhiteSpace(liCss)) { tag.AddCssClass(liCss); } hb.Append(tag.ToString(YTagRenderMode.StartTag)); string menuContents = await CoreRendering.RenderActionAsync(menuEntry, renderMode, null, RenderEngine : renderEngine, HasSubmenu : true, BootstrapSmartMenuLevel : level); hb.Append(menuContents); hb.Append("\n"); hb.Append(subMenuContents); hb.Append("</li>\n"); rendered = true; } } if (!rendered) { // <li> YTagBuilder tag = new YTagBuilder("li"); //if (!menuEntry.Enabled) // tag.MergeAttribute("disabled", "disabled"); if (!string.IsNullOrWhiteSpace(liCss)) { tag.AddCssClass(liCss); } if (renderEngine == ModuleAction.RenderEngineEnum.BootstrapSmartMenu) { tag.AddCssClass("nav-item"); } hb.Append(tag.ToString(YTagRenderMode.StartTag)); string menuContents = await CoreRendering.RenderActionAsync(menuEntry, renderMode, null, RenderEngine : renderEngine, BootstrapSmartMenuLevel : level); hb.Append(menuContents); hb.Append("</li>\n"); } } } } --level; return(hb.ToString()); }