Razor Syntax not rendering Multi-Statement code nugget - asp.net

Hello guys I have this weird problem with Razor Syntax.
I have written the same code nuggets in Razor syntax ,having only difference in Inline expression and Multi-statement block.
About.cshtml
<!-- Single statement blocks -->
<p>
Put content here.
#Html.SubmitButton("You are in About")
</p>
Rendered Output:
Index.cshtml
<!-- Inline expressions BUT DOESNT WORKS-->
#{ Html.SubmitButton("okay in Index");}
<!-- Multi-statement block BUT DOESNT WORKS-->
#{
Html.SubmitButton("You are in Index");
Html.CheckBox("A Check Box");
}
Rendered Output:
P.S: Ignore the input button text in the snapshot.

The htmlhelpers only return values.
Even inside code blocks, you still need the # to tell Razor what to do with those values (print them to the HTML buffer).
So never-mind with the code block in this case, it would be redundant, as there's no other code in there but the html-helpers.
But even if there were other code to be placed within the block, you'd still need to preface the helpers with #:
#{
var myVar = "something";
// and so on ...
#Html.SubmitButton("You are in Index");
#Html.CheckBox("A Check Box");
}

Related

How to render HTML string in ASP.NET MVC?

On my main page, I have the code #{Html.RenderPartial("_Partial1.cshtml");}, and on my Partial, I have an HTML string:
#{
// The string is actually dynamic, not static. This is here for simplicity
string abc="<div class=\"error\">abc</div>";
}
#abc
I want to output abc with some CSS error styles, but I actually got <div class="error">abc</div> - of course, no styles there. How do I make it interpreted as HTML source code and not a string?
You can use the Html.Raw() method for that.
And if you are using model in your view than use:
#model YourApp.Models.YourModel
....
#Html.Raw(#Model.NameOfYourProperty)

ASP.NET MVC 3 and ASP.NET MVC 4 razor syntax changes?

I created two application in VS2012
Application#1. MVC 3, NET 4.5
Application#2. MVC 4, NET 4.5
Now I open any .cshtml file and add the following code:
<div>
#if (true)
{
#string.Format("{0}", "test")
}
</div>
It works just fine in Application#1 (mvc3) and I see "test" word displayed. But it doesn't work in Application#2 (mvc4).
Could anybody explain why it happens and what should be changed?
UPDATE: I've just found out one more very weird thing. If you replace #string.format("some text") with #String.format("some text") everything works fine (note uppercase String)
We had a similar issue when upgrading... it appears that simply writing #string.Format("{0}", "test") will no longer write directly onto the page as it did in MVC3. You instead have to do something like this:
<div>
#if (true)
{
Html.Raw(string.Format("{0}", "test"));
}
</div>
or
<div>
#if (true)
{
<text>#string.Format("{0}", "test"))</text> //added # to evaluate the expression instead of treating as string literal
}
</div>
Are you using the Razor engine?
Since you are in a #if block you could write: string.Format("{0}", "test") rather than #string.Format("{0}", "test").
Note the #
In Razor Syntax for Conditional check you can start a block with one # sign and then put your Condition inside..
E.g
#{var price=20;}
<html>
<body>
#if (price>30)
{
<p>The price is too high.</p>
}
else
{
<p>The price is OK.</p>
}
</body>
</html>
So in your case you are using two # within one block. Check that part and it will be resolved.
So your code block should look like following.
<div>
#if (Model == null)
{
<p>#string.Format("{0}", "test")</p>
}
</div>
On top of that if you put "#" two time like it is there in your code lines it will give you hint as image below. This is feature of Razor Syntax 4.0. Also you miss the ";" in you code line.
http://www.w3schools.com/aspnet/razor_cs_logic.asp

select2 AJAX control disturbs tab ordering

