Right way to retrieve model value in editortemplate - asp.net

Consider this editor template (even though it doesn't make sense - I have simplified it for clarity):
#Html.TextBox("", null)
This editor template should retrieve the name and the value for the element which it was called for. The name does get set correctly. The value, however, does not.
The data type differs - sometimes it is a double, sometimes it is a string. So I cannot declare a specific data type as the model.
The only way I can make it behave correctly is if I specify the type as dynamic:
#model dynamic
#Html.TextBox("", (string)Convert.ToString(Model))
This seems like a very clumsy syntax, although it works. Have I got it right?
EDIT:
The full code for my editortemplate is a textfield, that can dynamically be calculated by js ajax calls. It works perfectly, and is meant as a general template for any value that can be calculated from the value of other fields. It is not necessarily a string type. However, I need to provide an object for the argument of the Html.TextBox value.
#model dynamic
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", (string)Convert.ToString(Model), new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>
EDIT 2:
Seems this works as well:
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", Model, new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>

Related

multiple checkboxes that will display different divs when checked

i have about 10 checkbox options. the user can select just one or multiple. And when checked, different things will show.
so i have this working for getting one checkbox with the name "checkbox", but i need help on getting it so that it will work for 10 different checkboxes?
function showMe (box) {
var chboxs = document.getElementsByName("checkbox");
var vis = "none";
for(var i=0;i<chboxs.length;i++) {
if(chboxs[i].checked){
vis = "block";
break;
}
}
document.getElementById(box).style.display = vis;
}
You can send the element to the function, get the id (element.id).
And then have a list of divs with corresponding id="div1"
Maybe try something like this:
Javascript:
function showMe (element) {
document.getElementById("div" + element.id).style.display = (element.checked) ? "block" : "none";
}
HTML:
<input type="checkbox" onclick="showMe(event.target)" id="1">
<div id="div1" style="display:none">you clicked checkbox 1</div>

How to use Model data in String.Format?

I'm trying to display every images in specific folders based on the folder name which equivalent to Model.Id.
#foreach (var imgPath in Directory.GetFiles(Server.MapPath("~/menu/" + Model.Id), "*.jpg"))
{
var img = new FileInfo(imgPath);
<img src="#Url.Content(String.Format("~/menu/449/{0}", img.Name))" />
}
In the last line, 449 is the folder name. How can I use Model.Id to replace 449? I'm not sure how to do that using String.Format
#foreach (var imgPath in Directory.GetFiles(Server.MapPath("~/menu/" + Model.Id), "*.jpg"))
{
var img = new FileInfo(imgPath);
<img src="#Url.Content(String.Format("~/menu/{0}/{1}", Model.Id, img.Name))" />
}
With string.Format you use numeric placeholders that match the position of the parameter included after the string. {0} is the 1st parameter, {1} the second and so on.

Knockout.js - javascript function on data-bind

Is there a way i can call JavaScript function on data-bind like this:
<span id="lblSomePropVal" data-bind="text: MySomeFunction(SomeProperty())" ></span>
What i am trying to do is call MySomeFunction with the value of SomeProperty of my viewmodel. My SomeFunction will return some text based on value passed and that will be displayed in the span lblSomePropVal.
I tried it the way i have written in the example but it throws binding error.
Am i missing something here or is there any other way of doing this?
This is the error i am getting:
Microsoft JScript runtime error: Unable to parse bindings.
Message: [object Error];
Bindings value: text: MySomeFunction(SomeProperty())
I had a similar problem trying to calculate table cell entries. What worked for me was including 'MySomeFunction' in my data model, and then data-binding my table cells as:
<td data-bind="text: $root.MySomeFunction(SomeProperty)"></td>
You can use arbitrary JavaScript expressions for bindings, but keep in mind that they are evaluated in the viewmodel's context, so all functions in the expression have to be properties of viewmodel. In your case, MySomeFunction has to be a property of your viewmodel. If you create your viewmodel using mapping plugin, you can attach additional functions to the viewmodel like this:
var viewModel = ko.mapping.fromJS(data.d)
viewModel.MySomeFunction = function(...){...};
Well I am just going through the tutorial myself but I thought you had to set up a property and use ko.computed to give it its value (from the tutorial):
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function(){
return this.firstName() + " " + this.lastName();
},this);
}
Then you can have:
Full name: <strong data-bind="text: fullName"></strong>
I have managed to do this by using the context. If you need the whole code I can send it to you.
<h2 class="text" data-bind="html: currentProgram($context)"></h2>
function currentProgram(context){
var title = '<font size="1">' + context.$data.name + '</font>';
return title;
}
You will also need to set this
$.ajaxSetup({
async: false
});
<div style="font-size:18px;float:left;width:95%" data-bind="html: trimString(AccountName,25)"></div>
function trimString(value, maxLen) {
//Return undefined, and short strings
if (value === undefined) return undefined;
if (value.length < maxLen) return value;
return value.substring(0, (maxLen - 1));
}

