public static CommandBindingExpression GetExtensionCommand(this DotvvmControl control, string methodUsageId) { var propertyName = control.GetType().FullName + "/" + methodUsageId; var property = DotvvmProperty.ResolveProperty(typeof(PropertyBox), propertyName); return(control.GetCommandBinding(property) as CommandBindingExpression); }
protected override DotvvmControl TransformCore(DotvvmControl control, IDotvvmRequestContext context) { var gridView = control as TControl; ValidateControl(gridView, context); return(control); }
public override Type GetChildDataContextType(Type dataContext, Type parentDataContext, DotvvmControl control) { var type = control.GetType(); var property = type.GetProperty(PropertyName); if (property == null) throw new Exception($"property { PropertyName } does not exists on { type.FullName }."); return property.GetValue(control).GetType(); }
/// <summary> /// Invokes the specified method on all controls in the page control tree. /// </summary> private void InvokePageLifeCycleEventRecursive(DotvvmControl control, Action <DotvvmControl> action) { foreach (var child in control.GetThisAndAllDescendants()) { action(child); } }
public override void CreateControl(DotvvmControl container, PropertyDisplayMetadata property, DynamicDataContext context) { var textBox = new BusinessPack.Controls.TextBox(); container.Children.Add(textBox); var cssClass = ControlHelpers.ConcatCssClasses(ControlCssClass, property.Styles?.FormControlCssClass); if (!string.IsNullOrEmpty(cssClass)) { textBox.Attributes["class"] = cssClass; } textBox.ValueType = TextBoxHelper.GetValueType(property.PropertyInfo); textBox.FormatString = property.FormatString; textBox.SetBinding(TextBox.TextProperty, context.CreateValueBinding(property.PropertyInfo.Name)); if (property.DataType == DataType.Password) { textBox.Type = TextBoxType.Password; } else if (property.DataType == DataType.MultilineText) { textBox.Type = TextBoxType.MultiLine; } if (textBox.IsPropertySet(DynamicEntity.EnabledProperty)) { ControlHelpers.CopyProperty(textBox, DynamicEntity.EnabledProperty, textBox, TextBox.EnabledProperty); } }
public override void CreateControl(DotvvmControl container, PropertyDisplayMetadata property, DynamicDataContext context) { var comboBox = new ComboBox() { EmptyItemText = GetEmptyItemText(property, context) }; container.Children.Add(comboBox); comboBox.SetBinding(SelectorBase.ItemTextBindingProperty, context.CreateValueBinding(GetDisplayMember(property, context))); comboBox.SetBinding(SelectorBase.ItemValueBindingProperty, context.CreateValueBinding(GetValueMember(property, context))); comboBox.SetBinding(SelectorBase.ItemTextBindingProperty, context.CreateValueBinding(GetDisplayMember(property, context))); comboBox.SetBinding(SelectorBase.ItemValueBindingProperty, context.CreateValueBinding(GetValueMember(property, context))); comboBox.SetBinding(Selector.SelectedValueProperty, context.CreateValueBinding(property.PropertyInfo.Name)); comboBox.SetBinding(ItemsControl.DataSourceProperty, GetDataSourceBinding(property, context, comboBox)); var cssClass = ControlHelpers.ConcatCssClasses(ControlCssClass, property.Styles?.FormControlCssClass); if (!string.IsNullOrEmpty(cssClass)) { comboBox.Attributes["class"] = cssClass; } if (container.IsPropertySet(DynamicEntity.EnabledProperty)) { ControlHelpers.CopyProperty(container, DynamicEntity.EnabledProperty, comboBox, SelectorBase.EnabledProperty); } }
/// <summary> /// Processes the control tree. /// </summary> private void ProcessControlTreeCore(DotvvmControl control, Action<DotvvmControl> action) { action(control); // if there is a DataContext binding, locate the correct token ValueBindingExpression binding; var hasDataContext = false; if (control is DotvvmBindableControl && (binding = ((DotvvmBindableControl)control).GetBinding(DotvvmBindableControl.DataContextProperty, false) as ValueBindingExpression) != null) { CurrentPath.Push(binding.Javascript); RefreshCurrentPathArray(); hasDataContext = true; } // go through all children foreach (var child in control.Children) { ProcessControlTreeCore(child, action); } if (hasDataContext) { CurrentPath.Pop(); RefreshCurrentPathArray(); } }
private void AddMetaViewPort(DotvvmControl newControl, IDotvvmRequestContext context) { var mataViewport = new AmpMetaViewport(AmpConfiguration); newControl.Children.Add(mataViewport); var originalMetaViewport = (HtmlGenericControl)newControl.Children .FirstOrDefault(t => t is HtmlGenericControl generic && generic.TagName == "meta" && generic.Attributes.Any(p => p.Key.ToLower() == "name" && p.Value.ToString().ToLower() == "viewport")); if (originalMetaViewport == null || !originalMetaViewport.Attributes.ContainsKey("content")) { return; } foreach (var prop in originalMetaViewport.Attributes["content"].ToString().Split(',')) { var parts = prop.Split('='); mataViewport.ViewPortProperties.Add(parts[0], parts[1]); } RemoveControlFromTree(originalMetaViewport); }
public override void BuildForm(DotvvmControl hostControl, DynamicDataContext dynamicDataContext) { var entityPropertyListProvider = dynamicDataContext.RequestContext.Configuration.ServiceProvider.GetService <IEntityPropertyListProvider>(); // create the table var table = InitializeTable(hostControl, dynamicDataContext); // create the rows var properties = GetPropertiesToDisplay(dynamicDataContext, entityPropertyListProvider); foreach (var property in properties) { // find the editorProvider for cell var editorProvider = FindEditorProvider(property, dynamicDataContext); if (editorProvider == null) { continue; } // create the row HtmlGenericControl labelCell, editorCell; var row = InitializeTableRow(table, property, dynamicDataContext, out labelCell, out editorCell); // create the label InitializeControlLabel(row, labelCell, editorProvider, property, dynamicDataContext); // create the editorProvider InitializeControlEditor(row, editorCell, editorProvider, property, dynamicDataContext); // create the validator InitializeValidation(row, labelCell, editorCell, editorProvider, property, dynamicDataContext); } }
public override void BuildForm(DotvvmControl hostControl, DynamicDataContext dynamicDataContext) { var entityPropertyListProvider = dynamicDataContext.RequestContext.Services.GetRequiredService <IEntityPropertyListProvider>(); // create the rows var properties = GetPropertiesToDisplay(dynamicDataContext, entityPropertyListProvider); foreach (var property in properties) { // find the editorProvider for cell var editorProvider = FindEditorProvider(property, dynamicDataContext); if (editorProvider == null) { continue; } // create the row HtmlGenericControl labelElement, controlElement; var formGroup = InitializeFormGroup(hostControl, property, dynamicDataContext, out labelElement, out controlElement); // create the label InitializeControlLabel(formGroup, labelElement, editorProvider, property, dynamicDataContext); // create the editorProvider InitializeControlEditor(formGroup, controlElement, editorProvider, property, dynamicDataContext); // create the validator InitializeValidation(formGroup, labelElement, controlElement, editorProvider, property, dynamicDataContext); } }
/// <summary> /// Gets the validation target expression. /// </summary> public static string GetValidationTargetExpression(DotvvmControl control) { if (!(bool)control.GetValue(Validate.EnabledProperty)) { return(null); } // find the closest control int dataSourceChanges; var validationTargetControl = control.GetClosestWithPropertyValue(out dataSourceChanges, c => c.GetValueBinding(Validate.TargetProperty) != null); if (validationTargetControl == null) { return("$root"); } // reparent the expression to work in current DataContext // FIXME: This does not work: var validationBindingExpression = validationTargetControl.GetValueBinding(Validate.TargetProperty); string validationExpression = validationBindingExpression.GetKnockoutBindingExpression(); validationExpression = string.Join("", Enumerable.Range(0, dataSourceChanges).Select(i => "$parent.")) + validationExpression; return(validationExpression); }
public static void AddKnockoutDataBind(this IHtmlWriter writer, string name, DotvvmControl control, DotvvmProperty property, Action nullBindingAction = null, string valueUpdate = null, bool renderEvenInServerRenderingMode = false, bool setValueBack = false) { var expression = control.GetValueBinding(property); if (expression != null && (!control.RenderOnServer || renderEvenInServerRenderingMode)) { writer.AddAttribute("data-bind", name + ": " + expression.GetKnockoutBindingExpression(), true, ", "); if (valueUpdate != null) { writer.AddAttribute("data-bind", "valueUpdate: '" + valueUpdate + "'", true, ", "); } } else { if (nullBindingAction != null) { nullBindingAction(); } if (setValueBack && expression != null) { control.SetValue(property, expression.Evaluate(control, property)); } } }
/// <summary> /// Generates a list of postback update handlers. /// </summary> private static string GetPostBackHandlersScript(DotvvmControl control, string eventName) { var handlers = (List <PostBackHandler>)control.GetValue(PostBack.HandlersProperty); if (handlers == null) { return("null"); } var effectiveHandlers = handlers.Where(h => string.IsNullOrEmpty(h.EventName) || h.EventName == eventName); var sb = new StringBuilder(); sb.Append("["); foreach (var handler in effectiveHandlers) { if (sb.Length > 1) { sb.Append(","); } sb.Append("{name:'"); sb.Append(handler.ClientHandlerName); sb.Append("',options:function(){return {"); foreach (var option in handler.GetHandlerOptionClientExpressions()) { sb.Append(option.Key); sb.Append(":"); sb.Append(option.Value); } sb.Append("};}}"); } sb.Append("]"); return(sb.ToString()); }
protected override DotvvmControl TransformCore(DotvvmControl control, IDotvvmRequestContext context) { AddMetaCharset(control, context); AddLinkToOriginalPage(control, context); AddMetaViewPort(control, context); return(control); }
private void ApplyFallbackProperty(DotvvmControl control) { if (control.IsPropertySet(Amp.FallbackProperty) && control.GetValue <bool>(Amp.FallbackProperty) && control is HtmlGenericControl genericControl) { genericControl.Attributes.Add("fallback", null); } }
/// <summary> /// Saves the state of the control. /// </summary> public void SaveControlState(JToken viewModelToken, DotvvmControl control) { if (control is DotvvmBindableControl && ((DotvvmBindableControl)control).RequiresControlState) { // find the control state collection var controlStateCollection = viewModelToken["$controlState"]; if (controlStateCollection == null) { controlStateCollection = new JObject(); ((JObject)viewModelToken).Add("$controlState", controlStateCollection); } // find the control state item control.EnsureControlHasId(); var controlState = controlStateCollection[control.ID] as JObject; if (controlState == null) { controlState = new JObject(); ((JObject)controlStateCollection).Add(control.ID, controlState); } // serialize the property values foreach (var item in ((DotvvmBindableControl)control).ControlState.Where(v => v.Value != null)) { controlState.Add(item.Key, JToken.FromObject(item.Value)); controlState.Add(item.Key + "$type", JToken.FromObject(item.Value.GetType())); } } }
private static string GetSrc(DotvvmControl finalControl) { string GetSrcFromSrcset(string srcset) { return((srcset?.Trim() ?? string.Empty).Split(',').First().Trim().Split(' ').First()); } string src = null; var image = (Image)finalControl; if (!string.IsNullOrWhiteSpace(image.Src)) { src = image.Src; } if (string.IsNullOrWhiteSpace(src) && !string.IsNullOrWhiteSpace(image.SrcSet)) { src = GetSrcFromSrcset(image.SrcSet); } if (string.IsNullOrWhiteSpace(src)) { throw new AmpException("Unable to get source of image!"); } return(src); }
private void ApplyPlaceholderProperty(DotvvmControl control) { if (control.IsPropertySet(Amp.PlaceholderProperty) && control.GetValue <bool>(Amp.PlaceholderProperty) && control is HtmlGenericControl genericControl) { genericControl.Attributes.Add("placeholder", null); } }
public override void CreateControls(DotvvmRequestContext context, DotvvmControl container) { var literal = new Literal(); literal.FormatString = FormatString; literal.SetBinding(Literal.TextProperty, GetValueBinding(ValueBindingProperty)); container.Children.Add(literal); }
protected static string InvokeLifecycleAndRender(DotvvmControl control, TestDotvvmRequestContext context) { var view = context.View = new DotvvmView(); view.Children.Add(control); return(InvokeLifecycleAndRender(view, context)); }
protected override void AfterTransform(DotvvmControl finalControl, IDotvvmRequestContext context) { if (finalControl is AmpControl ampControl) { ampControl.AmpConfiguration = AmpConfiguration; } base.AfterTransform(finalControl, context); }
protected override void TransferControlProperties(DotvvmControl source, DotvvmControl target) { base.TransferControlProperties(source, target); var dotvvmView = (DotvvmView)source; var ampView = (AmpView)target; ampView.ViewModelType = dotvvmView.ViewModelType; }
protected override DotvvmControl TransformCore(DotvvmControl control, IDotvvmRequestContext context) { if (control is AmpDecoratorBase decorator) { decorator.Configuration = AmpConfiguration; } return(control); }
protected override DotvvmControl CreateReplacementControl(DotvvmControl control) { var routeLink = control as RouteLink; return(new AmpRouteLink(routeLink) { Config = AmpConfiguration }); }
protected override DotvvmControl CreateReplacementControl(DotvvmControl control) { var replacementControl = new Layout { Layout = control.GetValue <AmpLayout>(Amp.LayoutProperty) }; return(replacementControl); }
/// <summary> /// Creates the table element for the form. /// </summary> protected virtual HtmlGenericControl InitializeTable(DotvvmControl hostControl, DynamicDataContext dynamicDataContext) { var table = new HtmlGenericControl("table"); table.Attributes["class"] = "dotvvm-dynamicdata-form-table"; hostControl.Children.Add(table); return(table); }
protected override DotvvmControl TransformCore(DotvvmControl control, IDotvvmRequestContext context) { var genericControl = control as HtmlGenericControl; RemoveControlFromParent(control); string href = (string)genericControl.Attributes["href"]; context.ResourceManager.AddRequiredStylesheetFile(href, href); return(null); }
/// <summary> /// Validates the control command. /// </summary> public FindBindingResult ValidateControlCommand(string[] path, string commandId, DotvvmControl viewRootControl, DotvvmControl targetControl, string validationTargetPath) { // find the binding var result = FindControlCommandBinding(path, commandId, viewRootControl, (DotvvmBindableControl)targetControl, validationTargetPath); if (result.Binding == null) { throw EventValidationException(); } return result; }
protected override DotvvmControl TransformCore(DotvvmControl control, IDotvvmRequestContext context) { RemoveControlFromParent(control); var styleText = control.Children.OfType <RawLiteral>().Single().UnencodedText; var inlineResource = new InlineStylesheetResource(styleText); context.ResourceManager.AddRequiredResource(inlineResource); return(null); }
protected override void ValidateControl(DotvvmControl control, IDotvvmRequestContext context) { var gridview = control as GridView; IsPropertySupported(gridview, view => !((GridView)view).InlineEditing, view => ((GridView)view).InlineEditing = false, nameof(GridView.InlineEditing)); IsPropertySupported(gridview, view => !((GridView)view).EditRowDecorators?.Any() ?? false, view => ((GridView)view).EditRowDecorators?.Clear(), nameof(GridView.EditRowDecorators)); IsPropertySupported(gridview, view => ((GridView)view).SortChanged == null, view => ((GridView)view).SortChanged = null, nameof(GridView.SortChanged)); }
public static CommandBindingExpression RegisterExtensionCommand(this DotvvmControl control, Delegate action, string methodUsageId) { var id = control.GetDotvvmUniqueId() + methodUsageId; var propertyName = control.GetType().FullName + "/" + methodUsageId; var property = DotvvmProperty.Register <object, ExtensionCommands>(propertyName); var binding = new CommandBindingExpression(action, id); control.SetBinding(property, binding); return(binding); }
public static CommandBindingExpression?GetExtensionCommand(this DotvvmControl control, string methodUsageId) { var propertyName = control.GetType().FullName + "/" + methodUsageId; var property = DotvvmProperty.ResolveProperty(typeof(PropertyBox), propertyName); if (property is null) { throw new Exception($"Extension command {propertyName} has not been registered."); } return(control.GetCommandBinding(property) as CommandBindingExpression); }
private void RemoveMetaCharsetIfPresent(DotvvmControl control) { var metaCharsets = control.Children.Where(t => t is HtmlGenericControl genericControl && genericControl.TagName == "meta" && genericControl.Attributes.Any(p => p.Key.ToLower() == "charset")).ToList(); foreach (var metaCharset in metaCharsets) { control.Children.Remove(metaCharset); } }
public object ExecuteBinding(string expression, object[] contexts, DotvvmControl control) { var context = new DataContextStack(contexts.FirstOrDefault()?.GetType() ?? typeof(object)); context.RootControlType = control?.GetType() ?? typeof(DotvvmControl); for (int i = 1; i < contexts.Length; i++) { context = new DataContextStack(contexts[i].GetType(), context); } var parser = new BindingParser(); var expressionTree = parser.Parse(expression, context); return BindingCompiler.CompileToDelegate(expressionTree, context)(contexts, control); }
public static CommandBindingExpression RegisterExtensionCommand(this DotvvmControl control, Delegate action, string methodUsageId) { var bindingService = control.GetValue(Internal.RequestContextProperty).CastTo <IDotvvmRequestContext>() .Configuration.ServiceProvider.GetRequiredService <BindingCompilationService>(); var id = control.GetDotvvmUniqueId() + methodUsageId; var propertyName = control.GetType().FullName + "/" + methodUsageId; var property = DotvvmProperty.ResolveProperty(typeof(PropertyBox), propertyName) ?? DotvvmProperty.Register(propertyName, typeof(object), typeof(PropertyBox), null, false, null, typeof(PropertyBox), throwOnDuplicitRegistration: false); var binding = new CommandBindingExpression(bindingService, action, id); control.SetBinding(property, binding); return(binding); }
public void Add(string name, DotvvmControl control, DotvvmProperty property, Action nullBindingAction) { var binding = control.GetValueBinding(property); if (binding == null) { nullBindingAction(); } else { entries.Add(new KnockoutBindingInfo() { Name = name, Expression = control.GetValueBinding(property).GetKnockoutBindingExpression() }); } }
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); }
public static void AddKnockoutDataBind(this IHtmlWriter writer, string name, DotvvmControl control, DotvvmProperty property, Action nullBindingAction = null, string valueUpdate = null, bool renderEvenInServerRenderingMode = false, bool setValueBack = false) { var expression = control.GetValueBinding(property); if (expression != null && (!control.RenderOnServer || renderEvenInServerRenderingMode)) { writer.AddAttribute("data-bind", name + ": " + expression.GetKnockoutBindingExpression(), true, ", "); if (valueUpdate != null) { writer.AddAttribute("data-bind", "valueUpdate: '" + valueUpdate + "'", true, ", "); } } else { if (nullBindingAction != null) nullBindingAction(); if (setValueBack && expression != null) control.SetValue(property, expression.Evaluate(control, property)); } }
/// <summary> /// Validates the command. /// </summary> public FindBindingResult ValidateCommand(string[] path, string commandId, DotvvmControl viewRootControl, string validationTargetPath) { // find the binding var result = FindCommandBinding(path, commandId, viewRootControl, validationTargetPath); if (result == null || result.Binding == null) { throw EventValidationException(); } // validate the command against the control if (result.Control is IEventValidationHandler) { if (!((IEventValidationHandler)result.Control).ValidateCommand(result.Property)) { throw EventValidationException(); } } return result; }
/// <summary> /// Finds the binding of the specified type on the specified viewmodel path. /// </summary> private FindBindingResult FindCommandBinding(string[] path, string commandId, DotvvmControl viewRootControl, string validationTargetPath) { // walk the control tree and find the path CommandBindingExpression resultBinding = null; DotvvmBindableControl resultControl = null; DotvvmProperty resultProperty = null; var walker = new ControlTreeWalker(viewRootControl); walker.ProcessControlTree((control) => { // compare path if (resultBinding == null && control is DotvvmBindableControl && ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray)) { // find bindings of current control var bindableControl = (DotvvmBindableControl)control; var binding = bindableControl.GetAllBindings().Where(p => p.Value is CommandBindingExpression) .FirstOrDefault(b => b.Value.BindingId == commandId); if (binding.Key != null) { // we have found the binding, now get the validation path var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(bindableControl); if (currentValidationTargetPath == validationTargetPath) { // the validation path is equal, we have found the binding resultBinding = (CommandBindingExpression)binding.Value; resultControl = bindableControl; resultProperty = binding.Key; } } } }); return new FindBindingResult { Binding = resultBinding, Control = resultControl, Property = resultProperty }; }
/// <summary> /// Resolves the command called on the DotvvmControl. /// </summary> public ActionInfo GetFunction(DotvvmControl targetControl, DotvvmControl viewRootControl, DotvvmRequestContext context, string[] path, string commandId) { // event validation var validationTargetPath = context.ModelState.ValidationTargetPath; FindBindingResult findResult = null; if (targetControl == null) { findResult = eventValidator.ValidateCommand(path, commandId, viewRootControl, validationTargetPath); } else { findResult = eventValidator.ValidateControlCommand(path, commandId, viewRootControl, targetControl, validationTargetPath); } context.ModelState.ValidationTarget = findResult.Control.GetValue(Validate.TargetProperty) ?? context.ViewModel; return new ActionInfo { Action = () => findResult.Binding.Evaluate(findResult.Control, findResult.Property), Binding = findResult.Binding, IsControlCommand = targetControl != null }; }
public void BuildContent(DotvvmRequestContext context, DotvvmControl container) { var controlBuilderFactory = context.Configuration.ServiceLocator.GetService<IControlBuilderFactory>(); var control = BuildContentBody(controlBuilderFactory); container.Children.Add(control); }
/// <summary> /// Resolves the command called on the ViewModel. /// </summary> public ActionInfo GetFunction(DotvvmControl viewRootControl, DotvvmRequestContext context, string[] path, string command) { return GetFunction(null, viewRootControl, context, path, command); }
public override void CreateEditControls(IDotvvmRequestContext context, DotvvmControl container) { if (EditTemplate == null) throw new DotvvmControlException(this, "EditTemplate must be set, when editting is allowed in a GridView."); EditTemplate.BuildContent(context, container); }
/// <summary> /// Gets the root data context for a specified control. /// </summary> private object GetRootDataContext(DotvvmControl viewRoot) { if (viewRoot is DotvvmBindableControl) { return ((DotvvmBindableControl)viewRoot).DataContext; } throw new Exception("The view root must be bindable control!"); // TODO: exception handling }
public static void WriteKnockoutDataBindComment(this IHtmlWriter writer, string name, DotvvmControl control, DotvvmProperty property) { writer.WriteUnencodedText($"<!-- ko { name }: { control.GetValueBinding(property).GetKnockoutBindingExpression() } -->"); }
public override void CreateControls(DotvvmRequestContext context, DotvvmControl container) { ContentTemplate.BuildContent(context, container); }
/// <summary> /// Initializes a new instance of the <see cref="ViewModelJTokenControlTreeWalker"/> class. /// </summary> public ControlTreeWalker(DotvvmControl root) { this.root = root; }
public override void CreateEditControls(IDotvvmRequestContext context, DotvvmControl container) { var checkBox = new CheckBox { Enabled = true }; checkBox.SetBinding(CheckableControlBase.CheckedProperty, GetValueBinding(ValueBindingProperty)); container.Children.Add(checkBox); }
public void BuildContent(IDotvvmRequestContext context, DotvvmControl container) { var controlBuilderFactory = context.Configuration.ServiceLocator.GetService<IControlBuilderFactory>(); BuildContentBody.Invoke(controlBuilderFactory, container); }
public override void CreateEditControls(IDotvvmRequestContext context, DotvvmControl container) { var textBox = new TextBox(); textBox.FormatString = FormatString; textBox.ValueType = ValueType; textBox.SetBinding(TextBox.TextProperty, GetValueBinding(ValueBindingProperty)); container.Children.Add(textBox); }
public abstract void CreateEditControls(IDotvvmRequestContext context, DotvvmControl container);
public static string GenerateClientPostBackScript(string propertyName, ICommandBinding expression, DotvvmControl control, PostbackScriptOptions options) { object uniqueControlId = null; if (expression is ControlCommandBindingExpression) { var target = (DotvvmControl)control.GetClosestControlBindingTarget(); uniqueControlId = target.GetDotvvmUniqueId() as string; } var arguments = new List<string>() { "'root'", options.ElementAccessor, "[" + String.Join(", ", GetContextPath(control).Reverse().Select(p => '"' + p + '"')) + "]", (uniqueControlId is IValueBinding ? ((IValueBinding)uniqueControlId).GetKnockoutBindingExpression() : "'" + (string) uniqueControlId + "'"), options.UseWindowSetTimeout ? "true" : "false", JsonConvert.SerializeObject(GetValidationTargetExpression(control)), "null", GetPostBackHandlersScript(control, propertyName) }; // return the script var condition = options.IsOnChange ? "if (!dotvvm.isViewModelUpdating) " : null; var returnStatement = options.ReturnValue != null ? $";return {options.ReturnValue.ToString().ToLower()};" : ""; // call the function returned from binding js with runtime arguments var postBackCall = $"{expression.GetCommandJavascript()}({String.Join(", ", arguments)})"; return condition + postBackCall + returnStatement; }
public static string GenerateClientPostBackScript(string propertyName, ICommandBinding expression, DotvvmControl control, bool useWindowSetTimeout = false, bool? returnValue = false, bool isOnChange = false, string elementAccessor = "this") { return GenerateClientPostBackScript(propertyName, expression, control, new PostbackScriptOptions(useWindowSetTimeout, returnValue, isOnChange, elementAccessor)); }
/// <summary> /// Gets the content place holders. /// </summary> private List<ContentPlaceHolder> GetMasterPageContentPlaceHolders(DotvvmControl masterPage) { var placeHolders = masterPage.GetAllDescendants().OfType<ContentPlaceHolder>().ToList(); // check that no placeholder is nested in another one and that each one has valid ID foreach (var placeHolder in placeHolders) { if (placeHolder.ID == null) throw new DotvvmControlException(placeHolder, "PlaceHolder has to have a ID"); if (placeHolder.GetAllAncestors().Intersect(placeHolders).Any()) { throw new Exception(string.Format("The ContentPlaceHolder with ID '{0}' cannot be nested in another ContentPlaceHolder!", placeHolder.ID)); // TODO: exception handling } } return placeHolders; }
/// <summary> /// Invokes the specified method on all controls in the page control tree. /// </summary> private void InvokePageLifeCycleEventRecursive(DotvvmControl control, Action<DotvvmControl> action) { foreach (var child in control.GetThisAndAllDescendants()) { action(child); } }
/// <summary> /// Generates a list of postback update handlers. /// </summary> private static string GetPostBackHandlersScript(DotvvmControl control, string eventName) { var handlers = (List<PostBackHandler>)control.GetValue(PostBack.HandlersProperty); if (handlers == null) return "null"; var effectiveHandlers = handlers.Where(h => string.IsNullOrEmpty(h.EventName) || h.EventName == eventName); var sb = new StringBuilder(); sb.Append("["); foreach (var handler in effectiveHandlers) { if (sb.Length > 1) { sb.Append(","); } sb.Append("{name:'"); sb.Append(handler.ClientHandlerName); sb.Append("',options:function(){return {"); var isFirst = true; var options = handler.GetHandlerOptionClientExpressions(); options.Add("enabled", handler.TranslateValueOrBinding(PostBackHandler.EnabledProperty)); foreach (var option in options) { if (!isFirst) { sb.Append(','); } isFirst = false; sb.Append(option.Key); sb.Append(":"); sb.Append(option.Value); } sb.Append("};}}"); } sb.Append("]"); return sb.ToString(); }
public static void AddKnockoutDataBind(this IHtmlWriter writer, string name, IEnumerable<KeyValuePair<string, IValueBinding>> expressions, DotvvmControl control, DotvvmProperty property) { writer.AddAttribute("data-bind", name + ": {" + String.Join(",", expressions.Select(e => "'" + e.Key + "': " + e.Value.GetKnockoutBindingExpression())) + "}", true, ", "); }
public static IEnumerable<string> GetContextPath(DotvvmControl control) { while (control != null) { var pathFragment = control.GetValue(Internal.PathFragmentProperty, false) as string; if (pathFragment != null) { yield return pathFragment; } else { var dataContextBinding = control.GetBinding(DotvvmBindableObject.DataContextProperty, false) as IValueBinding; if (dataContextBinding != null) { yield return dataContextBinding.GetKnockoutBindingExpression(); } } control = control.Parent; } }