I am using select2 on dropdownlist of asp.net. The code is as follows:
<script type="text/javascript" src="js/select2.min.js"></script>
<link type="text/css" rel="Stylesheet" href="css/select2.css" />
var v = /* get the select control */
v.select2();
The problem is, once select2() function is called, tab ordering stops working. Therefore, when on the dropdownlist tab key is pressed, focus do not move to the control having next highest tabindex but move seemingly randomly to some other control.
Commenting the line where the function is called solve this problem but I need the filtering. I have tried some of the other techniques of filtering discussed here but they are too complicated. Select2 is very simple and useful because all you have to do is include the JS and CSS files and call the function.
How can I solve this ordering problem? Alternatively, is there another filtering option as easy to use as select2 that would help me?
After a few hours of struggle, I have solved the problem. It turns out that the select2 AJAX control do destroy the tab order if the tab is pressed as soon as it gets focus, that is, when nothing is typed in it. It does not, however, destroy tab ordering if some text is typed.
The internal structure of select2's auto-generated HTML is like following:
<div class="select2-container">
<a class="select2-choice">
<span</span>
<abbr class="select2-search-choice-close" />
<div> <b></b> </div>
</a>
<div class="select2-drop select2-offscreen">
<div class="select2-search">
<input class="select2-input select2-focused" tabIndex=<somevalue> />
</div>
<ul class="select2-results></ul>
</div>
</div>
If some text is typed in the HTML select control, then tab ordering is working correctly, if no text is typed then tab order is destroyed. I have used document.activeElement in firebug to find focused control in both cases. In case of no text the anchor element has focus, and in case of text typed the HTML input element has focus.
As shown above, while select2.js correctly set tabIndex property of HTML input element, it does not of the anchor element.
Solution
Just add the following line at the position specified further below in select2.js:
this.container.find("a.select2-choice").attr("tabIndex", this.opts.element.attr("tabIndex"));
Add the line after:
this.opts.element.data("select2", this).hide().after(this.container);
this.container.data("select2", this);
this.dropdown = this.container.find(".select2-drop");
this.dropdown.css(evaluate(opts.dropdownCss));
this.dropdown.addClass(evaluate(opts.dropdownCssClass));
this.dropdown.data("select2", this);
this.results = results = this.container.find(resultsSelector);
this.search = search = this.container.find("input.select2-input");
and before:
search.attr("tabIndex", this.opts.element.attr("tabIndex"));
this.resultsPage = 0;
this.context = null;
// initialize the container
this.initContainer();
this.initContainerWidth();
installFilteredMouseMove(this.results);
this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
installDebouncedScroll(80, this.results);
this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
So it becomes:
this.results = results = this.container.find(resultsSelector);
this.search = search = this.container.find("input.select2-input");
this.container.find("a.select2-choice").attr("tabIndex", this.opts.element.attr("tabIndex")); /* atif */
search.attr("tabIndex", this.opts.element.attr("tabIndex"));
this.resultsPage = 0;
this.context = null;
Make this change in select2.js. Obviously, you need to use the full js version, not the min version.
All you have to do is add one line, stated above. This would become line no#504 in VS2008 if done correctly.

Javascript Rich Display WYSIWYG Component/Methodology

