I have multiple views/models that are being looped into the main view. I load them via #Html.Partial()...These views/models are basically form elements with certain properties...Unfortunately I soon found out that only the first of each type of view/model is validated. I tried moving the fields around and only the first of each kind would validate.
My partial views look something like this:
#Html.DropDownListFor(model=>model.dropdownVal,Model.SelectItems,new { id=Model.FieldID, Name = Model.FieldID })
I looked at the HTML rendered, and it seems that the validation tags like "data-val" are not applied...
Any ideas would be greatly appreciated!
Add the following at the top of your partials to trick ASP.NET MVC into thinking that the helpers are used inside a form and generate the proper data-val attributes:
#{
this.ViewContext.FormContext = new FormContext();
}
Basically the Html.* helpers are generating data-val clients side validation attributes only if they are placed inside an Html.BeginForm. Except that in your case I guess that this Html.BeginForm is in your parent view and not inside the partial, so the #Html.DropDownListFor doesn't emit any validation attributes. By setting the current FormContext to a new instance in the partial as shown previously, the helper will generate the proper client side validation attributes on the corresponding input field.
Related
Summary: I have a view component with buttons which need to be able to change the details displayed in the rest of the component on click, but i can't figure out how to update the components content and data using an element within the component.
I am using asp.net razor pages to make a simple UI which displays various info grabbed from a JSON file, no database connection or POST functionality necessary.
I want the block of html that displays the data to be a reusable component, so i don't have to rewrite it every time i want to show a different entry in the file. From my research, there are a few options: HTML components, tag helpers, razor components, partial views, and view components. I chose to use a view component since the other options all seemed either outdated or not capable enough to achieve what i wanted. That is, with the exception of razor components, which require blazor to function fully which would also require me to learn a whole new framework and retrofit my program to work for it.
My view component functions to the point where i can invoke it from Index.cs and the component shows all the data from the first log in the list, as desired.
My intention: the default entryNo value is 0, so the component shows the title and date from the first log entry. When a user clicks the "Next" button (inside the component), entryNo becomes 1, and the component shows the title and date of the second entry in the log file.
ViewComponent.cshtml:
#model FullLog
#{ int entryIndLocal = 0; }
<div>
<div>#Model[entryNo].Title</div>
<div>#Model[entryNo].Date</div>
<button onclick={entryNo++}>Next</button>
</div>
What i've tried:
Setting the entryNo value in the view's .cs file and including a function to increment that value when called. I couldn't figure out how to call the function from the cshtml.
Initialising the entryNo variable from within the cshtml file, with the intention of the adding onclick={#entryNo++}. This didn't work either.
I am curious to know if it is possible to add a fragment to a view model:
return new ViewModel([]);
Returns my view to https://example.com/view
However is it possible to set this dynamically to add a fragment?
return new ViewModel("#fragment")
To return to https://example.com/view#fragment
The use case, have a js login/register view that is either https://example.com/view#login or https://example.com/view#register and want to return to the correct view...
EDIT
Obviously, this can be done using a re-direct, however, in the case of returning form errors, ViewModel needs to be used...
Not sure if this is possible to apply param to router, but you can alwas return redirectToRegister = true, and then write and execute JavaScript in view which will change view if True.
A fragment is a same document reference i.e. if the URL specification is used correctly #register and #login will refer to different elements in the same document.
The view model therefore should be returning the same html in both cases, and the fragment will be handled by the browser. To distinguish register and login pages instead use different paths in the URL.
I have implemented a reporting engine in mvc using html rendering. I had to create custom paging functionality based on the metadata returned via the render method. I am now looking at implementing interactive sorting in the same fashion which is looking like a more daunting task. It seems there is a setting in the HTML Device Information Settings header for html rendering called ActionScript.
ActionScript(*)-
Specifies the name of the JavaScript function to use when an action event occurs, such as a drillthrough or bookmark click. If this parameter is specified, an action event will trigger the named JavaScript function instead of a postback to the server.
My question is has anyone used this feature? Since I lose authentication after the report is rendered I will have to somehow make authenticated callbacks in the controller. It seems to me it may be easier just to add parameters for sorting in the report, however I would like to keep the interactive sorting in the report.
--Edit Solution1---
It turns out that the * next to script name above means the ActionScript parameter is being depreciated after ssrs 2012. Thus, I decided not to pursue it. If anyone else stumbles upon this then the best way I thought of to simulate interactive sorting without post backs is detailed below:
On the Report
1. Add a parameter to the report SortField1
2. Add a Sort condition to the Tablix or group you wish to sort. Tablix-Sort Expressions
3. Set the expression of the sort to Fields(Paremeters!SortField1.Value).Value
4. Set the default value of parameter SortField1 to the default sort field
5. Set Allow Nulls of the parameter to true.
6. Add a image or label for each column you would like to sort by
7. Create a action for the element created in step 7 with code similar to
="javascript:void(reportSortRequest('ColumsFieldName'))"
NOTE: Your view or view descendant will have need to have an identical function defined to accept the action
In the View
Implement the function reportSortRequest(fieldName). This should set
Model.SortField1 and invoke the post back to the controller to
re-render the report.
In the Controller (This is for Ajax post backs that sends a model that will have a field SortField1)
Call the render with report information including SortField1.
Updated with client script that works to access the report markup wrapper.
The report element generated by the ssrs markup can be accessed in your view by its tags. I have that found the following will work using the predetermined ssrs wrapper element #oReportCell":
Loaded in iframe :
var frameContent = $("#myIFrame").contents();
var ssrsContentElement = frameContent.find("#oReportCell");
Loaded in div:
var ssrsContentElement = $("#myDiv").find("#oReportCell");
Function to load html blob into either a frame or a div. Depending how the report was configured, the content is either a url of a temp file or the html markup.
function setReportContent(content, isUrl, renderInIFrame) {
if (isUrl) {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').attr('src', content);
}
else
$("#reportContent").load(content);
}
else {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').contents().find('html').html(content);
}
else
$("#reportContent").html(content);
}
if(!renderInIFrame)
showReportWaitIndicator(false);
$("#reportContent").show();
}
Notice that if you want report images with auto-resize property set to be rendered correctly you have to turn on allow-scripts so that the ssrs resize js functions can fire, be careful.
I don't have so much experience using AJAX in a MVC application, in fact is my first facing. Please check the below image and note the rectangles.
The image is just an example that I took from internet.
The biggest rectangle is a partial view in my application and I have to render it when the user press Continue or Continuar button. The application should replace the current view for another without refresh the page.
This is the code which I'm testing, note first that I'm passing the first element of a list, but when the user press the button, render the view with the next element index = 2.
public ActionResult DoTest()
{
if (!Request.IsAjaxRequest())
{ }
List<Worksheet> worksheets = new List<Worksheet>()
{
new Worksheet("Hoja 1", ...),
new Worksheet("Hoja 2", ...)
};
return View(worksheets[0]);
}
Can orient me a little bit to know how to implement this feature? I just know that I need to use Ajax.
Have a look through the tutorials and examples here. There's plenty of other material around on the web with information on this subject.
There are many different ways you can achieve this. One way would be to write a custom paging Helper (HtmlHelper) that accepts new content upon the post event. You can view all about Helpers here : Custom HTML Helpers
Another way could be to use partial page rendering to achieve the partial page update upon post event.
If I was you I would combine a partial view with a jquery function to update the content. You can view some help on that here: Change dive content with Jquery
I have an HTML Helper that essentially renders static content read from HTML files (inside of a vdir). There are cases when the HTML file has a title element defined and in such cases, the current page should use the given title. The content inside of the body should be rendered where the Helper class is referenced in the View.
This is how I call the helper.
<%=Html.StaticContent("staticcontent.htm",
new List<StaticContentTag>()
{
new StaticContentTag()
{TagKey=ReplaceTags.MarketName,
TagValue = "Austin"}
}, Model, true) %>
I'm passing in the ViewModel so that I can set the title and the last parameter is a flag that says whether to force the title or not.
The head has the title defined like this.
<title><%=Model.Title%></title>
I know what I'm doing wrong here by referencing the Model.Title element before even calling the helper. Any ideas on how I can work around this?
i believe ur title tag is rendered before u call the html helper in ur view. the purpose of helpers is to render html tags where they are called not to change contents of already rendered tags that can be done through javascript. however i would not use all that new keywords in my view. rather i would make a view model containing all required information for the view and then i would have no problem writing statement
<title><%=Model.title%></title>