Exemple #1
0
        internal override void Render(AjaxPage page, string[] templateNames, System.IO.TextWriter writer)
        {
            bool             canRender;
            AttributeBinding ifBinding;

            if (!TryRenderIf(page, templateNames, writer, out ifBinding, out canRender))
            {
                Abort(page, templateNames, writer);
                return;
            }

            if (!canRender)
            {
                return;
            }

            // Output the original template if toggle on was not specified
            if (On == null)
            {
                Abort(page, templateNames, writer);
                return;
            }

            // Get the data associated with the data view
            var onBinding = On.Evaluate(page);

            // Output the original template if no data for on was found
            if (!onBinding.IsValid)
            {
                Abort(page, templateNames, writer);
                return;
            }

            var onValue = onBinding.Value;

            var classValue   = "";
            var classBinding = (AttributeBinding)null;

            if (ClassName != null)
            {
                classBinding = ClassName.Evaluate(page);

                // Output the original template if no data for class was found
                if (!classBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                classValue = (string)classBinding.Value;
            }

            ToggleAction?actionValue;

            var actionBinding = (AttributeBinding)null;

            // Get the value of the toggle action (i.e.: show, hide, etc.)
            if (Action != null)
            {
                actionBinding = Action.Evaluate(page);

                // Output the original template if no data for action was found
                if (!actionBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                actionValue = (ToggleAction)Enum.Parse(typeof(ToggleAction), (string)actionBinding.Value, true);
            }
            else if (!string.IsNullOrEmpty(classValue))
            {
                actionValue = ToggleAction.AddClass;
            }
            else
            {
                actionValue = ToggleAction.Show;
            }

            var groupNameBinding = (AttributeBinding)null;

            if (GroupName != null)
            {
                groupNameBinding = GroupName.Evaluate(page);

                // Output the original template if no data for group name was found
                if (!groupNameBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }
            }

            var strictModeValue   = false;
            var strictModeBinding = (AttributeBinding)null;

            if (StrictMode != null)
            {
                strictModeBinding = StrictMode.Evaluate(page);

                // Output the original template if no data for strict mode was found
                if (!strictModeBinding.IsValid)
                {
                    Abort(page, templateNames, writer);
                    return;
                }

                if (strictModeBinding.Value is bool)
                {
                    strictModeValue = (bool)strictModeBinding.Value;
                }
                else
                {
                    strictModeValue = bool.Parse((string)strictModeBinding.Value);
                }
            }

            bool?equals;

            var whenBinding = (AttributeBinding)null;

            // Evaluate whether the on and when conditions are equal or
            // satisified, which determines whether the toggle is on or off
            if (When == null)
            {
                if (strictModeValue)
                {
                    // In strict mode the on value must be a boolean true
                    if (!(onValue is bool))
                    {
                        throw new ApplicationException(string.Format("With strict mode enabled, toggle:on should be a value of type Boolean, actual type \"{0}\".", onValue == null ? "null" : onValue.GetType().Name));
                    }

                    equals = (bool)onValue;
                }
                else if (onValue is System.Collections.IEnumerable)
                {
                    equals = false;

                    // Satisfied if there are any items
                    foreach (object o in (System.Collections.IEnumerable)onValue)
                    {
                        equals = true;
                        break;
                    }
                }
                else
                {
                    // Otherwise, check to see that the on value is "truthy"
                    equals = JavaScriptHelpers.IsTruthy(onValue);
                }
            }
            else
            {
                whenBinding = When.Evaluate(page);

                var whenValue = whenBinding.Value;

                if (whenValue == null)
                {
                    equals = (onValue == null);
                }
                else if (whenValue is FunctionInstance)
                {
                    object result;

                    try
                    {
                        result = Page.ScriptMarshaller.Unwrap(((FunctionInstance)whenValue).Call(null, Page.ScriptMarshaller.Wrap(onValue)));
                    }
                    catch
                    {
                        Abort(page, templateNames, writer);
                        return;
                    }

                    if (strictModeValue)
                    {
                        if (!(result is bool))
                        {
                            throw new ApplicationException(string.Format("With strict mode enabled, toggle:when function should return a value of type Boolean, found type \"{0}\".", result == null ? "null" : result.GetType().Name));
                        }
                        equals = (bool)result;
                    }
                    else
                    {
                        equals = JavaScriptHelpers.IsTruthy(result);
                    }
                }
                else
                {
                    equals = whenValue.Equals(onValue);
                }
            }

            // If no class value is defined then abort
            if ((actionValue == ToggleAction.AddClass || actionValue == ToggleAction.RemoveClass) && string.IsNullOrEmpty(classValue))
            {
                Abort(page, templateNames, writer);
                return;
            }

            bool render = actionValue == ToggleAction.Render || actionValue == ToggleAction.Dispose;

            AttributeBinding contentTemplateBinding;

            if (!TryContentTemplate(page, templateNames, writer, out contentTemplateBinding))
            {
                Abort(page, templateNames, writer);
                return;
            }

            var ownTemplateNames = contentTemplateBinding != null ?
                                   ((string)contentTemplateBinding.Value).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) :
                                   new string[0];

            using (var context = render ? page.BeginContext(page.Context.DataItem, null) : null)
            {
                RenderStartTag(page, writer, attrs => MergeAttribute(MergeAttribute(MergeAttribute(attrs,
                                                                                                   "class", value =>
                {
                    if (actionValue == ToggleAction.AddClass || actionValue == ToggleAction.RemoveClass)
                    {
                        if ((actionValue == ToggleAction.AddClass && equals.Value) || (actionValue == ToggleAction.RemoveClass && !equals.Value))
                        {
                            value = AttributeHelper.EnsureClassName(value, classValue);
                        }
                        else
                        {
                            value = AttributeHelper.RemoveClassName(value, classValue);
                        }
                    }

                    // Add/remove the "toggle-on" and "toggle-off" classes based on state
                    value = AttributeHelper.EnsureClassName(value, equals.Value ? "toggle-on" : "toggle-off");
                    value = AttributeHelper.RemoveClassName(value, equals.Value ? "toggle-off" : "toggle-on");

                    return(value);
                }).ToArray(),
                                                                                    "style", value =>
                {
                    if (actionValue == ToggleAction.Show || actionValue == ToggleAction.Hide ||
                        actionValue == ToggleAction.Render || actionValue == ToggleAction.Dispose)
                    {
                        if (((actionValue == ToggleAction.Show || actionValue == ToggleAction.Render) && equals.Value) ||
                            ((actionValue == ToggleAction.Hide || actionValue == ToggleAction.Dispose) && !equals.Value))
                        {
                            if (AttributeHelper.GetCssStyle(value, "display") == "none")
                            {
                                value = AttributeHelper.RemoveCssStyle(value, "display");
                            }
                        }
                        else
                        {
                            value = AttributeHelper.EnsureCssStyle(value, "display", "none");
                        }
                    }

                    return(value);
                }).ToArray(),
                                                                     "disabled", value =>
                {
                    if (actionValue == ToggleAction.Enable || actionValue == ToggleAction.Disable)
                    {
                        if ((actionValue == ToggleAction.Enable && equals.Value) || (actionValue == ToggleAction.Disable && !equals.Value))
                        {
                            value = null;
                        }
                        else
                        {
                            value = "disabled";
                        }
                    }

                    return(value);
                }), ifBinding, onBinding, classBinding, actionBinding, groupNameBinding, strictModeBinding, whenBinding, contentTemplateBinding,
                               // If this is render/dispose, include the nested template index as a special attribute
                               render ? new AttributeBinding(new Attribute()
                {
                    Name = "data-sys-tmplidx", Value = NestedTemplateIndex.ToString()
                }, null) : null,
                               render ? new AttributeBinding(new Attribute()
                {
                    Name = "data-sys-tcindex", Value = context.Id
                }, null) : null);

                // Only render the inner blocks if the template would be rendered client-side
                if (!render || (actionValue == ToggleAction.Render && equals.Value) || (actionValue == ToggleAction.Dispose && !equals.Value))
                {
                    foreach (var block in Blocks)
                    {
                        block.Render(page, templateNames.Concat(ownTemplateNames).ToArray(), writer);
                    }
                }

                RenderEndTag(writer);
            }
        }
Exemple #2
0
        /// <summary>
        /// Render the data view to the output for the current page.
        /// </summary>
        /// <param name="page"></param>
        /// <param name="templateNames"></param>
        /// <param name="writer"></param>
        internal override void Render(AjaxPage page, string[] templateNames, System.IO.TextWriter writer)
        {
            bool             canRender;
            AttributeBinding ifBinding;

            if (!TryRenderIf(page, templateNames, writer, out ifBinding, out canRender))
            {
                Abort(page, templateNames, writer);
                return;
            }

            if (!canRender)
            {
                return;
            }

            // Output the original template if data source was not specified
            if (Data == null)
            {
                Abort(page, templateNames, writer);
                return;
            }

            // Get the data associated with the data view
            var dataBinding = Data.Evaluate(page);

            // Output the original template if no data was found
            if (!dataBinding.IsValid)
            {
                Abort(page, templateNames, writer);
                return;
            }

            // Render the inline template for top level dataviews
            string templateId      = null;
            string controlId       = null;
            bool   renderControlId = false;

            if (page.Context.IsGlobal)
            {
                templateId = page.NextControlId;
                controlId  = Attributes.Where(a => a.Name == "id").Select(a => a.Value).FirstOrDefault();
                if (controlId == null)
                {
                    renderControlId = true;
                    controlId       = page.NextControlId;
                }
                writer.Write("<");
                writer.Write(Tag);
                writer.Write(" class='sys-template' id='");
                writer.Write(templateId);
                writer.Write("'>");
                writer.Write(Template);
                writer.Write("</");
                writer.Write(Tag);
                writer.Write(">");
            }

            AttributeBinding contentTemplateBinding;

            if (!TryContentTemplate(page, templateNames, writer, out contentTemplateBinding))
            {
                Abort(page, templateNames, writer);
                return;
            }

            var ownTemplateNames = contentTemplateBinding != null ?
                                   ((string)contentTemplateBinding.Value).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) :
                                   new string[0];

            RenderStartTag(page, writer, ifBinding, dataBinding, contentTemplateBinding,
                           // Include the nested template index as a special attribute
                           new AttributeBinding(new Attribute()
            {
                Name = "data-sys-tmplidx", Value = NestedTemplateIndex.ToString()
            }, null),
                           // If this is a top-level dataview then we will need to ensure an id so that linking can occur
                           renderControlId ? new AttributeBinding(new Attribute()
            {
                Name = "id", Value = controlId
            }, null) : null);

            // Convert the data into a list
            IEnumerable list;

            if (dataBinding.Value == null)
            {
                list = new object[0];
            }
            else if (dataBinding.Value is IEnumerable && !(dataBinding.Value is string))
            {
                list = (IEnumerable)dataBinding.Value;
            }
            else
            {
                list = new[] { dataBinding.Value }
            };

            // Process the template for each list item
            var index = 0;

            foreach (var item in list)
            {
                // Begin a new template context
                using (var context = page.BeginContext(item, index++, null))
                {
                    RenderContextBeginMarker(context, Tag, writer);

                    foreach (var block in Blocks)
                    {
                        block.Render(page, templateNames.Concat(ownTemplateNames).ToArray(), writer);
                    }

                    RenderContextEndMarker(context, Tag, writer);
                }
            }

            RenderEndTag(writer);

            // Render script linking logic
            if (page.Context.IsGlobal)
            {
                writer.Write("<script type=\"text/javascript\">$exoweb({{ domReady: function() {{ Sys.Application.linkElement(document.getElementById(\"{0}\"), document.getElementById(\"{1}\")); }} }});</script>", controlId, templateId);
            }
        }