quick back story--
I am working on ASP.Net based template editor that lets authors create text templates using Javascript inserted placeholder tags that will be filled in with dynamic text when the templates are used to display the final results.
For example the author might create a template like
The word [%12#add] was generated dynamically.
The application would eventually replace the tag with a dynamic word down the road (though it's not specifically relevant to this post)
The word foo was generated dynamically.
Depending on the circumstances, the template may be created in a text input, textarea or a modified version of the Ajax Control Toolkit HTML Editor. There might be 40 or more of these editable elements on the page, so using lots of stripped down or modified HTML editors would probably bog the page down too much.
The problem is that the tags such as [%12#add] are displayed inline with the user text and the result is confusing and aesthetically gross. The goal is parse the contens of the source element and when a tags such as [%12#add] are encountered, display something prettier and less cryptic to the user such as a stylable element or image wherever tags such as [%12#add] occur. The application still needs the template text with the tags on postback.
So the user might see
The word tag placeholder was generated dynamically.
but the original template would still be the value of the text input box
The word [%12#add] was generated dynamically.
It seems HTML editors like the ACT version and FckEditor accomplish this by rendering their output in an IFrame, but rather than kill myself trying to roll a lighter specialized version myself, I thought I'd ask if anyone knows of an existing free component or approach that has already tackled this.
With good reason, I don't think S.O. allows HTML formatting, but the bold "tag placeholder" above would ideally be something like tag placeholder.
I think CKEditor might be your best bet. I recently wrote a plugin for it that kept placeholders in the editable content for chunks of content that the user couldn't edit directly. A question I asked may help, particularly the comments to the accepted answer: Update editor content immediately before save in CKEditor plug-in.
The recommendation to me was to look at how object tags (e.g. as used to embed Flash movies) are handled, and from that I was able to proceed fairly quickly. Be aware though that CKEditor is not well documented for plugin developers, so you may often have to resort to looking at the source code.
Final model solution in case someone in the same situation needs a boost.
aspx page:
<div>
<asp:TextBox runat="server" ID="txtTest" TextMode="MultiLine" CssClass="Over" />
<br />
Add CKEdit
<br />
Add Tag
<br />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" />
</div>
<script type= "text/javascript" >
<!--
function ckTest(el) {
var tinyTool = {
toolbar:
[
['Bold', 'Italic', 'UIColor'], ['Styles', 'Format', 'Font', 'FontSize']
]
};
//Note: config.htmlEncodeOutput = true; to work with ASP.NET, see postback for decoding input
var editor = CKEDITOR.replace(el);//, tinyTool);
editor.addCss('.aux1 { background-color: #FFE0C0; border: solid 1px #17659E; }');
}
function insertTag(id, tag, display) {
var e = CKEDITOR.instances[id];
if (e) {
//Storing in comments does not work. stripped out when using insertHtml. Workaround?
//e.insertHtml("<span class='aux1'>" + display + "<!--" + tag + "--></span>");
//Kludge: fake attribute
e.insertHtml("<span class='aux1' tag='" + tag +"'>" + display + "</span> ");
}
}
-->
</script>
-->
</script>
CodeBehind:
protected void btnSubmit_Click(object sender, EventArgs e)
{
//Note: CKEditor converts single to double quotes in insertHtml
Regex regHiddenTag = new Regex(#"<span\sclass=""\w+""\stag=""(\[%[0-9]{1,2}_[TR]\])"">\w+</span>");
//Note: config.htmlEncodeOutput = true;
string encoded = txtTest.Text
.Replace("<", "<").Replace(">", ">").Replace("&", "&");
//TODO: Use AntiXss Library that I have to thwart bad HTML
string extractedTag = regHiddenTag.Match(encoded).Groups[1].Value;
//store to DB
string template = regHiddenTag.Replace(
encoded,
extractedTag);
//repopulate
string finalText = template.Replace(extractedTag, "foo");
}

How to solve duplicate objects in dynamic loading page by using jQuery?

I want to solve duplicate objects in dynamic loading content. Please look at the following source code for easier understand.
Base Page HTML With 1 Dynamic Loading Content
<body>
<div id="general-div"></div>>
<div id="div1"></div>
<div id="placeholder1">
Dynamic Content will be placed inside this.
<div class="inner-div"></div>
<div class="div1"></div>
</div>
</body>
For script in header of this page, it's very easy to select "general-div" object like the following code.
$('#general-div')
It's quite easy for select "inner-div" object inside placeholder1. So I can select by using the below code.
$('.inner-div')
The above code could works perfectly. However, I can't use the above code when there is more than 1 duplicated object in the same document like the following HTML. The above code will return 2 objects that don’t what I want.
Base Page HTML - After load another dynamic loading content
<body>
<div id="general-div"></div>>
<div id="div1"></div>
<div id="placeholder1">
Dynamic Content will be placed inside this.
<div class="inner-div"></div>
<div class="div1"></div>
</div>
<div id="placeholder2">
Dynamic Content will be placed inside this.
<div class="inner-div"></div>
<div class="div1"></div>
</div>
</body>
Possible Solution 1
I must create specified jQuery object foreach script in dynamic loading content like the following code.
// Deep copy for jQuery object.
var specfiedjQueryObj = $.extend(true, {}, jQuery);
// modify find function in jQuery object.
specfiedjQueryObj.fn.find = function(selector)
{
// by adding placeholder selector before eval result.
return new specfiedjQueryObj.fn.old_find('#placeholder1 ' + selector);
};
// So, I can select any object in dynamic loading content.
(function($)
{
// This result must be 1 object.
$('.div1');
})(temp);
Even though, this solution should be work great. But I found that jQuery is a very complex object. I found a lot of errors when I try to use it.
Do you have any idea for solving this problem?
PS.PlaceHolder Id is not a fixed Id. So, It's impossible to fixed it in selector rule. Moreover, I do not know exactly amount of element and position (first, last or middle) of it in document. Because of dynamic loading content will be displayed on a lot of page.
How about $('div[id^=placeholder]:last') ?
Selectors / attrubuteStartsWith
You could simply use $('.innerdiv:first') to get the first one or $('.inner-div:last') to get the last one. Or if you have multiples and want to select a particular one $('.inner-div:nth(x)') where x is the index of the item.
The following function will process data from partial loading view page and add specified context for each jQuery selector in script. This answer works well. However, it does not support external script file.
function renderPartialView(control, data)
{
// For detecting all script tag in loaded data.
var reExtractScript = /(<script type="text\/javascript">)([\s\S]+?)(<\/script>)/gi;
// For detecting all "$" sign (must be jQuery object) in loaded data.
var reFindDollarSign = /\$\(([\S]+?)\)/gi;
// Find all matched string in loaded data.
var result = reExtractScript.exec(data);
var allScript = '';
if (result)
{
for (i = 0; i < result.length; i += 4)
{
// Remove current script from loaded script.
data = data.replace(result[i], '');
// Replace all "$" function by adding context parameter that is control.
allScript += result[i+2].replace(reFindDollarSign, '$($1, "' + control + '")');
}
}
// Load non-script html to control.
$(control).html(data);
// Evaluate all script that is found in loaded data.
eval(allScript);
}
// This script will partially download view page from server in the same domain
$(function()
{
$.get(getUrl('~/Profile/Section/ViewEducation'), null, function(data)
{
// When partial loading is complete, all loaded data will be sent to “renderPartialView” function
renderPartialView('#education-view', data);
});
});
Okay, so let's talk about your example HTML. I added a class of placeholder, and added a dash in the id for convenience later.
<div id="placeholder-1" class="placeholder">
Dynamic Content will be placed inside this.
<div class="inner-div">baz</div>
<div class="div1">zip</div>
action
</div>
<div id="placeholder-2" class="placeholder">
Dynamic Content will be placed inside this.
<div class="inner-div">foo</div>
<div class="div1">bar</div>
action
</div>
Now I can bind an event to each of these links with $('.placeholder a.action').bind('click', ... ); If I want this event to all future chunks of html like this on the page, I do $('.placeholder a.action').live('click', ... );
This code will attach an event to those links and the var statements can capture the id, or the inner text of the <div>s. In this way you don't have colliding id attribute values, but you can traverse actions inside divs with class placeholder.
$('.placeholder a.action').live('click', function(){
// get the id
var id = $(this).parents('div.placeholder').attr('id').split('-')[1];
// get the text inside the div with class inner-div
var inner_div = $(this).parents('div.placeholder').children('.inner-div').text();
// get the text inside the div with class div1
var div1 = $(this).parents('div.placeholder').children('.div1').text();
return false;
});

Resources