Adding a 'target' attribute to the URL of a tabstrip item in Telerik MVC extensions

I am replacing this 'hand-rolled' tabstrip with the Telerik Extensions Tabstrip below it, but I can't fathom how to get the Tabstrip to include the target attribute in the URL for each item. How can I achieve this?
Before:
<ol>
#foreach (var sheet in Model.Sheets)
{
<li>
#sheet.Name</li>
}
</ol>
After:
#Html.Telerik().TabStrip().Name("Card").BindTo(Model.Sheets, (item, tabInfo) =>
{
item.Text = tabInfo.Name;
item.Url = Url.Content(Server.MapUrl(tabInfo.FilePath));
})
You could use the LinkHtmlAttributes property to set additional html attributes:
item.LinkHtmlAttributes = new Dictionary<string, object>
{
{ "target", "selected-worksheet" }
};
Actually I've never used Telerik, so I am not quite sure if you have to instantiate a new dictionary or simply add a key (in case the property is automatically instantiated):
item.LinkHtmlAttributes["target"] = "selected-worksheet";
I think I had a similar problem with the Telerik TreeView and solved it via a detour with jQuery.
My problem was, that it didn't work to pass any (Link)HtmlAttributes, to the TreeViewItems in the View. I tried to add several HtmlAttributes to the TreeViewItem in the Controller: (e.g. one attribute I wanted to add to the < a > element):
newNodes[i].HtmlAttributes.Add("data-ajax-update","#main");
, but after return as JsonResult of the Ajax-Request, all except .Text, .Value, .Enabled, .LoadOnDemand, .Url were then empty in the View.
I found a sensible answer that these elements are not getting serialized in the Telerik forum:
http://www.telerik.com/community/forums/aspnet-mvc/treeview/target-blank-on-treeviewitem-url.aspx#1548458
I solved it then, with adding a special
<span class="treeViewItemAddAjaxLocation"></span>
element to the .Text of the TreeViewItem. Locating these elements then via jQuery in the View and adding the desired html-attributes to the < a > element.
Telerik TreeView Binding method of the 2nd and 3rd stage elements via Ajax:
.DataBinding(databinding => databinding.Ajax().Select("_AjaxLoading", "Menu"))
Controller snippet in Action "_AjaxLoading":
IList<TreeViewItem> newNodes = new List<TreeViewItem>();
foreach (RevisionEntity revision in revisions)
{
newNodes.Add(new TreeViewItem()
{
Text = "Node Name" + "<span class='treeViewItemAddAjaxLocation'></span>", // name + locator element
Value = revision.ID.ToString() + ";RevisionEntity",
Encoded = false,
Enabled = true,
LoadOnDemand = false,
Url("/Menu/NavigateToRevisionDetails"), // creates an < a > element
});
}
return new JsonResult { Data = newNodes };
View:
<div class="t-bot">
<a class="t-link t-in" href="/Menu/NavigateToRevisionDetails" data-ajax-update="#main" data-ajax-mode="replace" data-ajax-method="GET" data-ajax="true">Node Name
<span class="treeViewItemAddAjaxLocation"></span>
</a>
<input class="t-input" type="hidden" value="774336a5-c6eb-42cc-905a-4d215c957fa2;RevisionEntity" name="itemValue">
</div>
function TreeView_onLoad(e) {
var treeView = $(this).data("tTreeView");
$(".treeViewItemAddAjaxLocation", treeView.element)
.each(function () {
var $this = $(this); // put it in jQuery constr
item = $this.closest(".t-link"); // take the a
item.attr('data-ajax-update', '#main');
item.attr('data-ajax-mode', 'replace');
item.attr('data-ajax-method', 'GET');
item.attr('data-ajax', 'true');
$this.remove(); // removes the span element
});
}
Result TreeView element:
<div class="t-bot">
<a class="t-link t-in" href="/Menu/NavigateToRevisionDetails" data-ajax-update="#main" data-ajax-mode="replace" data-ajax-method="GET" data-ajax="true">Node Name</a>
<input class="t-input" type="hidden" value="774336a5-c6eb-42cc-905a-4d215c957fa2;RevisionEntity" name="itemValue">
</div>
Loads the PartialView invoked through "NavigateToRevisionDetails" Action via Ajax in the #main html-element and the rest of the page doesn't get refreshed!

