private (string bindingName, KnockoutBindingGroup bindingValue) GetForeachKnockoutBindingGroup(IDotvvmRequestContext context) { var useTemplate = this.RenderAsNamedTemplate; var value = new KnockoutBindingGroup(); var javascriptDataSourceExpression = GetForeachDataBindExpression().GetKnockoutBindingExpression(this); value.Add( useTemplate ? "foreach" : "data", javascriptDataSourceExpression); if (useTemplate) { var itemTemplateId = context.ResourceManager.AddTemplateResource(context, clientSideTemplate !); value.Add("name", itemTemplateId, true); } if (clientSeparator != null) { // separator has to be always rendered as a named template var separatorTemplateId = context.ResourceManager.AddTemplateResource(context, clientSeparator); value.Add("separatorTemplate", separatorTemplateId, true); } return( useTemplate ? "template" : "foreach", value ); }
protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context) { base.AddAttributesToRender(writer, context); var expression = KnockoutHelper.GetValidationTargetExpression(this); if (expression == null) { return; } var group = new KnockoutBindingGroup(); { group.Add("target", expression); group.Add("includeErrorsFromChildren", IncludeErrorsFromChildren.ToString().ToLower()); group.Add("includeErrorsFromTarget", IncludeErrorsFromTarget.ToString().ToLower()); group.Add("hideWhenValid", HideWhenValid.ToString().ToLower()); } writer.AddKnockoutDataBind("dotvvm-validationSummary", group); if (HideWhenValid) { writer.AddStyleAttribute("display", "none"); } }
private void AddCssClassesToRender(IHtmlWriter writer) { KnockoutBindingGroup cssClassBindingGroup = null; foreach (var cssClass in CssClasses.Properties) { if (HasValueBinding(cssClass)) { if (cssClassBindingGroup == null) { cssClassBindingGroup = new KnockoutBindingGroup(); } cssClassBindingGroup.Add(cssClass.GroupMemberName, this, cssClass); } try { if (true.Equals(this.GetValue(cssClass))) { writer.AddAttribute("class", cssClass.GroupMemberName, append: true, appendSeparator: " "); } } catch { } } if (cssClassBindingGroup != null) { writer.AddKnockoutDataBind("css", cssClassBindingGroup); } }
private void AddCssStylesToRender(IHtmlWriter writer) { KnockoutBindingGroup cssStylesBindingGroup = null; foreach (var styleProperty in CssStyles.Properties) { if (HasValueBinding(styleProperty)) { if (cssStylesBindingGroup == null) { cssStylesBindingGroup = new KnockoutBindingGroup(); } cssStylesBindingGroup.Add(styleProperty.GroupMemberName, this, styleProperty); } try { var value = GetValue(styleProperty)?.ToString(); if (!string.IsNullOrEmpty(value)) { writer.AddStyleAttribute(styleProperty.GroupMemberName, value); } } catch { } } if (cssStylesBindingGroup != null) { writer.AddKnockoutDataBind("style", cssStylesBindingGroup); } }
/// <summary> /// Adds the data-bind attribute to the next HTML element that is being rendered. /// </summary> /// <param name="name">The name of the binding handler.</param> /// <param name="bindingGroup">A group of name-value pairs.</param> public void AddKnockoutDataBind(string name, KnockoutBindingGroup bindingGroup) { foreach (var writer in writers) { writer.AddKnockoutDataBind(name, bindingGroup); } }
protected virtual void RenderGroupNameAttribute(IHtmlWriter writer) { var group = new KnockoutBindingGroup(); group.Add("name", this, GroupNameProperty, () => { writer.AddAttribute("name", GroupName); }); writer.AddKnockoutDataBind("attr", group); }
private KnockoutBindingGroup GetForeachKnockoutBindingGroup() { var javascriptDataSourceExpression = GetForeachDataBindExpression().GetKnockoutBindingExpression(this); var group = new KnockoutBindingGroup(); group.Add("data", javascriptDataSourceExpression); if (SeparatorTemplate != null) { group.Add("separatorTemplate", GetValueRaw(Internal.UniqueIDProperty) + "_separator", true); } return(group); }
public static void WriteRouteLinkHrefAttribute(string routeName, HtmlGenericControl control, DotvvmProperty urlSuffixProperty, IHtmlWriter writer, IDotvvmRequestContext context) { if (!control.RenderOnServer) { var group = new KnockoutBindingGroup(); group.Add("href", GenerateKnockoutHrefExpression(routeName, control, urlSuffixProperty, context)); writer.AddKnockoutDataBind("attr", group); } else { writer.AddAttribute("href", EvaluateRouteUrl(routeName, control, urlSuffixProperty, context)); } }
private static void AddValidatedValue(IHtmlWriter writer, IDotvvmRequestContext context, DotvvmProperty prop, DotvvmControl control) { writer.AddKnockoutDataBind("dotvvmValidation", control, ValueProperty); // render options var bindingGroup = new KnockoutBindingGroup(); foreach (var property in ValidationOptionProperties) { var javascriptName = KnockoutHelper.ConvertToCamelCase(property.Name); var optionValue = control.GetValue(property); if (!object.Equals(optionValue, property.DefaultValue)) { bindingGroup.Add(javascriptName, JsonConvert.SerializeObject(optionValue)); } } writer.AddKnockoutDataBind("dotvvmValidationOptions", bindingGroup); }
/// <summary> /// Adds the data-bind attribute to the next HTML element that is being rendered. /// </summary> /// <param name="name">The name of the binding handler.</param> /// <param name="bindingGroup">A group of name-value pairs.</param> public void AddKnockoutDataBind(string name, KnockoutBindingGroup bindingGroup) { if (dataBindAttributes.Contains(name) && !(dataBindAttributes[name] is KnockoutBindingGroup)) { throw new InvalidOperationException($"The value of binding handler '{name}' cannot be combined with a KnockoutBindingGroup!"); } if (dataBindAttributes.Contains(name)) { var currentGroup = (KnockoutBindingGroup)dataBindAttributes[name]; currentGroup.AddFrom(bindingGroup); } else { dataBindAttributes[name] = bindingGroup; } }
private void AddCssClassesToRender(IHtmlWriter writer) { KnockoutBindingGroup cssClassBindingGroup = null; foreach (var cssClass in CssClasses.Properties) { if (cssClassBindingGroup == null) { cssClassBindingGroup = new KnockoutBindingGroup(); } cssClassBindingGroup.Add(cssClass.GroupMemberName, this, cssClass, null); } if (cssClassBindingGroup != null) { writer.AddKnockoutDataBind("css", cssClassBindingGroup); } }
public static void WriteRouteLinkHrefAttribute(RouteLink control, IHtmlWriter writer, IDotvvmRequestContext context) { // Render client-side knockout expression only if there exists a parameter with value binding var containsBindingParam = control.Params.RawValues.Any(p => p.Value is IValueBinding); if (containsBindingParam) { var group = new KnockoutBindingGroup(); group.Add("href", GenerateKnockoutHrefExpression(control.RouteName, control, context)); writer.AddKnockoutDataBind("attr", group); } if (control.RenderOnServer || !containsBindingParam) { writer.AddAttribute("href", EvaluateRouteUrl(control.RouteName, control, context)); } }
private static void AddValidatedValue(IHtmlWriter writer, IDotvvmRequestContext context, DotvvmProperty prop, DotvvmControl control) { writer.AddKnockoutDataBind("dotvvmValidation", control, ValueProperty, renderEvenInServerRenderingMode: true); // render options var bindingGroup = new KnockoutBindingGroup(); foreach (var property in ValidationOptionProperties) { var javascriptName = KnockoutHelper.ConvertToCamelCase(property.Name); var optionValue = control.GetValue(property); if (!object.Equals(optionValue, property.DefaultValue)) { bindingGroup.Add(javascriptName, JsonConvert.SerializeObject(optionValue, DefaultViewModelSerializer.CreateDefaultSettings())); } } writer.AddKnockoutDataBind("dotvvmValidationOptions", bindingGroup); }
private static void AddValidatedValue(IHtmlWriter writer, RenderContext context, object value, DotvvmControl control) { writer.AddKnockoutDataBind("dotvvmValidation", control, ValidatedValueProperty); // render options var bindingGroup = new KnockoutBindingGroup(); foreach (var property in ValidationOptionProperties) { var javascriptName = property.Name.Substring(0, 1).ToLower() + property.Name.Substring(1); var optionValue = control.GetValue(property); if (!object.Equals(optionValue, property.DefaultValue)) { bindingGroup.Add(javascriptName, JsonConvert.SerializeObject(optionValue)); } } writer.AddKnockoutDataBind("dotvvmValidationOptions", bindingGroup); }
private void AddHtmlAttributesToRender(IHtmlWriter writer) { var attributeBindingGroup = new KnockoutBindingGroup(); foreach (var attribute in Attributes) { if (attribute.Value is IValueBinding) { var binding = attribute.Value as IValueBinding; attributeBindingGroup.Add(attribute.Key, binding.GetKnockoutBindingExpression(this)); if (!RenderOnServer) { continue; } } AddHtmlAttribute(writer, attribute.Key, attribute.Value); } if (!attributeBindingGroup.IsEmpty) { writer.AddKnockoutDataBind("attr", attributeBindingGroup); } }
public void AddFrom(KnockoutBindingGroup other) { entries.AddRange(other.entries); }
/// <summary> /// Adds all attributes that should be added to the control begin tag. /// </summary> protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context) { object id; if (!IsPropertySet(ClientIDProperty)) { SetValueRaw(ClientIDProperty, id = CreateClientId()); } else { id = GetValueRaw(ClientIDProperty); } if (id != null) { Attributes["id"] = id; } CheckInnerTextUsage(); // verify that the properties are used only where they should if (!RendersHtmlTag) { EnsureNoAttributesSet(); } else { var attrBindingGroup = new KnockoutBindingGroup(); // render hard-coded HTML attributes foreach (var attribute in Attributes) { if (attribute.Value is IValueBinding) { var binding = attribute.Value as IValueBinding; attrBindingGroup.Add(attribute.Key, binding.GetKnockoutBindingExpression(this)); if (!RenderOnServer) { continue; } } AddHtmlAttribute(writer, attribute.Key, attribute.Value); } if (!attrBindingGroup.IsEmpty) { writer.AddKnockoutDataBind("attr", attrBindingGroup); } KnockoutBindingGroup cssClassBindingGroup = null; foreach (var cssClass in CssClasses.Properties) { if (cssClassBindingGroup == null) { cssClassBindingGroup = new KnockoutBindingGroup(); } cssClassBindingGroup.Add(cssClass.GroupMemberName, this, cssClass, null); } if (cssClassBindingGroup != null) { writer.AddKnockoutDataBind("css", cssClassBindingGroup); } // handle Visible property AddVisibleAttributeOrBinding(writer); // handle Text property writer.AddKnockoutDataBind("text", this, InnerTextProperty, () => { // inner Text is rendered as attribute only if contains binding // otherwise it is rendered directly as encoded content if (!string.IsNullOrWhiteSpace(InnerText)) { Children.Clear(); Children.Add(new Literal(InnerText)); } }, renderEvenInServerRenderingMode: true); } base.AddAttributesToRender(writer, context); }
/// <summary> /// Adds the corresponding attribute for the Id property. /// </summary> protected virtual void RenderClientId(IHtmlWriter writer) { if (!string.IsNullOrEmpty(ID)) { // build the client ID var dataContextChanges = 0; var hasExpressions = false; var fragments = new List <ClientIDFragment>(); foreach (var ancestor in new[] { this }.Concat(GetAllAncestors())) { if (ancestor.HasBinding(DataContextProperty)) { dataContextChanges++; } if (this == ancestor || IsNamingContainer(ancestor)) { var clientIdExpression = (string)ancestor.GetValue(Internal.ClientIDFragmentProperty); if (clientIdExpression != null) { // generate the expression var expression = new StringBuilder(); for (int i = 0; i < dataContextChanges; i++) { expression.Append("$parentContext."); } expression.Append(clientIdExpression); fragments.Add(new ClientIDFragment() { Value = expression.ToString(), IsExpression = true }); hasExpressions = true; } else if (!string.IsNullOrEmpty(ancestor.ID)) { // add the ID fragment fragments.Add(new ClientIDFragment() { Value = ancestor.ID }); } } if (ancestor.ClientIDMode == ClientIDMode.Static) { break; } } if (!hasExpressions) { // generate ID attribute var sb = new StringBuilder(); for (int i = fragments.Count - 1; i >= 0; i--) { if (sb.Length > 0) { sb.Append("_"); } sb.Append(fragments[i].Value); } writer.AddAttribute("id", sb.ToString()); } else { // generate ID binding var sb = new StringBuilder(); for (int i = fragments.Count - 1; i >= 0; i--) { if (sb.Length > 0) { sb.Append(","); } if (fragments[i].IsExpression) { sb.Append(fragments[i].Value); } else { sb.Append("'"); sb.Append(fragments[i].Value); sb.Append("'"); } } var group = new KnockoutBindingGroup(); group.Add("id", $"dotvvm.evaluator.buildClientId(this, [{sb.ToString()}])"); writer.AddKnockoutDataBind("attr", group); } } }
/// <summary> /// Adds the data-bind attribute to the next HTML element that is being rendered. /// </summary> /// <param name="name">The name of the binding handler.</param> /// <param name="bindingGroup">A group of name-value pairs.</param> public void AddKnockoutDataBind(string name, KnockoutBindingGroup bindingGroup) { if (dataBindAttributes.Contains(name) && !(dataBindAttributes[name] is KnockoutBindingGroup)) { throw new InvalidOperationException($"The value of binding handler '{name}' cannot be combined with a KnockoutBindingGroup!"); } if (bindingGroup.IsEmpty) { return; } if (dataBindAttributes.Contains(name)) { var currentGroup = (KnockoutBindingGroup)dataBindAttributes[name]; currentGroup.AddFrom(bindingGroup); } else { dataBindAttributes[name] = bindingGroup; } }
/// <summary> /// Adds all attributes that should be added to the control begin tag. /// </summary> protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context) { object id; if (!IsPropertySet(ClientIDProperty)) { SetValueRaw(ClientIDProperty, id = CreateClientId()); } else { id = GetValueRaw(ClientIDProperty); } if (id != null) Attributes["id"] = id; CheckInnerTextUsage(); // verify that the properties are used only where they should if (!RendersHtmlTag) { EnsureNoAttributesSet(); } else { var attrBindingGroup = new KnockoutBindingGroup(); // render hard-coded HTML attributes foreach (var attribute in Attributes) { if (attribute.Value is IValueBinding) { var binding = attribute.Value as IValueBinding; attrBindingGroup.Add(attribute.Key, binding.GetKnockoutBindingExpression()); if (!RenderOnServer) continue; } AddHtmlAttribute(writer, attribute.Key, attribute.Value); } if (!attrBindingGroup.IsEmpty) { writer.AddKnockoutDataBind("attr", attrBindingGroup); } // handle Visible property AddVisibleAttributeOrBinding(writer); // handle Text property writer.AddKnockoutDataBind("text", this, InnerTextProperty, () => { // inner Text is rendered as attribute only if contains binding // otherwise it is rendered directly as encoded content if (!string.IsNullOrWhiteSpace(InnerText)) { Children.Clear(); Children.Add(new Literal(InnerText)); } }); } base.AddAttributesToRender(writer, context); }