Access DevExpress JavaScript objects for nested fields - devexpress

When I render DevExpress MVC controls for nested fields, using a custom FormBuilder class of my own, I'm using the naming convention of ModelName.FieldName. This fixes binding issues I was having, but I now need client-side access to the JavaScript objects that are created for the control.
In the past, I would find an object called FieldName. For nested fields, what is the naming pattern for the JavaScript object name (since ModelName.FieldName would not be a suitable JavaScript object name), and is there perhaps an alternative way to access the object by passing in the full field name as a parameter to some JavaScript method (something like AllControls.GetControl('ModelName.FieldName'))?
Here is a sample of my code:
var textBoxSettings = new TextBoxSettings
{
Name = "ModelName.FieldName",
};
writer.Write(devExpress.TextBox(textBoxSettings).GetHtml());
UPDATE:
It appears that DevExpress does indeed render objects with the name ModelName.FieldName. I'm not sure how to access those objects in JavaScript - is there some kind of escape sequence to treat the entire phrase as a single variable name?

From my understanding the 'DevExpress' way to access controls dynamically is to use the control collection functions
var nameTextBox =
ASPxClientControl.GetControlCollection().GetByName('ModelName.FieldName')

DevExpress does actually create the JavaScript object with a variable name in the form ModelName.FieldName.
To access that object in JavaScript, you can use the format:
var myControl = window['ModelName.FieldName'];

Related

How to get originating context of helper in handlebars?