Can I get access to htmlText setter code in textArea in Flex?

Greetings,
I can see that when I set htmlText in a textarea control, the text property contains the html free version of the text. So there is a parser somewhere that is ripping of html from the content, which would be very usefull for my purposes.
However, based on the flex source code, the setting of html is done in UITextField.as, which is the type of the textfield member of TextArea. The line that does the work is:
super.htmlText = value;
in function
override public function set htmlText(value:String):void
Trying to follow the class hieararchy, I end up in FlexTextField class, which extends flash player's textfield class.
It appears the functionality I am after is in flash player. So is there any way of accessing this html cleaning function? Am I missing something here?
Best Regards
Seref
In case regex fails you, here is something you might want to check out:
var t:String = "asd <span>This is <font>some</font> text <b> :) </b> </span> \nand more";
function stripTags(x:XML):String {
var t:String = "";
var children:XMLList = x.children();
var child:XML;
for(var i:Number = 0; i < children.length(); i++){
child = children[i];
if(child.nodeKind() == "text")
t += child.toString();
else if(child.nodeKind() == "element")
t += stripTags(child);
}
return t;
}
var x:XML = new XML("<root>" + t + "</root>");
XML.ignoreWhitespace = false;
var s:String = stripTags(x);
trace(s);
PS: I haven't tested this ActionScript code, here is the equivalent JavaScript code that I tested and found working. I assume it would work in ActionScript since both follow ECMAScript.
var t = "asd <span>This is <font>some</font> text <b> :) </b> </span> \nand more";
function stripTags(str){
function strip(x){
var t = "";
var children = x.children();
var child;
for(var i = 0; i < children.length(); i++){
child = children[i];
if(child.nodeKind() == "text")
t += child.toString();
else if(child.nodeKind() == "element")
t += strip(child);
}
return t;
}
var xml = new XML("<root>" + str + "</root>");
XML.ignoreWhitespace = false;
return strip(xml);
}
var s = stripTags(t);
console.log(s);
output:
asd This is some text :)
and more
Nope, there is no way to access code in the Flash Player native classes.
However, you should be able to use a Regex to easily parse out all HTML Tags in your content.
Although, not tested, here is one option that came up in Google. You can just use that in Flex. So, you can probably do something like this:
var regEx : RegExp = new RegExp('<(.|\n)*?>');
var noHTMLText = htmlText.replace(regEx , '');
Of course, this was written in the browser. More info on Regex in Flex.

Resources