MVC 5 Razor view not rendering HTML within if condition - c#

This is the MVC 5 razor view code: ForestView.cshtml
#model Forest.Tree
#{
var resultHtml = string.Empty;
}
<div id="divTreeSearch>
#(Html.Kendo().PanelBar().
Name("panelbar")
.Items(panelbar =>
{panelbar.Add()
.Content(#<text>#Html.Partial("_TreeSearch", Model, ViewData)</text>);}))
</div>
<div id="divTreeSearchResult">
#if(Model.TreeResultObj != null)
{
resultHtml = Html.ContentFromPartial("_TreeReport", Model.TreeResultObj);
#Html.Raw(resultHtml); -- Not working
#Html.Raw(HttpUtility.HtmlDecode(resultHtml)); -- Not Working
Html.Raw(resultHtml); -- Not working
Html.Raw(HttpUtility.HtmlDecode(resultHtml)); -- Not Working
Model.resultStringSaved = resultHtml;
#Html.DisplayText("resultStringSaved"); -- Not Working
#Html.Raw("<text>Test</text>") -- Even this is not working
}
#Html.Raw(Model.resultStringSaved) -- Not Working
#Html.Raw(HttpUtility.HtmlDecode(Model.resultStringSaved)) -- Not Working
#Html.DisplayText("resultStringSaved") -- Not Working
#Html.Raw("<text>Test</text>") -- This is Working
</div>
ForestView.cshtml - #model Forest.Tree
_TreeSearch.cshtml - #model Forest.Tree
_TreeReport.cshtml - #model Forest.SearchData.Results
The projerty TreeResultObj in the model Forest.Tree is of type Forest.SearchData.Results
The ForestView.cshtml is the main view which loads initially and displays the search inputs from the _TreeSearch partial
When search criteria entered and a 'search' button is clicked (all this is from the _TreeSearch) - a ajax call is make and the TreeSearch(id tree) action is called
The action again returns the main 'ForestView' - however now the model property 'TreeResultObj' is populated. so the code within the 'if conditon' in the 'ForestView' executed and calls another partial to get the content back as HTML string, which is saved in the 'resultHtml' variable
At this point I can see the Html Sting like "<Text>blah blah blah</text>"
However trying to display the HTML string below the search panel in the main 'ForestView' is not working - I have tried almost every possible way.
Any text within the if condition is not rendered - it is an ajax call so there is no page refresh - I can see the HTML string value and also save it as a Model property but cannot get to display it in the main view.
Any help would be much appreciated. Thanks in advance.

At that point, you are just invoking a method and ignoring the result. Try:
#: #Html.Raw(resultHtml)
The #: switches to output mode. Note: if you had used something that was clearly markup, it would have switched automatically. For example:
<div>#Html.Raw(resultHtml)</div>

I was also facing the same issue but I could make it to working. I wanted to open a div start and conditionally end it within a for loop.
Put any dummy HTML element before the #Html.Raw
<div id="divTreeSearchResult">
#if(Model.TreeResultObj != null)
{
resultHtml = Html.ContentFromPartial("_TreeReport", Model.TreeResultObj);
<span>dummySpan</span>
#Html.Raw(resultHtml);
#Html.Raw(HttpUtility.HtmlDecode(resultHtml));
#Html.Raw(resultHtml);
#Html.Raw(HttpUtility.HtmlDecode(resultHtml));
Model.resultStringSaved = resultHtml;
#Html.DisplayText("resultStringSaved");
#Html.Raw("<text>Test</text>")
}
#Html.Raw(Model.resultStringSaved)
#Html.Raw(HttpUtility.HtmlDecode(Model.resultStringSaved))
#Html.DisplayText("resultStringSaved")
#Html.Raw("<text>Test</text>")
</div>
After you place a dummy html element there all the below #Html.Raw will work
Happy Coding
Tarak

1 - And the content from render should be violating HTML syntax and Razor normally doesn't render wrong HTML content.
2 - Enclose the HTML.Raw(resultHtml) into dev.

After zillions of tests in a full-day:
Change use of:
#Html.Raw(Html.DisplayFor(modelItem => item.Mensagem))
by:
#Html.Raw(Html.DisplayTextFor(modelItem => item.Mensagem))
You will get the rendered HTML withou any <>!!!

Related

How to display razor and C# code in view in MVC

I am using MVC and razor for a style Guide. I need to display the code in the view so others can use it on the site.
I need to display the code without the Razor helper executing the function.
I am trying to do this via a Razor helper. I want this helper to render the button as well as display the exact MVC Razor helper code in the view (rather than have it display the outputted HTML from the helper).
#helper ShowCode() {
<div>
#Html.TextBox("textBox")
</div>
}
Then I call the helper below and try and display the code:
// render the button
#ShowCode()
// display the button code
<pre>
<code>
#ShowCode().ToString()
</code>
</pre>
However, this displays the following:
I need it to display the following code instead of the HTML:
<div>
#Html.TextBox("textBox")
</div>
How can I display the code within the Razor helper without it being outputted as html? (I want to display exactly what is in the Razor helper). Is this possible?
You can't actually do it like that. Razor returns HTML there is no way to get actual Razor template code as string.

ASP.Net MVC 5: Html.RenderAction("...") at runtime

I want to add a PartialView multiple times by pressing a button.
<div id="FilterRows">
#{Html.RenderAction("_FilterRow");}
</div>
<button id="newRow" type="button"
class="btn btn-sm btn-default"
style="width: 50px">+</button>
This piece of code works properly. But now i want to append the div FilterRows with another PartialView of _FilterRow at clicking on the button.
This is how it looks today:
Something like:
$(document).ready(function() {
$("#newRow").click(function() {
$("#Exec").append("<br>", #{Html.RenderAction("_FilterRow");} {
});
});
});
Is unfortunately not working. Any Ideas?
If you add an action which returns the partial rendered as a partial (ie. return PartialView("myView", model); then you can load using jQuery:
# Create a new element to contain...
var el = $('<div></div>');
$('#parent').append(el);
# ...the new content
el.load('#Url.Action("action", "controller"');
(This means running the JS in the razor view to get the correct URL generation. If most of the JS is in its own file, pass the URL from a little JS in the Razor file just for things like URLs.)
As long as your script is in the page (and not in an external .js file) you can use Razor inside js (although feedback directly from MicroSoft indicates that this is "unexpected", it works fine).
Have a look at the rendered html to see what's wrong.
In this case you need quotes (") around the render action:
$("#FilterRows").append("#{Html.RenderAction("_FilterRow");}");
This assumes a number of potential issues:
the 'RenderAction' can't have any newlines in the output
the 'RenderAction' can't have any quotes in the output (either use ' on the append and " inside the render or the other-way-around)
the action to be rendered cannot have any row-specific parameters (which appears to be ok in this case to add a new blank row)
the script must be in a .cshtml file (though you can get around this by setting a global/namespace'd variable in the .cshtml and have the actual code in a .js file)
you need to use the correct combination of #{}/#() and render/tostring
You might be better off with #Html.RenderPartial if you just want to render some html and don't need an action.
An alternative, perhaps more friendly, mechanism would be to have the blank-row already on the page (perhaps hidden) and use .clone().

How to include template dynamic in AngularJS?

I have 3 different view(DetailView, CardView, Column) template/html pages to show in single-page. The user can switch between these 3 view.
I want to bind single view at a time in page, if user switch it will remove previous view and bind the new view. I have data in Model for bind the view so, I no need to call service to bind data. I want toggle between these three-view without refresh page and loading data.
Problem is, if bind three view it will conflict with div-id and there are lots of html-code for all view in DOM.
Please suggest me how to toggle between these different view without loading & refreshing page??
<body>
<div ng-include="'detailView.html'" ng-show="detailView"></div>
<div ng-include="'cardView.html'" ng-show="cardView"></div>
<div ng-include="'cardView.html'" ng-show="cardView"></div>
</body>
As i know Angular Apps are SPA (Single Page Application) so if you switch pages by routing its default behavior its the one that you are asking for. Its not reloading/refreshing the page. It remove the previous view and bind the new one.
Check this guide : https://scotch.io/tutorials/single-page-apps-with-angularjs-routing-and-templating
Also try to use $location service to switch routes. It does not reload the page.
$location.path("/your-route").
Angular has routing module. This way you can define a route (page) with it's own URL, HTML template and controller.
configuration example:
YOUR_MODULE.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
You can read more about it in angular's documentation:
https://docs.angularjs.org/tutorial/step_07
For bigger applications I would suggest you to use UI-ROUTER:
https://github.com/angular-ui/ui-router
Anyway, if you're looking for something simple without any routing, you should use NG-IF instead of NG-SHOW.
NG-SHOW just hiding the HTML by css (display none) which means there might be conflicts for elements with the same IDs.
NG-IF will remove the element from the DOM, so there won't be any conflicts.
Good luck!
From what i could understand, when the first time the page loads, you have certain flag up to show that view and corresponding call to a service to bind data to that view.
Next time, the model is updated and a new flag is set, a new view comes into play and a similar service binds data..
Initially set the model all to false and make one true for default.
Toggle through view as:
<body>
<div ng-include="'detailView.html'" ng-if="detailView"></div>
<div ng-include="'cardView.html'" ng-if="cardView"></div>
</body>
Through this, at a particular time only one div is active and id would not conflict.
In the controller:
If($scope.detailView == true){
//Call to service for data..
}
Similarly, when the new model is updated , set all previous to false.
Please update your query to more clarify your objective.

Parse and modify HTML from MVC Model using jQuery / Javascript

This needs to be done on the client (please trust me, I'll save the explanation).
I have a razor view that renders partial views in a loop. viewModel is just another class.
#{
foreach (ObjectName objInstance in Model.Collection)
{
#Html.Parial(partialViewName, viewModel)
}
}
And the partial view ultimately renders HTML from a viewModel property (this obviously occurs many times since this partial view is rendered in a loop).
#Html.Raw(Model.GetPropertyTextValue())
The HTML from GetPropertyTextValue() can look something like this:
<ul>\r\n<li>2,3,6-Tri-O-methyl-D-glucose (<a target=\"_blank\" href=\"http://www.blahblah.com/pubmed/12345?name=value\">1</a>) , 2,3,6-tri-O-methyl-D-mannose, 3-O- blah blah</ul>
I need to take the value in Model.GetPropertyTextValue and parse through it, replacing the entire URL (to blahblah.com) with a different link (but keep any numbers like the "12345"). Such URLs could appear multiple times in the string.
I believe this should be done with jQuery/Javascript, but I'm not sure how to approach it. Can anyone please suggest how to go about this? Thank you.
If you absolutely have to do on the client side, you can try something like this. First wrap your generated content with an identifiable div, so that you will be able to act within that container only:
<div id="items-to-parse">
#{
foreach (ObjectName objInstance in Model.Collection)
{
#Html.Partial(partialViewName, viewModel)
}
}
</div>
Then create a simple script that searches for all links within that container and changes their href attribute:
$('#items-to-parse a').each(function() {
$(this).attr('href', 'http://the.new.url');
});

MVC4: How do I get value from partial view for insert/edit

I am new to MVC and I am just trying to get a grip on certain aspects of MVC that I will be using in the project I have coming up. So, I have a view where the user will input data regarding training: name, id, location, and training dates. I have created partial view that will be used for the dates, it incorporates the jQuery date picker and a date mask. This pv will replace date fields where needed. It all works fine, but, I do not know how to get the value placed in the partial view to be passed back into the model, once the user clicks the "Create" or "Edit" button.
Here is my code (Edit View):
#Html.Partial("partialview", Model.ValueToPass)
And For the partial view:
#model Nullable<DateTime>
#{
string dt = string.Empty;
if (Model != null) { dt = Model.Value.tostring("MM/dd/yyyy"); }
<script type="text/javascript">.......</script>
<p> #Html.TextBox("Test", dt, new {#class = "DateTextArea"}) </p>
As stated, I can get a preexisting date from the model loaded into the textbox, without issue, its just retrieving that value or new value, if the user enters a new date, and putting it into the database. Any help or direction would be of great help. Thank you.
If the partial view is within a form element at the top level page, then it will be posted back as if it was part of the original form.
Think of a partial view as being only used at render time. By the time you see the page in your browser, think of it as being one complete page (Not groups of partial views). So any page submit will be done with the whole form in mind.
SOLVED:
I'd like to thank each of you for your inputs as they did help me in finding a solution. The main part I was missing was this:
#Html.Partial("partialview"), Model.ValueToSend, new ViewDataDictionary(ViewData) {
TemplateInfo = new System.Web.Mvc.TemplateInfo {HtmlFieldPrefix = "ValueToSend"
})
I was missing the templateinfo portion on the parent view. Also, I did change my textbox to TextBoxFor and used:
TextBoxFor(model => model, new { #class = .....)
DO NOT go with model.Value, as I had that in there earlier and was still retrieving a null date value on postback. The solution code does not require a hidden field to be populated, the templateinfo code adds an id to the input field in the partial view and the parent controller automatically grabs the data in the partial's input field to get sent to the database, as if it were one of the other auto generated elements on the parent view.
To make the hidden field idea work, with multiples of the same partial view on the parent view, set the hidden field and date textfield (in this example) to the same id; the hiddenfield you'd put an h in front of it ( e.g. date and hdate). Then you'd need to set a javascript variable to get the id of the active element
var id;
($(".datepickerclass").change(function(){
id = $(this).attr('id');
)}
Additionally, if you're using the datepicker
$(".datepickerclass").datepicker(
.....
beforeShow:
id = $(this).attr('id')
And then add the value to the correct hidden element within the change or blur event of the textbox or within the datepicker:
onSelect:
var val = $(id).val()
$('#h'+ id).val(val)
Pardon if the jQuery may be off a bit, I shut down my development machine and I'm typing this without fully testing the jQuery code, but I think you'd get the point. Thanks again for all the help. Next up will be tackling a jQuery grid.
Edit:
Unfortunately since my rating is not high enough, I cannot upvote the answers provided, as they deserve to be.
Use #Html.TextBoxForModel instead of #Html.TextBox(....). This will cause the input to be created with the correct name so that it will bind correctly to your model when you post the page.
You don't need to format the date yourself, you can use the dateFormat option on the jQuery date picker to format the value.
If you use EditorForModel instead of TextBoxForModel, it will create the input with the correct type to use the browsers built in date picker, if available. You can then use Modernizr to test if dates are supported and use the jQuery date picker if it is not. Here is a decent tutorial about it.
You have to be aware that anything you do with C# and razor in your views happens before the HTTP response. So once the response is sent to the client, all your #Model.value or #if(something) { #Html.Partial(...) } statements will have already translated into pure HTML.
Something you can do to get values from a partial view to your main view is use jQuery:
Imagine a main view like:
#Html.HiddenFor(m=>m.ChosenName, new { id="hiddenGlobalName" }
and a partial view like this:
<input type="text" id="partialNameField" />
<input type="button" value="Save and close popup" id="closeButton" />
<script>
$(function(){
$('#closeButton').click(function(){
var partialValue = $('#partialNameField').val(); // get the value
$('#hiddenGlobalName').val(partialValue); // "save" to main view
});
});
</script>
Because the DOM will be constructed after the HTTP request is over, you have access to all elements of a main view from any included partial view at the time the user sees them.
Hope this can help you!

Categories