protected KnockoutBindingGroup BuildControlKnockoutBinding()
        {
            var binding = new KnockoutBindingGroup();

            binding.Add("maxItemsCount", this, MaxItemsCountProperty, () =>
            {
                binding.Add("maxItemsCount", MaxItemsCount.ToString());
            });

            binding.Add("groupName", this, GroupNameProperty, () =>
            {
                binding.Add("groupName", KnockoutHelper.MakeStringLiteral(GroupName));
            });

            binding.Add("allowedOperations", KnockoutHelper.MakeStringLiteral(AllowedOperations.ToString()));

            if (HasBinding(ItemDroppedProperty))
            {
                var tempContainer = GetDataContextTarget(this, ItemDroppedProperty);
                var function      = KnockoutHelper.GenerateClientPostBackExpression(nameof(ItemDropped), GetCommandBinding(ItemDroppedProperty), tempContainer, new PostbackScriptOptions()
                {
                    ElementAccessor = CodeParameterAssignment.FromIdentifier("target")
                });
                binding.Add("onItemDropped", $"function (target) {{ {function} }}");
            }

            return(binding);
        }
Esempio n. 2
0
 protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
 {
     writer.AddAttribute("class", "code-editor");
     writer.AddKnockoutDataBind("aceEditor", this, CodeProperty);
     writer.AddKnockoutDataBind("aceEditor-language", KnockoutHelper.MakeStringLiteral(Language.ToString().ToLower()));
     base.AddAttributesToRender(writer, context);
 }
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            ExtraCssFileUrlProperty.IsSet(this);

            writer.AddAttribute("class", "dotvvm-crystal-report-viewer-container");
            writer.AddAttribute("report-page-url", WebUtility.HtmlEncode(ReportPageUrl));
            writer.AddAttribute("display-toolbar", DisplayToolbar.ToString());
            writer.AddAttribute("display-page", DisplayPage.ToString());
            writer.AddAttribute("display-statusbar", DisplayStatusbar.ToString());
            writer.AddAttribute("best-fit-page", BestFitPage.ToString());
            if (ExtraCssFileUrlProperty.IsSet(this))
            {
                writer.AddAttribute("extra-css-file-url", WebUtility.HtmlEncode(ExtraCssFileUrl));
            }
            if (WidthProperty.IsSet(this))
            {
                writer.AddAttribute("width", Width);
            }
            if (HeightProperty.IsSet(this))
            {
                writer.AddAttribute("height", Height);
            }

            writer.AddKnockoutDataBind("crystalReportFile", this, CrystalReportFileProperty, () =>
            {
                writer.AddKnockoutDataBind("crystalReportFile", KnockoutHelper.MakeStringLiteral(CrystalReportFile));
            });

            base.AddAttributesToRender(writer, context);
        }
Esempio n. 4
0
        public string CompileBinding(string expression, Type[] contexts, Type expectedType)
        {
            var configuration = DotvvmTestHelper.CreateConfiguration();

            configuration.RegisterApiClient(typeof(TestApiClient), "http://server/api", "./apiscript.js", "_api");
            configuration.Markup.ImportedNamespaces.Add(new NamespaceImport("DotVVM.Framework.Tests.Binding"));

            var context = DataContextStack.Create(contexts.FirstOrDefault() ?? typeof(object), extensionParameters: new BindingExtensionParameter[] {
                new BindingPageInfoExtensionParameter(),
            }.Concat(configuration.Markup.DefaultExtensionParameters).ToArray());

            for (int i = 1; i < contexts.Length; i++)
            {
                context = DataContextStack.Create(contexts[i], context);
            }
            var parser         = new BindingExpressionBuilder();
            var expressionTree = parser.ParseWithLambdaConversion(expression, context, BindingParserOptions.Create <ValueBindingExpression>(), expectedType);
            var jsExpression   =
                configuration.ServiceProvider.GetRequiredService <StaticCommandBindingCompiler>().CompileToJavascript(context, expressionTree);

            return(KnockoutHelper.GenerateClientPostBackScript(
                       "",
                       new FakeCommandBinding(BindingPropertyResolvers.FormatJavascript(jsExpression, nullChecks: false), null),
                       new Literal(),
                       new PostbackScriptOptions(
                           allowPostbackHandlers: false,
                           returnValue: null,
                           commandArgs: CodeParameterAssignment.FromIdentifier("commandArguments")
                           )));
        }
