示例#1
0
        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
                );
        }
示例#2
0
        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");
            }
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
 /// <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);
     }
 }
示例#6
0
        protected virtual void RenderGroupNameAttribute(IHtmlWriter writer)
        {
            var group = new KnockoutBindingGroup();

            group.Add("name", this, GroupNameProperty, () => {
                writer.AddAttribute("name", GroupName);
            });
            writer.AddKnockoutDataBind("attr", group);
        }
示例#7
0
 protected virtual void RenderGroupNameAttribute(IHtmlWriter writer)
 {
     var group = new KnockoutBindingGroup();
     group.Add("name", this, GroupNameProperty, () =>
     {
         writer.AddAttribute("name", GroupName);
     });
     writer.AddKnockoutDataBind("attr", group);
 }
示例#8
0
        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);
        }
示例#9
0
 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));
     }
 }
示例#10
0
 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));
     }
 }
示例#11
0
        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);
        }
示例#12
0
        /// <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;
            }
        }
示例#13
0
        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);
            }
        }
示例#14
0
        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));
            }
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
            }
        }
示例#18
0
 public void AddFrom(KnockoutBindingGroup other)
 {
     entries.AddRange(other.entries);
 }
示例#19
0
 public void AddFrom(KnockoutBindingGroup other)
 {
     entries.AddRange(other.entries);
 }
示例#20
0
        /// <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);
        }
示例#21
0
        /// <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);
                }
            }
        }
示例#22
0
        /// <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;
            }
        }
示例#23
0
        /// <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);
        }