I am creating a custom helper.
If I use my new helper within an object like this:
{{#data}}
{{newHelper}}
{{/data}}
How do I access the data object from my helper function?
I know I can do
args.data.root['data']
But I want to access it dynamically because it wont always be within an object called 'data', it could be anything.
You can access the current context with this
So instead of using args.data.root['data'].value you can simply use this.value

Why is ViewBag called ViewBag?

In asp.net mvc, why is ViewBag called ViewBag?
I'm looking for the history or reason why it's called ViewBag over some other name.
ViewBag is a dynamic mapping of the ViewData dictionary. It's called a "bag" because there's no order or sequence to it.. it's just a bunch of data accessible from a dynamic property, much like if you had a bag of stuff.
The underlying ViewData has order to it, but when it's mapped to the dynamic collection it loses that order.. thus it's a bag.
See a definition here:
http://www.cs.miami.edu/~geoff/Courses/MTH517-00S/Content/ArrayBasedADTs/BagsStacksQueues.html
Its a bag full of information which is made available to the view.
It enables you to dynamically share values from the controller to the view. It is a dynamic object which means it has no pre-defined properties. You define the properties you want the ViewBag to have by simply adding them to the property. In the view, you retrieve those values by using same name for the property.

How to render editor template for model property by property name

The end goal is to render an editor template, for a model property, known only at run time, that will not take it's value from the ViewBag.
Html.Editor will use the ViewBag value if the property names match. I don't want this and I hate this "feature".
I hope that this is possible somehow:
var propName = "MyProperty";
var expression = GiveMeTheExpression();
#Html.EditorFor(expression,"MyEditorTemplate")
If not this then some way of rendering an editor template without the viewbag values being used instead of the model's values. I'm totally fine with doing this, IF I CAN IGNORE THE VIEWBAG VALUES SOMEHOW:
#Html.Editor(propName, other, arguments)
You'll probably have to use Html.Partial with a custom ViewDataDictionary.
object knownAtRuntime = ViewBag.ObjectName; // Adapt to your solution
string templateName = String.Concat("EditorTemplates/", knownAtRuntime.GetType().Name);
#Html.Partial(templateName, knownAtRuntime, new ViewDataDictionary(knownAtRuntime));
Note: I made this example simple to illustrate the core concept but you can of course extend it to read UIHintAttribute etc if you like.
Note 2: You may also want to copy values from Html.ViewData to the new ViewDataDictionary to keep your modelstate etc.
Why not try this ?
#Html.EditorFor(x=>x.SomePropertyName)
Assuming SomePropertyName is the name of a Property of your Model which is strongly typed to your view.
Shyju taking about strongly typed object, if I understand you correctly, you need something like: asp.net mvc 3 and dynamic view generation
My solution was to use the #Html.Editor() method with property name as string and to use ViewBag keys that are very unlikely to be found on the model object.
Not ideal, but should work well.

jquery - dynamically fill fields with json based on property name

asp.net mvc model object is being fetched by ajax call - $.ajax(....
form has fields with IDs exactly to matching properties on returned json object (created by Html.TextBox("NAME", Model.Order.NAME) )
How to automatically populate fields(inputs) with corresponding json object properties ?
Manually would be like $("#NAME).val(json.NAME) so how to make this dynamic?
Is there some kind of reflections (like System.Reflection in c#) for javascript/jquery ?
Maybe something like this:
$("#formId input").each(function(){
$(this).val(json[$(this).attr("id")]);
});
... which iterates over all the form inputs, and looks for a JSON entry with the inputs ID.
The thing to note here is that you can retrieve json.NAME via json["NAME"].

Multiple user controls and javascript

I include a JS file in a user control. The host page has multiple instances of the user control.
The JS file has a global variable that is used as a flag for a JS function. I need the scope of this variable be restricted to the user control. Unfortunately, when I have multiple instances of the control, the variable value is overwritten.
What's the recommended approach in a situation like this?
Some options are to dynamically generate the javascript based on the ClientId of the User Control. You could dynamically generate the global variable for example.
Another option and one I would recommend is to encapsulate the global variable and function within an object, then your user control can emit the JS to create an instance of that object (Which can be dynamically named thus letting you scope the object as you see fit).
Edit
I don't have a working code sample that I can share but, I have done this in a couple different ways. the easiest method is to do this in the markup of your user control.
<script language='javascript'>
var <%=this.ClientID%>myObject=new myObject();
</script>
Assuming your control has a clientId of myControl this will create a variable myControlmyObject.
Another way to do this would be to generate the script in the code behind you could register it using: Page.ClientScript.RegisterStartupScript().
I would recommend refactoring your code such that all the common JS logic is stored in one place, not in every UserControl. This will reduce the size of your page by a good margin.
You can pass in the id of the UserControl to the common JS method(s) to differentiate between the UserControls.
For the issue of limiting the scope of your 'UserControl' variable, you could store some sort of a Key/Value structure to keep your UserControl-specific value - the Key would be the UserControl clientID, and the value would be the variable that you're interested in.
For example:
var UCFlags = new Object();
//set the flag for UserControl1:
UCFlags["UC1"] = true;
//set the flag for UserControl2:
UCFlags["UC2"] = false;
To access them, you simply pass the ClientID of the UserControl in to the UCFlags array:
myFlag = UCFlags["UC1"];
On the server-side, you can replace the constant strings "UC1" or "UC2" with
<%= this.ClientID %>
like this:
myFlag = UCFlags["<%= this.ClientID %>"];
You can still use the <%= this.ClientID %> syntax here even though the bulk of the JS is in a separate file; simply set
UCFlags["<%= this.ClientID %>"] = value;
before the call to embed the JS file.
Well, if you have to keep with the current solution, you could rename your global variable to something like the following code, which should be in the .ascx file for your control:
<script type='text/javascript'>
var <%= this.ClientID %>_name_of_global_variable;
</script>
Where "this" is the asp.net control. That way, each control has a unique variable name, based off the client id. Make sure you update the rest of your javascript to use this new naming convention. The problem, it looks messy, and the variable names will become very long depending on where the control is embedded in the page.
Does that make sense? It should take minimal javascript modification to get it working.
I ran into same issue and below blog post solved it. Solution is to take Object oriented way for javaScript
Adding multiple .NET User Controls that use JavaScript to the same page

Resources