Esempio n. 5
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            writer.AddAttribute("type", "text");

            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-DataSource", this, DataSourceProperty);
            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-SelectedValue", this, SelectedValueProperty);
            if (ItemValueBindingProperty.IsSet(this))
            {
                writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-ValueMember", ItemValueBinding.KnockoutExpression.ToDefaultString());
            }

            if (ItemTextBindingProperty.IsSet(this))
            {
                writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-DisplayMember", ItemTextBinding.KnockoutExpression.ToDefaultString());
            }

            var selectionChangedBinding = GetCommandBinding(SelectionChangedProperty);

            if (selectionChangedBinding != null)
            {
                writer.AddAttribute("onchange", KnockoutHelper.GenerateClientPostBackScript(nameof(SelectionChanged), selectionChangedBinding, this, isOnChange: true, useWindowSetTimeout: true));
            }

            base.AddAttributesToRender(writer, context);
        }
Esempio n. 6
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            var script = KnockoutHelper.GenerateClientPostBackScript(nameof(Click), this.GetCommandBinding(ClickProperty), this, new PostbackScriptOptions(returnValue: null));

            writer.AddAttribute("onclick", $"var promise = {script}; promise.then(a => this.innerText = a.commandResult || a)");

            base.AddAttributesToRender(writer, context);
        }
 public static ActiveDotvvmProperty RegisterCommandToAttribute <TDeclaringType>(string name, string attributeName)
 {
     return(DelegateActionProperty <object> .Register <TDeclaringType>(name, (writer, context, value, control) =>
     {
         var binding = value as ICommandBinding;
         var script = KnockoutHelper.GenerateClientPostBackScript(name, binding, context, control);
         writer.AddAttribute(attributeName, script);
     }));
 }
Esempio n. 8
0
 public static ActiveDotvvmProperty RegisterCommandToAttribute <TDeclaringType>(string name, string attributeName)
 {
     return(DelegateActionProperty <ICommandBinding> .Register <TDeclaringType>(name, (writer, context, property, control) =>
     {
         var binding = control.GetCommandBinding(property) ?? throw new Exception($"Command binding expression was expected in {property}.");
         var script = KnockoutHelper.GenerateClientPostBackScript(name, binding, control);
         writer.AddAttribute(attributeName, script);
     }));
 }
Esempio n. 9
0
 protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
 {
     writer.AddAttribute("onclick", KnockoutHelper.GenerateClientPostBackScript(nameof(Click), this.GetCommandBinding(ClickProperty), this, new PostbackScriptOptions(
                                                                                    commandArgs: CodeParameterAssignment.FromExpression(
                                                                                        new JsArrayExpression(
                                                                                            new JsIdentifierExpression("prompt").Invoke(new JsLiteral("type something"))
                                                                                            )
                                                                                        )
                                                                                    )));
 }
Esempio n. 10
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            var parameter = Parameter.GetParametrizedKnockoutExpression(this);

            writer.AddAttribute("onclick", KnockoutHelper.GenerateClientPostBackScript(nameof(Click), this.GetCommandBinding(ClickProperty), this, new PostbackScriptOptions(
                                                                                           commandArgs: new ParametrizedCode.Builder {
                "[",
                parameter,
                "]"
            }.Build(OperatorPrecedence.Max)
                                                                                           )));
        }
Esempio n. 11
0
        protected override void RenderContents(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            var expr = SelectedKeyBinding.GetKnockoutBindingExpression();

            for (int i = 0; i < Choices.Count; i++)
            {
                var key = KnockoutHelper.MakeStringLiteral(Choices[i].Key);

                writer.WriteKnockoutDataBindComment("if", $"ko.unwrap({expr}) === {key}");
                templateHosts[i].Render(writer, context);
                writer.WriteKnockoutDataBindEndComment();
            }
        }
Esempio n. 12
0
        public void CommandResolver_Valid_SimpleTest()
        {
            var path      = new[] { ValueBindingExpression.CreateBinding <object>(bindingService, vm => ((Test1)vm[0]).A[0], (DataContextStack)null) };
            var commandId = "someCommand";
            var command   = new CommandBindingExpression(bindingService, vm => {
                ((TestA)vm[0]).Test(((TestA)vm[0]).StringToPass, ((dynamic)vm[1]).NumberToPass);
            }, commandId);

            var testObject = new Test1 {
                A = new[]
                {
                    new TestA()
                    {
                        StringToPass = "******"
                    }
                },
                NumberToPass = 16
            };
            var viewRoot = new DotvvmView()
            {
                DataContext = testObject
            };

            viewRoot.SetBinding(Controls.Validation.TargetProperty, ValueBindingExpression.CreateBinding(bindingService, vm => vm.Last(), new ParametrizedCode("$root")));

            var placeholder = new HtmlGenericControl("div");

            placeholder.SetBinding(DotvvmBindableObject.DataContextProperty, path[0]);
            viewRoot.Children.Add(placeholder);

            var button = new Button();

            button.SetBinding(ButtonBase.ClickProperty, command);
            placeholder.Children.Add(button);

            var resolver = new CommandResolver();
            var context  = new TestDotvvmRequestContext()
            {
                ViewModel = testObject, ModelState = new ModelState()
            };

            context.ModelState.ValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(button);

            resolver.GetFunction(viewRoot, context, path.Select(v => v.GetProperty <SimplePathExpressionBindingProperty>().Code.FormatKnockoutScript(button, v)).ToArray(), commandId, new Func <Type, object> [0]).Action();

            Assert.AreEqual(testObject.NumberToPass, testObject.A[0].ResultInt);
            Assert.AreEqual(testObject.A[0].ResultString, testObject.A[0].ResultString);
        }
Esempio n. 13
0
        public void CommandResolver_Valid_SimpleTest()
        {
            var path      = new[] { new ValueBindingExpression(vm => ((dynamic)vm[0]).A[0], "A()[0]") };
            var commandId = "someCommand";
            var command   = new CommandBindingExpression(vm => ((TestA)vm[0]).Test(((TestA)vm[0]).StringToPass, ((dynamic)vm[1]).NumberToPass), commandId);

            var testObject = new
            {
                A = new[]
                {
                    new TestA()
                    {
                        StringToPass = "******"
                    }
                },
                NumberToPass = 16
            };
            var viewRoot = new DotvvmView()
            {
                DataContext = testObject
            };

            viewRoot.SetBinding(Validate.TargetProperty, new ValueBindingExpression(vm => vm.Last(), "$root"));

            var placeholder = new HtmlGenericControl("div");

            placeholder.SetBinding(DotvvmBindableObject.DataContextProperty, path[0]);
            viewRoot.Children.Add(placeholder);

            var button = new Button();

            button.SetBinding(ButtonBase.ClickProperty, command);
            placeholder.Children.Add(button);

            var resolver = new CommandResolver();
            var context  = new DotvvmRequestContext()
            {
                ViewModel = testObject
            };

            context.ModelState.ValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(button);

            resolver.GetFunction(viewRoot, context, path.Select(v => v.Javascript).ToArray(), commandId).Action();

            Assert.AreEqual(testObject.NumberToPass, testObject.A[0].ResultInt);
            Assert.AreEqual(testObject.A[0].ResultString, testObject.A[0].ResultString);
        }
Esempio n. 14
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        private FindBindingResult FindControlCommandBinding(string[] path, string commandId, DotvvmControl viewRootControl, DotvvmControl targetControl, string validationTargetPath)
        {
            // walk the control tree and find the path
            ControlCommandBindingExpression resultBinding = null;
            DotvvmProperty resultProperty = null;
            DotvvmControl  resultControl  = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                // compare path
                if (ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                {
                    // find bindings of current control
                    var binding = control.GetAllBindings().Where(p => p.Value is ControlCommandBindingExpression)
                                  .FirstOrDefault(b => b.Value.BindingId == commandId);
                    if (binding.Key != null)
                    {
                        // verify that the target control is the control command target
                        if (control.GetClosestControlBindingTarget() == targetControl)
                        {
                            // we have found the binding, now get the validation path
                            var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                            if (currentValidationTargetPath == validationTargetPath)
                            {
                                // the validation path is equal, we have found the binding
                                resultBinding  = (ControlCommandBindingExpression)binding.Value;
                                resultProperty = binding.Key;
                                resultControl  = control;
                            }
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                Property = resultProperty,
                Binding = resultBinding,
                Control = resultControl
            });
        }
Esempio n. 15
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            writer.AddAttribute("type", "text");

            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-DataSource", this, DataSourceProperty);
            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-SelectedValue", this, SelectedValueProperty);
            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-DisplayMember", KnockoutHelper.MakeStringLiteral(DisplayMember));
            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-ValueMember", KnockoutHelper.MakeStringLiteral(ValueMember));
            writer.AddKnockoutDataBind("dotvvm-contrib-TypeAhead-LimitToList", this, LimitToListProperty);

            var selectionChangedBinding = GetCommandBinding(SelectionChangedProperty);

            if (selectionChangedBinding != null)
            {
                writer.AddAttribute("onchange", KnockoutHelper.GenerateClientPostBackScript(nameof(SelectionChanged), selectionChangedBinding, this, isOnChange: true, useWindowSetTimeout: true));
            }

            base.AddAttributesToRender(writer, context);
        }
Esempio n. 16
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            writer.AddStyleAttribute("display", "none");
            writer.AddAttribute("class", "dotvvm__pwa__offline-handler", true);
            var onlinePageLoadBinding = GetCommandBinding(OnlinePageLoadProperty);

            if (onlinePageLoadBinding != null)
            {
                writer.AddAttribute("onlinepageload", KnockoutHelper.GenerateClientPostBackScript(nameof(OnlinePageLoad), onlinePageLoadBinding, this), true, ";");
            }
            var offlinePageLoadBinding = GetCommandBinding(OfflinePageLoadProperty);

            if (offlinePageLoadBinding != null)
            {
                writer.AddAttribute("offlinepageload", KnockoutHelper.GenerateClientPostBackScript(nameof(OfflinePageLoad), offlinePageLoadBinding, this, new PostbackScriptOptions()), true, ";");
            }
            base.AddAttributesToRender(writer, context);

            writer.AddKnockoutDataBind("dotvvm-pwa-offlineHandler", new KnockoutBindingGroup());
        }
Esempio n. 17
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        private FindBindingResult FindCommandBinding(string[] path, string commandId, DotvvmBindableObject viewRootControl, string validationTargetPath)
        {
            // walk the control tree and find the path
            CommandBindingExpression resultBinding  = null;
            DotvvmBindableObject     resultControl  = null;
            DotvvmProperty           resultProperty = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                // compare path
                if (resultBinding == null && ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                {
                    // find bindings of current control
                    var binding = control.GetAllBindings()
                                  .FirstOrDefault(b => b.Value is CommandBindingExpression commandBinding && commandBinding.BindingId == commandId);
                    if (binding.Key != null)
                    {
                        // we have found the binding, now get the validation path
                        var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                        if (currentValidationTargetPath == validationTargetPath)
                        {
                            // the validation path is equal, we have found the binding
                            resultBinding  = (CommandBindingExpression)binding.Value;
                            resultControl  = control;
                            resultProperty = binding.Key;
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                Binding = resultBinding,
                Control = resultControl,
                Property = resultProperty
            });
        }
 public void SetUp()
 {
     var viewContext = new ViewContext { HttpContext = new FakeHttpContext() };
     var htmlHelper = new HtmlHelper<TestModel>(viewContext, new FakeViewDataContainer());
     knockoutHelper = new KnockoutHelper<TestModel>(htmlHelper);
 }
 protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
 {
     writer.AddKnockoutDataBind("doneTyping", "function () { " + KnockoutHelper.GenerateClientPostBackScript(nameof(DoneTyping), GetCommandBinding(DoneTypingProperty), this, true, null, false, "$element") + " } ");
     writer.AddAttribute("delay", SearchDelayInMs.ToString());
     base.AddAttributesToRender(writer, context);
 }
Esempio n. 20
0
        protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
        {
            context.ResourceManager.AddCurrentCultureGlobalizationResource();

            IValueBinding dateBinding = null;

            foreach (var item in Properties)
            {
                if (item.Key == DateProperty)
                {
                    dateBinding = item.Value as IValueBinding;
                }
            }

            if (dateBinding == null)
            {
                var expression = dateBinding.GetKnockoutBindingExpression(this);
                expression = "dotvvm.globalize.formatString(" + JsonConvert.ToString("d.M.yyyy") + ", " + expression + ")";
                writer.AddKnockoutDataBind("dotvvm-contrib-BootstrapDatepicker", expression);
            }
            else
            {
                writer.AddKnockoutDataBind("dotvvm-contrib-BootstrapDatepicker", this, DateProperty, renderEvenInServerRenderingMode: true);
            }

            if (!string.IsNullOrWhiteSpace(Language))
            {
                writer.AddAttribute("data-date-language", Language);
            }

            var activeTabChangedBinding = GetCommandBinding(ChangedProperty);

            if (activeTabChangedBinding != null)
            {
                writer.AddAttribute("data-dotvvm-contrib-BootstrapDatepicker-changed", KnockoutHelper.GenerateClientPostBackScript(nameof(Changed), activeTabChangedBinding, this, true, null));
            }


            base.AddAttributesToRender(writer, context);
        }
Esempio n. 21
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        /// <param name="path">DataContext path of the binding</param>
        /// <param name="commandId">Id of the binding</param>
        /// <param name="viewRootControl">ViewRootControl of the binding</param>
        /// <param name="targetControl">Target control of the binding, null if not finding control command binding</param>
        /// <param name="validationTargetPath">Validation path of the binding</param>
        /// <param name="findControl">Determinate whether finding control command binding or not</param>
        /// <returns></returns>
        private FindBindingResult FindCommandBinding(string[] path, string commandId,
                                                     DotvvmBindableObject viewRootControl, DotvvmBindableObject targetControl,
                                                     string validationTargetPath, bool findControl)
        {
            // walk the control tree and find the path
            CommandBindingExpression resultBinding  = null;
            DotvvmBindableObject     resultControl  = null;
            DotvvmProperty           resultProperty = null;

            bool   checkControl;
            bool   bindingInPath     = false;
            var    candidateBindings = new Dictionary <string, CandidateBindings>();
            string errorMessage      = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                if (resultBinding == null)
                {
                    // find bindings of current control
                    var bindings = control.GetAllBindings()
                                   .Where(b => b.Value is CommandBindingExpression);

                    foreach (var binding in bindings)
                    {
                        var wrongExceptionPropertyKeys   = new List <string>();
                        var correctExceptionPropertyKeys = new List <string>();
                        var infoMessage = new StringBuilder();

                        // checking path
                        if (!ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                        {
                            wrongExceptionPropertyKeys.Add("DataContext path");
                            infoMessage.Append(
                                $"Expected DataContext path: '{string.Join("/", path)}' Command binding DataContext path: '{string.Join("/", walker.CurrentPathArray)}'");
                        }
                        else
                        {
                            //Found a binding in DataContext
                            bindingInPath = true;
                            correctExceptionPropertyKeys.Add("DataContext path");
                        }

                        //checking binding id
                        if (((CommandBindingExpression)binding.Value).BindingId != commandId)
                        {
                            wrongExceptionPropertyKeys.Add("binding id");
                        }
                        else
                        {
                            correctExceptionPropertyKeys.Add("binding id");
                        }

                        //checking validation path
                        var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                        if (currentValidationTargetPath != validationTargetPath)
                        {
                            wrongExceptionPropertyKeys.Add("validation path");
                            infoMessage.Append($"Expected validation path: '{string.Join("/", validationTargetPath)}' Command binding validation path: '{string.Join("/", currentValidationTargetPath)}'");
                        }
                        else
                        {
                            correctExceptionPropertyKeys.Add("validation path");
                        }

                        //If finding control command binding checks if the binding is control otherwise always true
                        checkControl = !findControl || control.GetClosestControlBindingTarget() == targetControl;

                        if (!wrongExceptionPropertyKeys.Any() && checkControl)
                        {
                            //correct binding found
                            resultBinding  = (CommandBindingExpression)binding.Value;
                            resultControl  = control;
                            resultProperty = binding.Key;
                        }
                        else if (wrongExceptionPropertyKeys.Any())
                        {
                            var exceptionPropertyKey =
                                (findControl && checkControl
                                    ? "Control command bindings with wrong "
                                    : "Command bindings with wrong ") + string.Join(", ", wrongExceptionPropertyKeys)
                                + (correctExceptionPropertyKeys.Any()
                                    ? " and correct " + string.Join(", ", correctExceptionPropertyKeys)
                                    : "")
                                + ":";
                            if (!candidateBindings.ContainsKey(exceptionPropertyKey))
                            {
                                candidateBindings.Add(exceptionPropertyKey, new CandidateBindings());
                            }
                            candidateBindings[exceptionPropertyKey]
                            .AddBinding(new KeyValuePair <string, IBinding>(infoMessage.ToString(), binding.Value));
                        }
                        else
                        {
                            errorMessage = "Invalid command invocation (the binding is not control command binding)";
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                ErrorMessage = bindingInPath ? errorMessage : "Nothing was found in found inside specified DataContext check if ViewModel is populated",
                CandidateBindings = candidateBindings,
                Binding = resultBinding,
                Control = resultControl,
                Property = resultProperty
            });
        }